[英]Index/Match Function Lookup Array with multiple criteria
我查看了此情況,但找不到有效的答復。
我需要編寫一個宏,該宏在表中搜索特定的名稱(A列),材料(B列)和顏色(C列)組合,然后從D列返回價格。
我可以輸入公式(數組)
=INDEX(Sht1!A1:D5552,MATCH(1,(Sht1!A1:A5552=A1)*(Sht1!B1:B5552=B1)*(Sht1!G1:G5552=C1),0),4)
其中A1包含我要搜索的項目的名稱,B1包含材料,C1包含顏色,值返回就可以了。 但是,我將其設置為可以在“名稱/材料/顏色”之間快速選擇,並且希望能夠快速拉高價格,因此我試圖編寫一個可在單擊按鈕時運行的宏。
我遇到的問題是將MATCH(1,(Sht1!A1:A5552 = A1) (Sht1!B1:B5552 = B1) (Sht1!C1:C5552 = C1),0)部分轉換為VBA。 我試圖避免僅使用record函數,因為它會以R1C1格式吐出一個.ForumlaArray,將來很難解釋和更新。
我努力了
Application.Index(Sht1.Range("A1:D5552"), _
Application.Match(1, Sht1.Range("A1:A5552") = Range("A1") & _
"*" & Sht1.Range("B1:B5552") = Range("B1") & "*" & Sht1.Range("C1:C5552") = _
Range("C1"), 0), 4)
但是得到類型不匹配
我還嘗試放入.ForumlaArray,但收到“無法設置范圍類的FormulaArray屬性”錯誤(因為它需要R1C1格式)
"=INDEX(Sht1!A1:D5552,MATCH(1,(Sht1!A1:A5552=A1)*(Sht1!B1:B5552=B1)*(Sht1!C1:C5552=C1),0),4)"
我對變量的設置有所不同,但是我試圖簡化這些示例以使其易於解釋。
我認為采用完全不同的方法會更好。 我將使用VBA來維護表列中唯一值的列表,而不是讓VBA進行查找,每個值都包含在一個命名范圍內。 然后,使用“數據驗證”為由VBA創建的命名范圍填充的每個搜索項(名稱,材料,顏色)創建一個下拉菜單,並繼續使用上面顯示的數組公式執行實際查找。
有關如何從excel向VBA數組填充唯一值的信息,請參見Jean-FrançoisCorbett的答案。
使用Table
與合並結構化引用 ,你可以添加更多的項目到你的底Table
,它會自動神奇地擴大到包括他們。 設置VBA代碼以在Table
更改時構建唯一值的新列表(並將它們存儲在命名范圍內,例如NamesList
, MaterialsList
, ColorList
)。
另一種選擇是僅使用數據透視表。
您錯誤地使用了Application.Match
函數和VBA的一些基礎知識。 簡而言之,該函數不能像公式那樣工作。
AFAIK Application.Match
需要一個值來尋找,以及一維單元格范圍來尋找它,並返回數組中單元格的索引。 因此,聽起來您將需要對每一列進行多次操作。 當然,我找不到任何可接受的文檔 。
正確的用法是:
row_index = Application.Match(Sht1.Range("A1").Value, Sht1.Range("A1:A5552"), 0)
price_value = Sht1.Cells(row_index, "D").Value
但這只會返回第一個比賽,而不是全部。 如果您要做的只是在VBA中復制公式,則VBA不會提高性能。 其他張貼者是正確的,可能需要采用其他方法。
您犯錯的其他一些基本原理主要是您采用了公式字符串並將其直接轉換為Application.Match
您不能做到的AFAIK。
您正在嘗試指定匹配條件,例如:
Sht1.Range("A1:A5552") = Range("A1")
您實際上正在嘗試比較Ranges。 VBA嘗試將其傳遞給Application.Match
之前,將其評估為布爾值。 因為范圍的尺寸不同,這將返回類型錯誤。
如果您尚未這樣做:需要將Sht1
聲明為Worksheet
對象,並將其設置為ActiveWorkbook.Sheets("Sht1")
Dim Sht1 As WorkSheet
Set Sht1 = ActiveWorkbook.Sheets("Sht1")
您不能僅僅希望變量Sht1
已經引用工作表“ Sht1”。
然后,您嘗試像這樣將它們串在一起。
Sht1.Range("A1:A5552") = Range("A1") & "*" & _
Sht1.Range("B1:B5552") = Range("B1") & "*" & _
Sht1.Range("C1:C5552") = Range("C1")
我認為您了解&
是用於字符串連接,但是您正在嘗試將字符串"*"
與未定義的布爾值/范圍進行連接。
如果要使用VBA解決方案,則可以遍歷所有行,直到找到匹配項:
Function FindProduct(name As String, material As String, color As String) As String
Dim product_sheet As WorkSheet
Set product_sheet = GetProductSheet() ' Workbooks(BOOK_NAME).Sheets(SHEET_NAME)
Dim row_index as Long
For row_index = 2 To product_sheet.UsedRange.Rows.Count
If product_sheet.Cells(row_index, NAME_COL).Value = name _
And product_sheet.Cells(row_index, MATERIAL_COL).Value = material _
And product_sheet.Cells(row_index, COLOR_COL).Value = color Then
FindProduct = product_sheet.Cells(row_index, PRODUCT_COL).Value
Exit Function
End If
Next row_index
End Function
或者如果性能是一個問題:
我可以稍后提供。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.