Excel-如何计算包含列表的两列中的对

时间:2019-07-13 11:06:50

标签: excel excel-formula

我的数据库中注册了许多农民。每个农民种一些水果,然后销往几个县。

对于每个水果/县(例如苹果,沃里克郡),我如何计算可以提供该组合的农民数量?

我的数据库中已有100多位农民注册。

因此,我的数据库中每个农民都有一行,一列是水果,一列是他们所覆盖的县。每个农民覆盖的水果和县都记录为该农民行上两个单元格中以逗号分隔的列表。

我想创建一个矩阵,水平上有水果,垂直上有县,以计算有多少农民覆盖了该特定组合。

enter image description here

对于屏幕截图中的示例,我已经尝试过:

=COUNTIF(A2:B4,AND(ISNUMBER(SEARCH(G11,A2,1)),ISNUMBER(SEARCH(A13,B2,1)))="TRUE")

但没有运气。

3 个答案:

答案 0 :(得分:1)

仅出于“乐趣”,我使用AND()和FIND()构建了一个解决方案:

IFERROR(AND(FIND(B$7,$A$2,1),FIND($A8,$B$2,1)),0)+IFERROR(AND(FIND(B$7,$A$3,1),FIND($A8,$B$3,1)),0)+IFERROR(AND(FIND(B$7,$A$4,1),FIND($A8,$B$4,1)),0)

enter image description here

您可以将其包装在IF()中,以便仅显示大于1的结果,这可能会更容易发现想要的结果。

IF(IFERROR(AND(FIND(B$7,$A$2,1),FIND($A8,$B$2,1)),0)+IFERROR(AND(FIND(B$7,$A$3,1),FIND($A8,$B$3,1)),0)+IFERROR(AND(FIND(B$7,$A$4,1),FIND($A8,$B$4,1)),0)<2,"")

答案 1 :(得分:1)

如果您拥有Excel 2010+,则可以使用Power Query(在Excel 2016+中也称为Get & Transform)来实现。

使用Power Query可以在添加任何新产品(或县)时轻松地更新表。在向数据表中添加行(或在给定行中添加产品或县)之后,您只需重新运行查询即可。

除了删除多余的空格(拆分列后的Trim)之外,所有其他操作都可以通过GUI完成。但是,您只需将M代码粘贴到高级编辑器中,然后浏览GUI以研究各个步骤。

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Products", type text}, {"Counties", type text}}),
    #"Split Column by Delimiter" = Table.ExpandListColumn(Table.TransformColumns(#"Changed Type", {{"Counties", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Counties"),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Counties", type text}}),
    #"Split Column by Delimiter1" = Table.ExpandListColumn(Table.TransformColumns(#"Changed Type1", {{"Products", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "Products"),
    #"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Products", type text}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type2", "Prod", each Text.Trim([Products])),
    #"Added Custom1" = Table.AddColumn(#"Added Custom", "County", each Text.Trim([Counties])),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"Products", "Counties"}),
    #"Grouped Rows" = Table.Group(#"Removed Columns", {"County", "Prod"}, {{"grouped", each _, type table [Prod=text, County=text]}, {"counts", each Table.RowCount(_), type number}}),
    #"Removed Columns1" = Table.RemoveColumns(#"Grouped Rows",{"grouped"}),
    #"Pivoted Column" = Table.Pivot(#"Removed Columns1", List.Distinct(#"Removed Columns1"[Prod]), "Prod", "counts", List.Sum)
in
    #"Pivoted Column"

原始数据

enter image description here

结果

enter image description here

答案 2 :(得分:0)

哦,明白了。它是由表单填充器制成表格或已提供数据的方式(我在这里向其他人解释,以便他们知道我来自哪里)。他可能想改变填写这些表格的方式,以使其更易于阅读,遵循和进行更有效的逻辑处理。

他收到了令人困惑的/错误汇编的信息/表格,并希望使它们更加直接/逻辑。

我认为我按照您对问题的表述方式,我在Excel中的工作方式以及给出的信息了解了它。我的工作方式类似:“计算字符串中任何特定单词出现的次数”。

版本1:

 =(LEN(lookupall("*"&B$8&"*",$A$2:$B$4,2))-LEN(SUBSTITUTE(lookupall("*"&B$8&"*",$A$2:$B$4,2),$A9,"")))/LEN(B$8) 

然后上下拖动。

或更好: 版本2:

      =(LEN(lookupall("*"&B$7&"*",$A$2:$B$4,2))-LEN(SUBSTITUTE(lookupall("*"&B$7&"*",$A$2:$B$4,2),$A8,"")))/LEN($A8)

[现在14:00在上面编辑-凌晨5点被写入,并且被某些单元格关闭了] 我的结果是:

版本1结果表:

enter image description here

第2版结果表:我认为这正是您想要的。

enter image description here

注意:是的,在两个源表中,我都称它们为A2:B4(但数据是相同的。war = Warwickshire。app = apples等)

您最想找哪个人?

lookupall是一个UDF,如果您四处搜寻,可以在网上找到。它提供所有vlookup结果,包括重复的查找,并在一起。在我看来,您可以查看A(县)中的值出现在每个结果中的次数(水果查询),然后除以该单词中字母的数量(县im版本1)。 ,即版本2中的水果以获取准确的数字。

在版本1中,我认为您必须舍入/向上舍入结果(例如,因为当我摆脱b2中的glos(格洛斯特郡)时,b12中的结果变为0,这对于给定这些数字将是精确的)。但是版本2更好-更准确。

这对您来说是正确的方向吗?可能需要进行更多调整,但是我认为鉴于问题的大致性质(我的阅读方式),这是我能做的最好的事情。系领带会更准确...

尽管我确信那里有更好,更通用,更通用的,科学上准确的,其他类似表适用的精确公式,但仅使用1个公式或1个单一UDF就会更好。

我使用的lookupall UDF:

          Function LookupAll(vVal, rTable As Range, ColumnI As Long) As Variant
          Dim rFound As Range, lLoop As Long
          Dim strResults As String

          With rTable.Columns(1)
          Set rFound = .Cells(1, 1)
          For lLoop = 1 To WorksheetFunction.CountIf(.Cells, vVal)
          Set rFound = .Find(what:=vVal, After:=rFound, LookIn:=xlFormulas, lookAt _
          :=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
          False, SearchFormat:=False)

          strResults = strResults & ";" & rFound(1, ColumnI)
          Next lLoop

          End With


          LookupAll = Trim(Right(strResults, Len(strResults) - 1))
          End Function

实际上,这确实完成了(以及许多其他)工作,并且成为了我大部分工作的救命稻草。 (ps.s.没人在办公室问我问题,也没人给我任何东西!这些都是我发现,研究和发现的,或者是我为了生存而制造的!)。


我的正确结果表我很高兴地说与Solar Mikes完全一样!所以版本2是正确的

          =(LEN(lookupall("*"&E$7&"*",$A$2:$B$4,2))-LEN(SUBSTITUTE(lookupall("*"&E$7&"*",$A$2:$B$4,2),$A11,"")))/LEN($A11) 

在B8单元格中向下拖动并穿越

enter image description here