简体   繁体   English

Excel索引匹配到远程查找表

[英]Excel Index Match to Ranged Lookup Table

I have created a fictitious example below with a pricing lookup table Table2 and a transactions table Table1 . 我在下面用价格查询表Table2和交易表Table1创建了一个虚拟示例。 Tables below. 下表。

Table1 表格1

+----------+--------+
| CATEGORY | VOLUME |
+----------+--------+
| Orange   | 12     |
+----------+--------+
| Orange   | 25     |
+----------+--------+
| Grape    | 40     |
+----------+--------+
| Grape    | 700    |
+----------+--------+

Table2 表2

+----------+-------+-------+
| CATEGORY | RANGE | PRICE |
+----------+-------+-------+
| Orange   | 10    | 2.50  |
+----------+-------+-------+
| Orange   | 20    | 2.00  |
+----------+-------+-------+
| Orange   | 30    | 1.50  |
+----------+-------+-------+
| Grape    | 50    | 5.00  |
+----------+-------+-------+
| Grape    | 100   | 2.00  |
+----------+-------+-------+

The hope is to reference the lookup table and pull the PRICE associated with a RANGE less than or equal to VOLUME for a given CATEGORY. 希望是参考查询表并拉取与给定CATEGORY的RANGE小于或等于VOLUME关联的PRICE。 In cases where VOLUME is larger than any of the RANGEs in the lookup table, it would pull the PRICE for the highest RANGE. 如果VOLUME大于查找表中的任何RANGE,它将拉动PRICE以获得最高的RANGE。

Desired Output 期望的输出

+----------+--------+-------+
| CATEGORY | VOLUME | PRICE |
+----------+--------+-------+
| Orange   | 12     | 2.00  |
+----------+--------+-------+
| Orange   | 25     | 1.50  |
+----------+--------+-------+
| Grape    | 40     | 5.00  |
+----------+--------+-------+
| Grape    | 700    | 2.00  |
+----------+--------+-------+

My head immediately went to using double unary --( array functions, but that performance would not work when both tables are hundreds of thousands of records. 我立即想到使用双重一元-(数组函数),但是当两个表都是成千上万条记录时,该性能将无法正常工作。

Any ideas much appreciated. 任何想法表示赞赏。 Using Excel 2016. 使用Excel 2016

I would suggest using an SQL statement against the two worksheets/tables, and pasting the results using CopyFromRecordset . 我建议对两个工作表/表使用一条SQL语句,并使用CopyFromRecordset粘贴结果。

SQL: SQL:

SELECT t1.CATEGORY, t1.VOLUME, (
        SELECT PRICE
        FROM [Table2$] AS t2
        WHERE t1.CATEGORY = t2.CATEGORY
            AND (
                t1.VOLUME <= t2.RANGE
                OR t2.RANGE = MAXRANGE
            )
        ORDER BY t2.RANGE
    ) AS FINALPRICE
FROM [Table1$] AS t1
LEFT JOIN (
    SELECT CATEGORY, MAX(RANGE) AS MAXRANGE
    FROM [Table2$ AS t2a]
    GROUP BY CATEGORY
) AS MAXRANGES ON t1.CATEGORY = MAXRANGES.CATEGORY

Add a reference ( Tools -> References... ) to the maximum version of Microsoft ActiveX Data Objects (on my machine it's 6.1). 添加对Microsoft ActiveX数据对象的最高版本的引用( 工具 -> 引用... )(在我的计算机上为6.1)。

It assumes three worksheets — Table1 , Table2 and Results . 它假定了三个工作表Table1Table2Results (It is also possible to use named ranges, or specific cell ranges, as tables.) (也可以将命名范围或特定单元格范围用作表。)

Sub main()
Dim conn As New ADODB.Connection
With conn
    .Provider = "Microsoft.ACE.OLEDB.12.0"
    .ConnectionString = "Data Source=""" & ActiveWorkbook.FullName & """;" & _
        "Extended Properties=""Excel 12.0;HDR=Yes"""
    .Open
End With

Dim sql As String
sql = _
    "SELECT t1.CATEGORY, t1.VOLUME, ( " & _
            "SELECT TOP 1 PRICE " & _
            "FROM [Table2$] AS t2 " & _
            "WHERE t1.Category = t2.Category " & _
                "AND ( " & _
                    "t1.VOLUME <= t2.RANGE " & _
                    "OR t2.RANGE = MAXRANGE " & _
                ") " & _
            "ORDER BY t2.RANGE " & _
        ") AS FINALPRICE " & _
    "FROM [Table1$] AS t1 " & _
    "LEFT JOIN ( " & _
        "SELECT CATEGORY, MAX(RANGE) AS MAXRANGE " & _
        "FROM [Table2$] AS t2a " & _
        "GROUP BY CATEGORY " & _
    ") AS MAXRANGES ON t1.CATEGORY = MAXRANGES.CATEGORY"

Dim rs As ADODB.Recordset
Set rs = conn.Execute(sql)

Worksheets("Results").Cells(1, 1).CopyFromRecordset rs

conn.Close
Set conn = Nothing
Set rs = Nothing
End Sub

Not sure if you can convert your Table 2 into a pivot table. 不知道是否可以将表2转换为数据透视表。 If you can, the below should work 如果可以的话,下面的方法应该可以工作

Convert your table 2 into a pivot table. 将您的表2转换为数据透视表。 Add two helper columns( "Row" and "Column") 添加两个助手列(“行”和“列”)

Row =MATCH(E11,$E$3:$E$5,0)

this gives you the category row in the pivot table 这为您提供了数据透视表中的类别行

Column =IFERROR(1/AGGREGATE(14,6,1/(($F$2:$O$2>F11)*COLUMN($F$2:$O$2)*(OFFSET($F$2:$O$2,H11,0)>0)),1)-COLUMN($E$2),COLUMN($O$2)-COLUMN($E$2))

Here I'm also using array operations(for which you had concern about performance) but that is limited to two row arrays and not the whole data you have. 在这里,我还使用了数组操作(您担心性能),但这仅限于两行数组,而不是整个数据。 Still can't say much about performance 仍然不能说太多性能

$F$2:$O$2>F11 gives all ranges greater than current volume $F$2:$O$2>F11给出所有大于当前交易量的范围

COLUMN($F$2:$O$2) gives the column number COLUMN($F$2:$O$2)给出列号

OFFSET($F$2:$O$2,H11,0)>0 checks in the current category row, which cells have values. OFFSET($F$2:$O$2,H11,0)>0在当前类别行中检查哪些单元格具有值。

The combination of above three conditions gives you the column numbers that has a range greater than the required volume and has a corresponding price to it. 以上三个条件的组合为您提供的列号的范围大于所需的数量,并具有相应的价格。

The 1/AGGREGATE() part gives you the minimum column number which is subtracted from the first column's number COLUMN($E$2) . 1/AGGREGATE()部分为您提供最小的列号,该数目要从第一列的数COLUMN($E$2)减去。

if the volume is larger than max range, the formula will give error which is captured in the IFERROR part. 如果音量大于最大范围,则公式将给出错误,该错误将在IFERROR部分捕获。 COLUMN($O$2)-COLUMN($E$2) gives you the last column number in the pivot table. COLUMN($O$2)-COLUMN($E$2)为您提供数据透视表中的最后一个列号。

Once you have the row and column number, the price can be got by the below formula 获得行号和列号后,可以通过以下公式获得价格

=INDEX($E$3:$O$5,H11,I11+1)

Note the +1 for the column number in this formula 注意此公式中的列号+1

Here is an image to see the references correctly 这是一张可以正确查看参考的图片

Sceenshot

To check performance I generated a data set of 391 categories with each having 40 ranges. 为了检查性能,我生成了391个类别的数据集,每个类别都有40个范围。 Doesn't make excel slow....but your case might be different 不会使excel变慢....但是您的情况可能有所不同

性能截图

Let me know if you need help with understanding. 如果您需要了解方面的帮助,请告诉我。 My explanations might not be enough :P 我的解释可能还不够:P

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

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