Excel-难以处理复杂的索引/匹配/匹配查询

时间:2019-09-13 03:15:36

标签: excel indexing match

我有一个9列,大约6000行的表。每行都有一个价格作为最后一列。这些价格中的某些价格应为0.00。

在另一个工作表中,我有大约3700行的“原始”表。我需要的价格在这些行中。但是,原始表在行中水平放置价格,每个行旁边是具有特定gal范围的单元格。基本上,我的表格在每个位置/ gal范围/价格组合中都有唯一的行,原始表在单个位置行中依次显示所有gal范围/价格

例如,原始表中的一行如下所示:

... / 1-2000 / 2.8383 / 2001-4000 / 2.5382 / ...

在我的新表中,它们看起来像这样:

... / 1-2000 / 2.8383
... / 20001-4000 / 2.5382
etc

我的新表和原始表中的所有内容都相同,除了这些gal范围和价格。

我想做的是使用数组多个条件索引/匹配(基于新表和原始表中的3个单元格)查找行,找到与gals范围匹配的值,然后将价格设为该gal范围单元格的右侧。

这是我要在新表中获取其值的行: row in new table

这是原始表中具有我需要的值的行: row with value in original table

在这里仔细看一下我构建的公式:

INDEX(old!$A$2:$Q$3755,MATCH(1,(A29=old!$A$2:$A$3755)*(F29=old!$F$2:$F$3755)*(G29=old!$G$2:$G3755),1),MATCH(H29,old!$J$2:$Q$3755,1)+1)

第一个标准的索引/匹配部分效果很好...我为表建立索引并匹配以查找行。如果我仅输入Col的数字(例如1、2、3),它将从相应的单元格中完美返回值。但是,我似乎无法使Col匹配部分正常工作……我不断收到REF和N / A错误。

进行双向搜索是否有技巧?似乎只是在行中找到该值,然后在...之后获取下一个单元格,这是一件简单的事情?

这里的一个陷阱是我要查找的gal范围值不是唯一的...至少有20个其他引用具有相同范围(例如“ 1-2000”)。有没有一种方法可以将col匹配限制为我只找到与该行匹配的那一行?

我们非常感谢您的帮助。

谢谢, 里克

3 个答案:

答案 0 :(得分:1)

解决这种情况的一种方法是使用#powerquery

请参阅此article,以了解如何在您的Excel版本上使用 Power Query 。它在 Excel 2010 Professional Plus和更高版本中可用。我的演示使用的是 Excel 2016

步骤是:

  1. 将旧数据加载/添加到Power Query Editor。我的样本数据只有一行,但对于数千行却一样;

Sample Data

  1. 使用Transform标签下的 Merge Columns 合并列功能,将前 7 列与以分号;为分隔符合并;
  2. 为每对GALLONSTOTAL PRICES使用相同的定界符;重复 Merge Columns 。如果正确完成操作,则应该具有以下内容:

Merged

  1. 使用Transform标签下的 Unpivot Columns 功能取消GALLONS;TOTAL PRICE的所有合并列,然后删除Attribute列;

Unpivoted

  1. 使用Transform标签下的拆分列功能,以定界符;拆分每一列。如果正确完成操作,则应该具有以下内容:

Splited

  1. GALLONS范围列中复制一个列(上面的屏幕快照中的倒数第二列),然后拆分原始的GALLONS范围列通过定界符-。那你应该有:

Splited2

  1. 重命名所需的列标题;

Renamed

  1. 关闭并加载新表到新工作表(默认情况下),或者您可以更改默认设置并为新表创建连接并将其加载到工作簿中的所需位置。

Output

第二个表是输出表,您可以从这个新表中进行 INDEX + MATCH ,这应该比从旧表中容易得多。如果数据相同但结构不同,则可以使用输出表,而不必担心查找缺失的价格。

我已在源表中添加了一条测试行,这是单击按钮后的刷新输出:

Output2

以下是电源背后的功率查询M代码,仅供参考。所有步骤都使用编辑器的内置功能执行,非常简单。

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"IATA", Int64.Type}, {"ST", type text}, {"FUELER", type text}, {"UPDATED", type datetime}, {"RESTRICTIONS", type text}, {"BASEF UEL", type text}, {"NOTES", type any}, {"GALLONS1", type text}, {"TOTAL PRICES1", type text}, {"GALLONS2", type text}, {"TOTAL PRICES2", type text}, {"GALLONS3", type text}, {"TOTAL PRICES3", type text}, {"GALLONS4", type text}, {"TOTAL PRICES4", type text}, {"GALLONS5", type text}, {"TOTAL PRICES5", type text}}),
    #"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"IATA", type text}, {"UPDATED", type text}, {"NOTES", type text}}, "en-AU"),{"IATA", "ST", "FUELER", "UPDATED", "RESTRICTIONS", "BASEF UEL", "NOTES"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged"),
    #"Merged Columns1" = Table.CombineColumns(#"Merged Columns",{"GALLONS1", "TOTAL PRICES1"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged.1"),
    #"Merged Columns2" = Table.CombineColumns(#"Merged Columns1",{"GALLONS2", "TOTAL PRICES2"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged.2"),
    #"Merged Columns3" = Table.CombineColumns(#"Merged Columns2",{"GALLONS3", "TOTAL PRICES3"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged.3"),
    #"Merged Columns4" = Table.CombineColumns(#"Merged Columns3",{"GALLONS4", "TOTAL PRICES4"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged.4"),
    #"Merged Columns5" = Table.CombineColumns(#"Merged Columns4",{"GALLONS5", "TOTAL PRICES5"},Combiner.CombineTextByDelimiter(";", QuoteStyle.None),"Merged.5"),
    #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Merged Columns5", {"Merged"}, "Attribute", "Value"),
    #"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Attribute"}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Removed Columns", "Merged", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Merged.1", "Merged.2", "Merged.3", "Merged.4", "Merged.5", "Merged.6", "Merged.7"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Merged.1", Int64.Type}, {"Merged.2", type text}, {"Merged.3", type text}, {"Merged.4", type datetime}, {"Merged.5", type text}, {"Merged.6", type text}, {"Merged.7", type text}}),
    #"Split Column by Delimiter1" = Table.SplitColumn(#"Changed Type1", "Value", Splitter.SplitTextByDelimiter(";", QuoteStyle.Csv), {"Value.1", "Value.2"}),
    #"Changed Type2" = Table.TransformColumnTypes(#"Split Column by Delimiter1",{{"Value.1", type text}, {"Value.2", type text}}),
    #"Duplicated Column" = Table.DuplicateColumn(#"Changed Type2", "Value.1", "Value.1 - Copy"),
    #"Reordered Columns" = Table.ReorderColumns(#"Duplicated Column",{"Merged.1", "Merged.2", "Merged.3", "Merged.4", "Merged.5", "Merged.6", "Merged.7", "Value.1 - Copy", "Value.1", "Value.2"}),
    #"Split Column by Delimiter2" = Table.SplitColumn(#"Reordered Columns", "Value.1", Splitter.SplitTextByDelimiter("-", QuoteStyle.Csv), {"Value.1.1", "Value.1.2"}),
    #"Changed Type3" = Table.TransformColumnTypes(#"Split Column by Delimiter2",{{"Value.1.1", Int64.Type}, {"Value.1.2", Int64.Type}}),
    #"Renamed Columns" = Table.RenameColumns(#"Changed Type3",{{"Merged.1", "IATA"}, {"Merged.2", "ST"}, {"Merged.3", "FUELER"}, {"Merged.4", "UPDATED"}, {"Merged.5", "RESTRICTIONS"}, {"Merged.6", "BASEF UEL"}, {"Merged.7", "NOTES"}, {"Value.1 - Copy", "GALLONS"}, {"Value.1.1", "Min Fuel"}, {"Value.1.2", "Max Fuel"}, {"Value.2", "TOTAL PRICE"}}),
    #"Changed Type4" = Table.TransformColumnTypes(#"Renamed Columns",{{"UPDATED", type date}})
in
    #"Changed Type4"

答案 1 :(得分:0)

这可以通过索引/匹配来完成,但是您必须保持冷静。

我的截图以供参考

enter image description here

F7单元格中的公式为

=INDEX(
INDEX(A2:A3,MATCH(B7&C7&D7,INDEX(A2:A3&C2:C3&F2:F3,0),0))
  :INDEX(L2:L3,MATCH(B7&C7&D7,INDEX(A2:A3&C2:C3&F2:F3,0),0)),
MATCH(E7,
     INDEX(A2:A3,MATCH(B7&C7&D7,INDEX(A2:A3&C2:C3&F2:F3,0),0))
     :INDEX(L2:L3,MATCH(B7&C7&D7,INDEX(A2:A3&C2:C3&F2:F3,0),0)),0)
+1)

解释:首先,我们在A列上建立索引,以查找包含三个值的串联的行。使用相同的Match将其与联合运算符:结合在一起,在列L上具有索引。

此索引将返回一行数据,从A列到L列。然后用作另一个Index / Match的range参数,其中在该行数据Match中查找“ g值”并将1加到在找到的单元格的右边移动一个。

请注意,您不希望在此公式中使用整列,因为计算起来会很慢。

答案 2 :(得分:0)

这是另一种方法,根本不使用索引/匹配,而是使用Sumproduct。在F7中:

=SUMPRODUCT($B$2:$L$3,($A$2:$A$3=B7)*($C$2:$C$3=C7)*($F$2:$F$3=D7)*($A$2:$K$3=E7))

请注意,通过从B到L的第一个范围和从A到K的最后一个范围可以实现一列的偏移。

enter image description here