Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 从两张图纸比较VBA太慢?_Excel_Vba - Fatal编程技术网

Excel 从两张图纸比较VBA太慢?

Excel 从两张图纸比较VBA太慢?,excel,vba,Excel,Vba,这是我的代码,我试图将一张包含3000行的工作表与另一张包含5000行的工作表进行比较,但是工作速度太慢,有人能帮忙吗 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

这是我的代码,我试图将一张包含3000行的工作表与另一张包含5000行的工作表进行比较,但是工作速度太慢,有人能帮忙吗

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
一些建议:

  • 由于您正在禁止屏幕更新,并且(非常正确地)没有使用“复制和粘贴”将数据从X.ActiveSheet移动到Sheet1,因此您确实不需要“ThisWorkbook1.Sheets(“Sheet1”).Activate”行在循环中反复重复。即使Sheet1已激活,激活调用也可能相当耗时,而且您不需要翻转哪个工作表处于激活状态

  • 此外,您还在循环中反复打开“E:\Partner\u Commission\u Compiler\Repository\Transaction\u 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

除了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
它声明它是一个
变体
。每次代码使用
ASI
,Excel都必须破译
ASI
中存储的数据类型,以确定如何分配或比较它。如果您将其声明为特定类型,它可以跳过该确定步骤,这将加快执行速度。由于要将其分配给单元格的内容,因此可以指定
String
Integer
。如果有时是一个,有时是另一个,
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
与:


删除每个循环上的所有这些分配将节省一些处理时间。但是,阅读代码有点困难,因此您可能希望在注释中留下一些伪代码,以帮助记住所有这些不同的单元格所代表的内容。

如果代码缩进,那么您的代码将更易于阅读和理解。我不介意这么做,所以这取决于你。嗨,Mark,iv更新了它,但是由于某种原因缩进并没有像它应该的那样出现。这对你来说是一个很大的改变,但是任何在许多单元格上循环的代码都可能需要相当长的时间,所以在这个场景中我总是使用数组。基本概念是,读取单元格的循环的每次迭代实际上是代码的软件层和工作表之间的I/O,因此单元格越多=I/O越多。如果使用数组方法,则将两个表的内容读入一个数组(每个1)=2个I/O,然后在代码中执行任意操作,可能写入另一个数组或更新现有数组,最后将任何更新的或新的数组写回目标。3 I/O’由于您的代码正在工作,尽管速度很慢,您的问题可能会得到更多关于可能的重复的答案。也很相关:谢谢你的帮助!节省了我很多时间:)也很有帮助,谢谢:)
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)