簡體   English   中英

VBA:VLookUp多重結果

[英]VBA: VLookUp Multiple Results

我需要一些代碼的幫助。

我正在嘗試執行VLookup,並將數據顯示在O,P和Q列中。

我想要做的是循環通過工作表(“全局”)列A從第3行開始直到最后使用的行。 它需要匹配從第2行開始的A列表中的數據(“詳細信息”)。

因此,當它找到匹配值時,它將顯示“全局”O2中的“詳細信息”C2,“全局”P2中的“詳細信息”I2和“全局”Q2中的“詳細信息”G2中的結果。

然后它需要循環“全局”匹配並復制所有數據。 如果未找到匹配項,則顯示“NA!”。

我需要它做的最后一件事是刪除未找到匹配項的Global中的所有行。

我下面的代碼做了我需要的,唯一的問題是它非常慢,需要幾分鍾才能循環800行,有時甚至更長!

還有另一種方法可以做到這一點,它會更順暢,更快速地運行嗎?

任何幫助表示贊賞!!

謝謝

`Private Sub btnVlookUp_Click()
Dim i, j, lastG, lastD As Long

' find last row
lastG = Sheets("Global").Cells(Rows.Count, "B").End(xlUp).Row
lastD = Sheets("Details").Cells(Rows.Count, "A").End(xlUp).Row

' loop over values in "Global"
For i = 3 To lastG
    lookupVal = Sheets("Global").Cells(i, "B") ' value to find

    ' loop over values in "details"
    For j = 2 To lastD
        currVal = Sheets("Details").Cells(j, "A")

        If lookupVal = currVal Then
            Sheets("Global").Cells(i, "O") = Sheets("Details").Cells(j, "C")
            Sheets("Global").Cells(i, "P") = Sheets("Details").Cells(j, "I")
            Sheets("Global").Cells(i, "Q") = Sheets("Details").Cells(j, "G")
            ' mark the row
            Sheets("Details").Cells(j, "Z") = "marked"

        End If
    Next j
Next i

' loop over rows in "details" and delete rows which have not been marked
For j = 2 To lastD
    If Sheets("Details").Cells(j, "Z") <> "marked" Then
        ' delete unmarked rows
        Sheets("Details").Cells(j, "A").EntireRow.Delete
        If Sheets("Details").Cells(j, "B") <> "" Then
            j = j - 1 ' revert iterator so it doesn't skip rows
        End If
    Else:
        ' remove the mark
        Sheets("Details").Cells(j, "Z") = ""
    End If
Next j
End Sub`

根據這里的建議,以及大量的試驗和錯誤,我設法調整了我的代碼。

我在超過600條記錄上對此進行了測試,並在幾秒鍾內運行,在上一段代碼中需要幾分鍾。

如果你能看到更好的方法來做下面的代碼,那么讓我知道,我還在學習VBA所以所有的幫助我可以變得更好!

感謝所有的支持!!!!!!!!

Private Sub btnVlookUp_Click()
Dim i, j, lastG, lastD As Long
With Application
    .ScreenUpdating = False
    .EnableEvents = False
    .CutCopyMode = False
End With
' find last row
lastG = Sheets("Global").Cells(Rows.Count, "B").End(xlUp).Row
lastD = Sheets("Details").Cells(Rows.Count, "A").End(xlUp).Row

' loop over values in "Global"
For i = 2 To lastG
    lookupVal = Sheets("Global").Cells(i, "B") ' value to find

    ' loop over values in "details"
    For j = 2 To lastD
        currVal = Sheets("Details").Cells(j, "A")

        If lookupVal = currVal Then
            Sheets("Global").Cells(i, "O") = Sheets("Details").Cells(j, "C")
            Sheets("Global").Cells(i, "P") = Sheets("Details").Cells(j, "I")
            Sheets("Global").Cells(i, "Q") = Sheets("Details").Cells(j, "G")
            ' mark the row
            Sheets("Details").Cells(j, "Z") = "marked"
            Sheets("Details").Cells(1, "Z") = "marked"
        Exit For
        End If
    Next j
Next i

On Error Resume Next
Sheets("Details").Columns("Z").SpecialCells(xlBlanks).EntireRow.Delete
Sheets("Details").Columns("Z").ClearContents

With Application
    .ScreenUpdating = True
    .EnableEvents = True
    .CutCopyMode = True
End With

End Sub

您編寫的代碼效率非常低,這就是為什么它需要永遠。 您沒有具體提到“全局”和“詳細信息”表中有多少行(您提到800,不確定這兩者是否相同)。 但如果每個都有1000個,那么你的兩個循環是1000x1000 = 100萬個循環。

最好的解決方案是根本不使用VBA,而是在Excel中使用VLOOKUP函數。 這是你需要做的:

按列A對詳細信息表進行排序然后,在全局表單的單元格O3中,您將放置以下公式:= VLOOKUP(A3,詳細信息!$ A2:$ I(無論最后一行是什么),3,FALSE)

如果您不熟悉此函數,它將獲取第一個參數,在第二個參數的第一列中查找它,直到找到匹配項,然后在第三個參數的列中返回該行中的值。 最后一個“FALSE”只給你一個完全匹配,否則你會得到一個#NA(如果你使用TRUE,你會獲得最接近的匹配)。

然后將此公式復制到整個工作表中。

然后復制列,並粘貼值。 這擺脫了論壇,只留下了價值觀,這使得一切都變得更快。

然后按此列對表進行排序,並且所有#NA將合在一起,您可以在一個操作中刪除整個事物。

如果您想通過VBA執行此操作,可以輕松編寫上述步驟:

Private Sub btnVlookUp_Click()
Dim i, j, lastG, lastD As Long
Dim DetailsTable as Range

' find last row
lastG = Sheets("Global").Cells(Rows.Count, "B").End(xlUp).Row
lastD = Sheets("Details").Cells(Rows.Count, "A").End(xlUp).Row

' Make sure this is sorted.  If not, you'll need to add a sort command
Set DetailsTable=Sheets("Details").Range(Sheets("Details").Cells(1, 2), Sheets.Cells(lastD, 9))

Sheets("Global").Range("O3")="=VLOOKUP(A3," & DetailsTable.address(external:=true) & "3,FALSE)"
Sheets("Global").Range("O3").copy destination:=Sheets("Global").Range( Sheets("Global").cells(3,"O"),Sheets("Global").cells(lastG,"O"))

End Sub

這是一個開始,但應該讓你去。 祝好運!

您可以采取一些措施來輕松加快代碼速度。

首先,如果在代碼開頭添加Application.ScreenUpdating = False行,它將使Excel不必執行您在執行代碼時看到的所有閃爍和閃爍(實際上是在添加這些值之一)一個,刪除所有花費很多時間的行等。

接下來,您可以在If語句的末尾添加一個Exit For (在End If之前)。 這將停止嵌套的For循環,以防止在您找到所需內容后運行所有數據。

最后,我知道您使用j = j - 1來設置迭代器以不跳過行,但更好的做法是改為相反的方向。 如果將For循環更改為讀取For j = lastD to 2 Step -1它將使循環反向運行,因此刪除的行不是問題,您可以刪除“重置”行(這只會勉強加速你的代碼,它只是建議如何處理這個常見問題)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM