2013-10-11 142 views
1

我想通过比较每个单元格的值来比较vba中的两个excel表单。有没有提高性能的最佳方法?比较两张excel表格的最佳方法是什么?

当我有超过2000到3000行在我的Excel表。它需要大约5分钟执行。有什么办法来优化这个代码?

Sub CompareWorksheets(WS1 As Worksheet, WS2 As Worksheet) 

Dim dR As Boolean 
Dim r As Long, c As Integer, m As Integer 
Dim lrow1 As Long, lrow2 As Long, lrow3 As Long 
Dim lcoloumn1 As Integer, lcoloumn2 As Integer, 
Dim maxR As Long, maxC As Integer, cf1 As String, cf2 As String 
Dim dupCount As Long 

With WS1.UsedRange 
    lrow1 = .Rows.Count 
    lcoloumn1 = .Columns.Count 
End With 

With ws2.UsedRange 
    lrow2 = .Rows.Count 
    lcoloumn2 = .Columns.Count 
End With 

maxR = lrow1 
maxC = lcoloumn1 

If maxR < lrow2 Then maxR = lrow2 
If maxC < lcoloumn2 Then maxC = lcoloumn2 
DiffCount = 0 
lrow3 = 1 

For i = 1 To maxR 
    dR = True 
    Application.StatusBar = "Comparing worksheets " & Format(i/maxR, "0 %") & "..." 
    For r = 1 To maxR 
     For c = 1 To maxC 
      WS1.Select 
      cf1 = "" 
      cf2 = "" 
      On Error Resume Next 
      cf1 = WS1.Cells(i, c).FormulaLocal 
      cf2 = ws2.Cells(r, c).FormulaLocal 
      On Error GoTo 0 
      If cf1 <> cf2 Then 
       dR = False 
       Exit For 
      Else 
       dR = True 
      End If 
     Next c 
     If dR Then 
     Exit For 
     End If 
    Next r 
    If Not dR Then 
     dupCount = dupCount + 1 
     WS1.Range(WS1.Cells(i, 1), WS1.Cells(i, maxC)).Select 
     Selection.Copy 
     Worksheets("Sheet3").Select 
     Worksheets("Sheet3").Range(Worksheets("Sheet3").Cells(lrow3, 1), Worksheets ("Sheet3").Cells(lrow3, maxC)).Select 
     Selection.PasteSpecial 
     lrow3 = lrow3 + 1 
     WS1.Select 
     For t = 1 To maxC 
      WS1.Cells(i, t).Interior.ColorIndex = 19 
      WS1.Cells(i, t).Select 
      Selection.Font.Bold = True 
     Next t 
    End If 
    Next i 
End Sub 

谢谢!

+0

显示您到目前为止的代码... –

+0

这就是我如何做的,但我没有它的性能问题。也许,这是你的代码结构的方式,而不是它的问题所在。你可以显示代码,以便我们检查吗? – neelsg

回答

3

可能最好的方法是将每张纸的范围值传递给一个数组。
然后迭代该数组的每个元素。

Sub test2() 

Dim arr1(), arr2() As Variant 
Dim i, j As Long 

arr1 = Sheets("Sheet1").Range("A1:D4").Value 
arr2 = Sheets("Sheet2").Range("A1:D4").Value 

For i = 1 To UBound(arr1, 1) 
    For j = 1 To UBound(arr1, 2) 
     If arr1(i, j) = arr2(i, j) Then 'do the comparison here 
      'code here 
     End If 
    Next j 
Next i 

End Sub 

上述代码仅用于相同的范围比较。
否则,您需要添加另一个循环。
希望这会让你开始。

更新:
下面是细胞的公式比较你的代码的部分的等效。

Dim arr1(), arr2() As Variant 

Set WS1 = ThisWorkbook.Sheets("Sheet1") 
Set WS2 = ThisWorkbook.Sheets("Sheet2") 

arr1 = WS1.UsedRange.FormulaLocal 
arr2 = WS1.UsedRange.FormulaLocal 

lrow1 = UBound(arr1, 1) 
lrow2 = UBound(arr2, 1) 
lcolumn1 = UBound(arr1, 2) 
lcolumn2 = UBound(arr2, 2) 

maxR = lrow1 
maxC = lcoloumn1 

If maxR < lrow2 Then maxR = lrow2 
If maxC < lcoloumn2 Then maxC = lcoloumn2 

DiffCount = 0 
lrow3 = 1 

For i = 1 To maxR 
    dR = True 
    Application.StatusBar = "Comparing worksheets " & Format(i/maxR, "0 %") & "..." 
    For r = 1 To maxR 
     For c = 1 To maxC 
      cf1 = "" 
      cf2 = "" 
      On Error Resume Next 
      cf1 = arr1(i, c) 
      cf2 = arr2(r, c) 
      On Error GoTo 0 
      If cf1 <> cf2 Then 
       dR = False 
       Exit For 
      Else 
       dR = True 
      End If 
     Next c 
     If dR Then 
      Exit For 
     End If 
    Next r 
'the rest of your code goes here which i cannot comprehend. 

我无法改善代码的其他部分,道歉。
我无法想象你想要完成什么。
希望这可以帮助你一点。

+0

@ L42-感谢您的回复。但是,上面的代码将用户限制在特定范围内。我们不想要这个限制。我们的代码应该检查任何数量的行和列。 – Vicky

+0

@Vicky是的,没问题。一旦你确定了你的动态范围,把它分配给一个数组。要在代码中使用'maxR'和'maxC',请在阵列中使用'Ubound'和'Lbound'。比较12000个单元需要不到一秒的时间。 – L42

+0

+1。另一种方法是在第三张纸上添加一个简单的'IF'测试程序到相同的使用范围,以识别差异。有用的商业替代方案是一个名为SpreadSheet Advantage的程序 - 这看起来是在可能有不同列或行的比较之前对齐页面(例如,页面顶部的单个空白行将通过比较) – brettdj

相关问题