【发布时间】:2021-07-04 06:08:27
【问题描述】:
我提出了以下 VBA 代码,这些代码运行良好,但运行时间过长。所以,我正在尝试处理所有输入数组的数据。但我被 Vlookup APROXIMATE MATCH in ARRAYS 卡住了。
有效的 VBA 代码是:
Option Explicit
Sub VlookupAlternative()
Const INPUT_SHT = "shtSrc"
Const OUTPUT_SHT = "shtDest"
Dim wb As Workbook, wsIn As Worksheet, wsOut As Worksheet
Dim rngSrc As Range, rngDest As Range, celSrc As Range, celDest As Range
Dim rLastIn As Long, cLastIn As Long
Dim rLastOut As Long, cLastOut As Long
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.ScreenUpdating = False
On Error Resume Next
Set wb = ThisWorkbook
Set wsIn = wb.Sheets(INPUT_SHT)
Set wsOut = wb.Sheets(OUTPUT_SHT)
rLastIn = lastRow(wsIn)
cLastIn = LastCol(wsIn)
rLastOut = lastRow(wsOut)
cLastOut = LastCol(wsOut)
With wb
Set rngSrc = wsIn.Range("$A$2:$F$" & rLastIn)
Set rngDest = wsOut.Range("$B$2:$D$" & rLastOut)
' Compare top headers and left headers respectively. If matching, copy the value in destination table.
For Each celDest In rngDest
For Each celSrc In rngSrc
If wsIn.Cells(celSrc.Row, 1).Value = Application.IfError(Application.VLookup(CDbl(TimeValue(wsOut.Cells(celDest.Row, 1).Value)), rngSrc, 1, True), "") And _
wsIn.Cells(celSrc.Row, 3).Value = Format(wsOut.Cells(celDest.Row, 1).Value, "DDDD") And _
wsIn.Cells(1, celSrc.Column).Value = wsOut.Cells(1, celDest.Column).Value Then
celDest.Value = celSrc.Value
End If
Next celSrc
Next celDest
End With
Application.Calculation = xlCalculationAutomatic
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Function lastRow(sh As Worksheet)
On Error Resume Next
lastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
我尝试用数组编写的代码:
Option Explicit
Sub VlookupAlternativeArray()
Const INPUT_SHT = "shtSrc"
Const OUTPUT_SHT = "shtDest"
Dim wb As Workbook, wsIn As Worksheet, wsOut As Worksheet
Dim rngSrc As Range, rngDest As Range, rngLookup As Range, rngReturn As Range
Dim celSrc As Range, celDest As Range
Dim rLastIn As Long, cLastIn As Long
Dim rLastOut As Long, cLastOut As Long
Dim lookupArray As Variant, returnArray As Variant, destArray As Variant
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.ScreenUpdating = False
On Error Resume Next
Set wb = ThisWorkbook
Set wsIn = wb.Sheets(INPUT_SHT)
Set wsOut = wb.Sheets(OUTPUT_SHT)
rLastIn = lastRow(wsIn)
cLastIn = LastCol(wsIn)
rLastOut = lastRow(wsOut)
cLastOut = LastCol(wsOut)
Set rngLookup = wsIn.Range("$A$2:$C$" & rLastIn)
Set rngReturn = wsIn.Range("$D$2:$F$" & rLastIn)
Set rngDest = wsOut.Range("$B$2:$D$" & rLastOut)
lookupArray = rngLookup.Value2
returnArray = rngReturn.Value2
destArray = rngDest.Value2
'**********I want to put a vlookup approximate equivalent code here.*************************************************
' Dim desc As String
' Dim i As Long
' Dim j As Long
' For i = LBound(destArray, 1) To UBound(destArray, 1)
' desc = destArray(i, 1)
' For j = LBound(lookupArray, 1) To UBound(lookupArray, 1)
' If InStr(1, desc, lookupArray(j, 1), vbTextCompare) > 0 Then
' destArray(i, 2) = returnArray(j, 1)
' Exit For
' End If
' Next j
' Next i
'*********************************************************************************************************************
wsOut.Range("B2").Resize(UBound(destArray, 1), 1).Value2 = Application.Index(destArray, 0, 2)
Application.Calculation = xlCalculationAutomatic
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Function lastRow(sh As Worksheet)
On Error Resume Next
lastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
作为 VBA 的初学者,我需要指导如何在 ARRAYS 中处理 Vlookup APPROXIMATE MATCH。 Application.Vlookup 在数组中工作吗? VBA 字典在这里是更好的选择吗?任何代码示例或建议将不胜感激。
如果需要参考代码的上下文,详细here。
【问题讨论】: