Excel索引匹配到远程查找表
我在下面创build了一个虚构的示例,其中包含定价查找表Table2和一个交易表Table1 。 下面的表格。
表格1
+----------+--------+ | CATEGORY | VOLUME | +----------+--------+ | Orange | 12 | +----------+--------+ | Orange | 25 | +----------+--------+ | Grape | 40 | +----------+--------+ | Grape | 700 | +----------+--------+
表2
+----------+-------+-------+ | CATEGORY | RANGE | PRICE | +----------+-------+-------+ | Orange | 10 | 2.50 | +----------+-------+-------+ | Orange | 20 | 2.00 | +----------+-------+-------+ | Orange | 30 | 1.50 | +----------+-------+-------+ | Grape | 50 | 5.00 | +----------+-------+-------+ | Grape | 100 | 2.00 | +----------+-------+-------+
希望是引用查找表,并拉动与范围小于或等于一个给定的CATEGORY VOLUME相关的价格。 如果VOLUME大于查找表中的任何范围,则会将PRICE拉到最高的范围。
期望的输出
+----------+--------+-------+ | CATEGORY | VOLUME | PRICE | +----------+--------+-------+ | Orange | 12 | 2.00 | +----------+--------+-------+ | Orange | 25 | 1.50 | +----------+--------+-------+ | Grape | 40 | 5.00 | +----------+--------+-------+ | Grape | 700 | 2.00 | +----------+--------+-------+
我的头马上去了使用双重一元 – (数组函数,但是当两个表都是成千上万的logging时,性能将不起作用。
任何想法非常赞赏。 使用Excel 2016。
不知道您是否可以将表2转换为数据透视表。 如果可以的话,下面应该可以工作
将表2转换为数据透视表。 添加两个辅助列(“行”和“列”)
Row =MATCH(E11,$E$3:$E$5,0)
这给你数据透视表中的类别行
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))
在这里,我也使用数组操作(为此您关心性能),但是这仅限于两行数组,而不是您所拥有的全部数据。 还是不能说太多的performance
$F$2:$O$2>F11
给出了大于当前音量的所有范围
COLUMN($F$2:$O$2)
给出列号
OFFSET($F$2:$O$2,H11,0)>0
检查当前类别行中哪些单元格具有值。
以上三个条件的组合给出了具有大于所需体积的范围并具有相应的价格的列号。
1/AGGREGATE()
部分为您提供了从第一列的编号COLUMN($E$2)
减去的最小列数。
如果体积大于最大范围,则公式将给出在IFERROR部分中捕获的错误。 COLUMN($O$2)-COLUMN($E$2)
为您提供数据透视表中的最后一个列号。
一旦你有行号和列号,价格可以通过下面的公式得到
=INDEX($E$3:$O$5,H11,I11+1)
请注意此公式中列号的+1
这是一个图像正确地看到引用
为了检查性能,我生成了391个类别的数据集,每个类别有40个范围。 不要让excel慢….但你的情况可能会有所不同
让我知道如果你需要帮助理解。 我的解释可能还不够:P
我build议对两个工作表/表使用SQL语句,并使用CopyFromRecordset
粘贴结果。
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
添加一个参考( 工具 – > 参考… )到最大版本的Microsoft ActiveX数据对象 (在我的机器上它是6.1)。
它假设三个工作表 – Table1
, Table1
Table2
和Results
。 (也可以使用命名范围或特定单元格范围作为表格。)
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