2015-03-25 83 views
0

所以這裏是我的代碼,即時試圖比較一個包含3000行與另一個5000行的工作表,但它工作太慢,任何人都可以幫忙嗎?VBA從兩張紙比較太慢?

Dim G As Long 
Dim K As Long 
Dim CardBrand As String 
Dim STD As String 
Dim CardBrand2 As String 
Dim ASI 
Dim ID As String 
Dim X As Workbook 
Dim FinalRow As Long 
Dim Finalrow2 As Long 
Dim I As Long 
Dim TC_STD As String 
Dim TC_ASI As String 
Dim TC_Perc As Double 
Dim TC_Base As Double 
Dim TC_ID As String 


    Application.ScreenUpdating = False 
    FinalRow = Cells(Rows.Count, "I").End(xlUp).Row 


    For G = 5 To FinalRow 

     CardBrand = Sheets("sheet1").Cells(G, 9).Value 
     STD = Sheets("sheet1").Cells(G, 10).Value 
     ID = Sheets("sheet1").Cells(G, 5).Value 

     For K = 2 To 51 

      CardBrand2 = Sheets("sheet2").Cells(K, 3).Value 

      If CardBrand = CardBrand2 Then 

       ASI = Sheets("sheet2").Cells(K, 1).Value 
       Set X = Workbooks.Open("E:\Partner_Commission_Compiler\Repository\Transaction_Charges.xlsx") 
       Finalrow2 = X.ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row 

       For I = 1 To Finalrow2 

        TC_ASI = X.ActiveSheet.Cells(I, 6).Value 
        TC_STD = X.ActiveSheet.Cells(I, 11).Value 
        TC_ID = X.ActiveSheet.Cells(I, 1).Value 

         If (TC_ASI = ASI) And (TC_STD = STD Or TC_STD = "All") And TC_ID = ID Then 

          TC_Perc = X.ActiveSheet.Cells(I, 19).Value 
          TC_Base = X.ActiveSheet.Cells(I, 20).Value 
          ThisWorkbook1.Sheets("Sheet1").Activate 

          Sheets("sheet1").Cells(G, 13).Value = TC_Perc 
          Sheets("sheet1").Cells(G, 14).Value = TC_Base 
         End If 
       Next I 
      End If 
     Next K 
    Next G 

    X.Close (False) 
    Application.ScreenUpdating = True 
+0

如果代碼是縮進的,你的代碼會更容易閱讀和理解。我不能爲此而煩惱,所以這取決於你。 – 2015-03-25 10:51:12

+0

嗨馬克,iv更新它,但縮進不是因爲它應該是有原因或另一個。 – 2015-03-25 11:03:25

+1

這對你來說會是一個很大的改變,但是任何在許多單元上循環的代碼可能需要很長時間,所以在這種情況下我總是使用數組。基本概念是讀取單元的循環的每次迭代實際上是代碼和工作表的軟件層之間的I/O,因此更多的單元=更多的I/O。你是否使用數組方法,將兩張表的內容讀入一個數組(每個數據爲1)= 2個I/O - 然後在代碼中執行任何你想要的操作,也許寫出另一個數組或更新現有的數組,最後,將任何更新或新的陣列寫回您的目標。 3 I/O's – 2015-03-25 11:08:45

回答

1

幾點建議:

  • 既然你沒有使用複製和粘貼從X.ActiveSheet移動數據到工作表Sheet1抑制ScreenUpdating,你是(非常正確),那麼你真的不要不需要線「ThisWorkbook1.Sheets(」Sheet1「)。激活」循環中重複。即使Sheet1已被激活,激活呼叫也可能非常耗時,並且不像您在翻轉哪張紙張處於活動狀態。

  • 此外,您正在循環中重複打開「E:\ Partner_Commission_Compiler \ Repository \ Transaction_Charges.xlsx」。再次不必要的,毫無疑問,當你不需要的時候,會消耗越來越多的CPU時間。

的以下兩行之前的任何您的循環移動:

Set X = Workbooks.Open("E:\Partner_Commission_Compiler\Repository\Transaction_Charges.xlsx") 
Finalrow2 = X.ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row 
+0

感謝非常有幫助!爲我節省了很多時間:) – 2015-03-25 18:31:40

1

除了cybermike的優良建議(而不是在每個循環中打開該文件應該保存顯著時間),你可以嘗試這些變化。

更改此:

CardBrand2 = Sheets("sheet2").Cells(K, 3).Value 
If CardBrand = CardBrand2 Then 

這個

If Sheets("sheet2").Cells(K, 3) = Sheets("sheet2").Cells(K, 3).Value 

您有:

Dim ASI 

它聲明它Variant。每次您的代碼使用ASI時,Excel都必須解密ASI中存儲的數據類型,以確定如何分配或比較它。如果您將其聲明爲特定類型,則可以跳過該加速執行的確定步驟。由於您將其分配給單元格的內容,因此可以指定StringInteger。如果它有時是一個,有時是另一個,然後是Dim as String,然後是明確的CStr(cell).value,並以字符串形式進行所有比較。它將再次消除Excel找出如何處理值的時間。

您可以更換:

TC_ASI = X.ActiveSheet.Cells(I, 6).Value 
TC_STD = X.ActiveSheet.Cells(I, 11).Value 
TC_ID = X.ActiveSheet.Cells(I, 1).Value 
If (TC_ASI = ASI) And (TC_STD = STD Or TC_STD = "All") And TC_ID = ID Then 
    TC_Perc = X.ActiveSheet.Cells(I, 19).Value 
    TC_Base = X.ActiveSheet.Cells(I, 20).Value 
    ThisWorkbook1.Sheets("Sheet1").Activate 
    Sheets("sheet1").Cells(G, 13).Value = TC_Perc 
    Sheets("sheet1").Cells(G, 14).Value = TC_Base 

有:

If x.cells(i,6) = Sheets("sheet2").Cells(K, 1) AND _ 
    (x.cells(1,11) = Sheets("sheet1").Cells(G, 10) OR _ 
    x.cells(1,11) = "All") AND _ 
    x.Cells(i,1) = Sheets("sheet1").Cells(G, 5) Then 
    Sheets("sheet1").Cells(G, 13).Value = X.Cells(I, 19) 
    Sheets("sheet1").Cells(G, 14).Value = X.Cells(I, 20) 

刪除每個迴路所有這些任務將節省一些處理時間。然而,閱讀代碼有點困難,所以你可能想在註釋中留下一些僞代碼來幫助記住所有這些不同的單元格代表什麼。

+0

也非常有幫助謝謝:) – 2015-03-25 18:31:56