VBA:比较两个不同工作表中两列的快速方法,并从工作表1中相应单元格旁边的第二个工作表复制值

时间:2017-05-17 19:58:25

标签: excel vba performance excel-vba loops

首先,如果我的英语不完美,我会事先道歉,我会尽力解释我的需要。

所以基本上,我有一个excel文件,其中有2张名为“Balance”和“Balance_MAJ”。

看起来像这样(只是一个小样本):"Balance" & "Balance_MAJ"

我需要的是比较“余额”的D列与“Balance_MAJ”的D列,以便更新“余额”的列F < / strong>使用“Balance_MAJ”的G列中的值。

实际上,这两张纸的D列包含相同的信息但不是相同的顺序。因此,我必须制作2个循环来比较这两个列,每次匹配时,我将在“Balance_MAJ”的G列中得到相应的值,我将把它放在“Balance”的F列中的相应单元格中。 / p>

类似的东西:What I need to do

问题是我的整个数据集包含大量数据(今天大约12 000行,未来可能包含更多行)。我使用了两种方法,在两种情况下都完美地工作,但它确实很慢(第一种方法约为1分50秒,第二种方法约为47秒)。

第一种方法(1mn50sec):

`Sub MAJ_Balance()

Dim i As Long
Dim j As Long
Dim lastRow_Balance As Long
Dim lastRow_BalanceMAJ As Long
Dim stNow As Date

stNow = Now

Application.ScreenUpdating = False

lastRow_Balance = Sheets("Balance").Cells(Rows.Count, "D").End(xlUp).Row
lastRow_BalanceMAJ = Sheets("Balance_MAJ").Cells(Rows.Count, 
"D").End(xlUp).Row

    For i = 5 To lastRow_Balance
      For j = 5 To lastRow_BalanceMAJ 
        If Sheets("Balance").Cells(i, "D").Value = 
           Sheets("Balance_MAJ").Cells(j, "D").Value Then
           Sheets("Balance").Cells(i, "F").Value = 
           Sheets("Balance_MAJ").Cells(j, "G").Value
        End If
      Next j
    Next i

MsgBox (DateDiff("s", stNow, Now))

Application.ScreenUpdating = True

End Sub`

第二种方法(47秒):

`Sub MAJ_Balance()

Dim i As Long
Dim j As Long
Dim v As Variant
Dim lastRow_Balance As Long
Dim lastRow_BalanceMAJ As Long
Dim stNow As Date

stNow = Now

Application.ScreenUpdating = False

lastRow_Balance = Sheets("Balance").Cells(Rows.Count, "D").End(xlUp).Row
lastRow_BalanceMAJ = Sheets("Balance_MAJ").Cells(Rows.Count, 
"D").End(xlUp).Row

    For i = 5 To lastRow_Balance
      With Sheets("Balance").Cells(i, "D")
      v = .Value
      For j = 5 To lastRow_BalanceMAJ 
        If v = Sheets("Balance_MAJ").Cells(j, "D").Value Then
        Sheets("Balance").Cells(i, "F").Value = 
        Sheets("Balance_MAJ").Cells(j, "G").Value
        End If
      Next j
      End With
    Next i

MsgBox (DateDiff("s", stNow, Now))

Application.ScreenUpdating = True

End Sub`

您对代码优化有什么想法吗? 最快的方法是什么?

我事先感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

我测试了另外两种方法,一种使用VLOOKUP,一种使用建议的数组。我使用您提供的样本设置,将数据复制到两张纸上的第28,676行。以下是两种方法的代码和我的速度测试宏:

Sub VLOOKUP_Method()

    Dim wb As Workbook
    Dim wsBal As Worksheet
    Dim wsMAJ As Worksheet

    Set wb = ActiveWorkbook
    Set wsBal = wb.Sheets("Balance")
    Set wsMAJ = wb.Sheets("Balance_MAJ")

    With wsBal.Range("F5", wsBal.Cells(wsBal.Rows.Count, "F").End(xlUp))
        .Formula = "=VLOOKUP(D" & .Row & ",'" & wsMAJ.Name & "'!D:G,4,FALSE)"
        .Value = .Value
    End With

End Sub

Sub ARRAY_Method()

    Dim wb As Workbook
    Dim wsBal As Worksheet
    Dim wsMAJ As Worksheet
    Dim aBalData As Variant
    Dim aMAJData As Variant
    Dim i As Long, j As Long

    Set wb = ActiveWorkbook
    Set wsBal = wb.Sheets("Balance")
    Set wsMAJ = wb.Sheets("Balance_MAJ")

    aBalData = wsBal.Range("B4").CurrentRegion.Value
    aMAJData = wsMAJ.Range("B4").CurrentRegion.Value

    For i = LBound(aBalData, 1) To UBound(aBalData, 1)
        For j = LBound(aMAJData, 1) To UBound(aMAJData, 1)
            If aBalData(i, 3) = aMAJData(j, 3) Then
                aBalData(i, 5) = aMAJData(j, 6)
                Exit For
            End If
        Next j
    Next i

    wsBal.Range("B4").Resize(UBound(aBalData, 1), UBound(aBalData, 2)).Value = aBalData

End Sub

Sub SpeedTests()

    Dim dTimer As Double
    Dim aResults(1 To 100, 1 To 2) As Variant
    Dim i As Long, j As Long

    j = 0
    For i = 1 To UBound(aResults, 1)
        j = j + 1
        dTimer = Timer
        VLOOKUP_Method
        aResults(j, 1) = Timer - dTimer
    Next i

    j = 0
    For i = 1 To UBound(aResults, 1)
        j = j + 1
        dTimer = Timer
        ARRAY_Method
        aResults(j, 2) = Timer - dTimer
    Next i

    Sheets("Speed_Results").Range("A2").Resize(UBound(aResults, 1), UBound(aResults, 2)).Value = aResults

End Sub

以下是我系统上的速度测试结果。 VLOOKUP速度提高了约2.5倍

enter image description here