[英]Excel Index Match to Ranged Lookup Table
我在下面用價格查詢表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的RANGE小於或等於VOLUME關聯的PRICE。 如果VOLUME大於查找表中的任何RANGE,它將拉動PRICE以獲得最高的RANGE。
期望的輸出
+----------+--------+-------+
| CATEGORY | VOLUME | PRICE |
+----------+--------+-------+
| Orange | 12 | 2.00 |
+----------+--------+-------+
| Orange | 25 | 1.50 |
+----------+--------+-------+
| Grape | 40 | 5.00 |
+----------+--------+-------+
| Grape | 700 | 2.00 |
+----------+--------+-------+
我立即想到使用雙重一元-(數組函數),但是當兩個表都是成千上萬條記錄時,該性能將無法正常工作。
任何想法表示贊賞。 使用Excel 2016
我建議對兩個工作表/表使用一條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
, 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
不知道是否可以將表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))
在這里,我還使用了數組操作(您擔心性能),但這僅限於兩行數組,而不是整個數據。 仍然不能說太多性能
$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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.