【发布时间】:2021-02-19 01:44:17
【问题描述】:
我一直在尝试使用数组来寻找比 VLOOKUP() 更快的替代方法,因为在处理非常大的数据集时可能需要很长时间。
我搜索了 SO 和许多其他网站,获取了 sn-ps 代码。
数据:
- A1:A5 要查找的值列表 (1,2,3,4,5)
- C1:C5 “查找”值的范围 (2,4,6,8,10)
- D1:D5 要“返回”的值范围 (a,b,c,d,e)
B1:B5 是我要粘贴“查找”值的位置。
代码工作到一定程度,因为它确实为 C1:C5 中“查找”值的 位置 以及 D1 中相邻单元格中的正确值返回正确值: D5。
当我尝试将返回值加载到Arr4(要粘贴回工作表的数组)时,当我将鼠标悬停在<Type mismatch> 上时。它不会阻止代码执行,但不会粘贴任何内容。
我的问题是:
- 如何使用
myVal2值填充数组Arr4,以及 - 如何将其粘贴回工作表?
Option Explicit
Sub testArray()
Dim ArrLookupValues As Variant
ArrLookupValues = Sheet1.Range("A1:A5") 'The Lookup Values
Dim ArrLookupRange As Variant
ArrLookupRange = Sheet1.Range("C1:C5") 'The Range to find the Value
Dim ArrReturnValues As Variant
ArrReturnValues = Sheet1.Range("D1:D5") 'The adjacent Range to return the Lookup Value
Dim ArrOutput As Variant 'output array
Dim UpperElement As Long
UpperElement = UBound(ArrLookupValues) 'Used purely for the ReDim statement
Dim i As Long
For i = LBound(ArrLookupValues) To UBound(ArrLookupValues)
Dim myVal As Variant
myVal = ArrLookupValues(i, 1)
Dim pos As Variant 'variant becaus it can return an error
pos = Application.Match(myVal, ArrLookupRange, 0) 'pos always returns the correct position
Dim myVal2 As Variant
If Not IsError(pos) Then
myVal2 = ArrReturnValues(pos, 1) 'myVal2 always returns the correct value
ReDim Preserve ArrOutput(1 To UpperElement, 1 To 1)
ArrOutput(i, 1) = myVal2
Else
ReDim Preserve ArrOutput(1 To UpperElement, 1 To 1)
myVal2 = "Not Found"
ArrOutput(i, 1) = myVal2
End If
Next i
Dim Destination As Range
Set Destination = Range("B1")
Destination.Resize(UBound(ArrOutput, 1), UBound(ArrOutput, 2)).Value =
ArrOutput
End Sub
【问题讨论】:
-
首先你需要删除
On Error Resume Next。此行隐藏了 所有 错误消息,但错误仍然存在,您只是看不到它们的消息。因此,如果您没有看到错误,则无法修复它们,如果您不修复它们,它将无法工作。 -
@PEH 感谢您的及时回复。我同意你的说法,但是,当我删除该行时,如果代码没有找到匹配的值,则代码会在下一行停止执行。
-
然后使用适当的错误处理和
If语句:If Not IsError(pos) Then并将myVal2 = Arr3(pos, 1)和其余部分放入其中。永远不要像以前那样使用On Error Resume Next。 -
您的
Arr4也需要像其他数组一样是二维的。即使只有一列,也不必是Arr4(1 To UpperElement, 1 To 1)和Arr4(i, 1) = myVal2