简体   繁体   English

Excel-复杂的索引/匹配/匹配查找

[英]Excel - Struggling with complex Index/Match/Match lookup

I've got a table with 9 columns and about 6000 rows. 我有一张有9列和大约6000行的表格。 Each row has a price as the last column. 每行都有一个价格作为最后一列。 Some of those prices are 0.00 when they should be a value. 这些价格中的一些价格应为0.00。

In another worksheet I have the "original" table with about 3700 rows. 在另一个工作表中,我有大约3700行的“原始”表。 The prices I need are in those rows. 我需要的价格在这些行中。 However, the original table has the prices horizontally within the rows, each next to a cell with specific range of gals. 但是,原始表在行中水平放置价格,每个行旁边是具有特定gal范围的单元格。 Basically the table I have has unique rows for every location/gal range/price combo, the original has all gal range/prices sequentially in single location rows 基本上,我的表格在每个位置/ gal范围/价格组合中都有唯一的行,原始表在单个位置行中依次包含所有gal范围/价格

For example, a row in the original table looks like this: 例如,原始表中的一行如下所示:

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

Where as in my new table they look like this: 在我的新表中,它们看起来像这样:

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

Everything is the same in my new table and the original table EXCEPT those gal ranges and prices. 除了这些gal范围和价格以外,我的新表和原始表中的所有内容都相同。

What I'm trying to do is use an array multiple criteria Index/Match (based on 3 cells in both my new table and the original) to lookup the row, find the value that matches the range of gals, and then take the price to the right of that gal range cell. 我想做的是使用数组多个条件索引/匹配(基于新表和原始表中的3个单元格)查找行,找到与gals范围匹配的值,然后取价格在该gal范围单元格的右侧。

Here is a row I'm trying to get the value for in my new table: 这是我要在新表中获取值的行: 新表中的行

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

Here's a closer look at the formula I've constructed: 以下是我构建的公式的详细信息:

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)

The first standard Index/Match part works great... I Index the table and Match to find the row. 第一个标准的Index / Match部分效果很好...我为表建立了索引,然后Match以找到该行。 If I just enter a number for the Col (eg, 1, 2, 3) it'll return the value from the corresponding cell PERFECTLY. 如果我只输入Col的数字(例如1、2、3),它将从相应的单元格中完美地返回值。 However, I can't seem to make the Col match part work... I continuously get REF and N/A errors. 但是,我似乎无法使Col匹配部分起作用...我不断收到REF和N / A错误。

Is there some trick to doing a two way search? 进行双向搜索是否有技巧? It seems like it should be a simple thing to just find that value in the row and take the next cell after if...? 似乎只需要在行中找到该值并在...之后获取下一个单元格就很简单了。

One catch here is that the gal range value I'm looking for is NOT unique... there are at least 20 other references that have the same range (eg, "1-2000"). 我要寻找的gal范围值不是唯一的……至少有20个其他引用具有相同范围(例如“ 1-2000”)。 Is there a way to limit the col match to just the row I find with the row match? 有没有一种方法可以将col匹配限制为我仅找到的行匹配?

Any help is GREATLY appreciated. 任何帮助是极大的赞赏。

Thanks, Rick 谢谢,瑞克

One way to tackle this case is to use #powerquery . 解决这种情况的一种方法是使用#powerquery

Please refer to this article to find out how to use Power Query on your version of Excel. 请参考本文以了解如何在您的Excel版本上使用Power Query It is availeble in Excel 2010 Professional Plus and later versions . Excel 2010 Professional Plus和更高版本中可用。 My demonstration is using Excel 2016 . 我的演示使用Excel 2016

The steps are: 这些步骤是:

  1. Load/Add your old data to the Power Query Editor. 将旧数据加载/添加到Power Query Editor。 My sample data only has one row but it is same for thousands of rows; 我的样本数据只有一行,但数千行却相同。

样本数据

  1. Use Merge Columns function under Transform tab to merge the first 7 columns with a delimiter say semicolon ; 使用“ Transform选项卡下的Transform 合并列”功能将前7列与定界符(例如分号)合并; ; ;
  2. Repeat Merge Columns for each pair of GALLONS and TOTAL PRICES with the same delimiter ; 用相同的分隔符对每对GALLONSTOTAL PRICES重复合并列 ; . If you have done it correctly you should have something like the following: 如果正确完成操作,则应具有以下内容:

合并的

  1. Use Unpivot Columns function under Transform tab to unpivot all the merged columns for GALLONS;TOTAL PRICE , then remove the Attribute column; 使用“ Transform选项卡下的Transform 取消透视列”功能GALLONS;TOTAL PRICE所有合并列,然后删除“ Attribute列;

非透视

  1. Use Split Column function under the Transform tab to split each column by delimiter ; 使用“ Transform选项卡下的Transform 拆分列”功能按定界符拆分每列; . If you have done it correctly you should have something like the following: 如果正确完成操作,则应具有以下内容:

Splited

  1. Make a duplicate column of the GALLONS range column (which is the second last column in the above screen-shot), and then split the original GALLONS range column by delimiter - . GALLONS范围列中创建一个重复列 (这是上述屏幕截图中的倒数第二列),然后用定界符-分割原始的GALLONS范围列。 Then you should have: 然后,您应该具有:

Splited2

  1. Rename the column headers as desired; 根据需要重命名列标题;

改名

  1. Close & Load the new table to a new worksheet (by default) or you can change the default setting and create a connection for the new table and load it to a desired location in your workbook. 关闭新表并将其加载到新工作表(默认情况下),或者您可以更改默认设置并为新表创建连接并将其加载到工作簿中的所需位置。

产量

The second table is the output table and you can do INDEX+MATCH from this new table which should be much easier than from the old table. 第二个表是输出表,您可以从这个新表执行INDEX + MATCH ,这应该比从旧表容易得多。 If the data are identical but just in different structure then you may just use the output table without worrying about looking up missing prices. 如果数据相同但结构不同,则可以只使用输出表,而不必担心查找缺失的价格。

I have added a test line to my source table and here is the Refreshed output with a click of button: 我在源表中添加了一条测试行,这是单击按钮后的刷新输出:

输出2

Here are the power query M codes behind the scene for reference only. 这是幕后的功率查询M代码,仅供参考。 All steps are performed using built-in functions of the editor which is quite straight forward. 所有步骤都使用编辑器的内置功能执行,非常简单。

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"

This can be done with Index/Match, but you have to keep your cool. 这可以通过索引/匹配来完成,但是您必须保持冷静。

My Screenshot for reference 我的截图供参考

在此处输入图片说明

The formula in cell F7 is 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)

To explain: First we build an Index on column A finding the row with a concatenation of the three values. 解释:首先,我们在A列上建立一个Index,以找到具有三个值的串联的行。 That is combined with the union operator : with an Index on column L, using the same Match. 这与并运算符结合:使用相同的Match在列L上具有索引。

This Index will return one row of data, from column A to L. It is then used as the range argument for another Index/Match, where inside that row of data Match looks for the "g value" and adds 1 to move one to the right of the found cell. 该索引将返回一行数据,从A列到L列。然后用作另一个Index / Match的范围参数,其中在该行数据Match中查找“ g值”并加1将其移动到找到的单元格的右边。

Note that you don't want whole columns in this formula, since it will be very slow to calculate. 请注意,您不希望此公式中有整列,因为计算起来会很慢。

Here is another approach, not using Index/Match at all, but Sumproduct instead. 这是另一种方法,根本不使用索引/匹配,而是使用Sumproduct。 in F7: 在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))

Note that the offset of one column is achieved with the first range from B to L and the last range from A to K. 请注意,使用B到L的第一个范围以及A到K的最后一个范围可以实现一列的偏移。

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM