【问题标题】:VBA - How to make code with For Loops and IF Statements more efficient?VBA - 如何使用 For 循环和 IF 语句使代码更高效?
【发布时间】:2020-06-26 19:58:57
【问题描述】:

我编写了一个代码来匹配数据(MaterialPN 与 MaterialPS 和 WeekPN 与 WeekPS)并在两张表之间复制适当的值(包装需求 - PN 和包装暂存 - PS)。

我已经关闭了屏幕更新、计算和事件。这使得运行时间从 5 分钟变为 1 分钟,这仍然很慢(我的数据只有约 3000 行)。我还尝试使用 GoTo Flag1 在 WeekPN 不等于 WeekPS 时强制退出 If 语句,但这并没有使我的代码运行得更快。

关于如何使这段代码更高效的任何提示?

提前感谢您的帮助!

Sub PackagingNeeds2PackagingStaging()
       
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

With Sheets("Packaging Needs")
i = .Cells(.Rows.Count, 5).End(xlUp).Row
End With

With Sheets("Packaging Staging")
l = .Cells(.Rows.Count, 1).End(xlUp).Row
End With

j = 25
    For k = 9 To i
        For x = 5 To l
            For Z = 14 To j
            
                MaterialPN = Sheets("Packaging Needs").Cells(k, 5).Value
                MaterialPS = Sheets("Packaging Staging").Cells(x, 1).Value

                WeekPN = Sheets("Packaging Needs").Cells(4, Z).Value
                WeekPS = Sheets("Packaging Staging").Cells(x, 12).Value
                
                If WeekPN <> WeekPS Then GoTo Flag1
                    If WeekPN = WeekPS Then
                        If MaterialPN = MaterialPS Then
                            Sheets("Packaging Staging").Cells(x, 19).Value = Sheets("Packaging Needs").Cells(k, Z).Value
                        End If
                    End If

Flag1:
            Next
        Next
    k = k + 5
    Next
    
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

End Sub

【问题讨论】:

  • 用户变量数组。
  • 至少使用Range.Find找到Z而不需要循环。
  • 每次点击工作表都会增加执行时间,因此将不使用 z 的调用向上移动到 x 或 k 循环中。此外,参考中的每个. 都会花费您,因此请声明一些工作表变量并使用它们。这甚至没有进入变体数组。您的 Goto 更改没有帮助,因为它没有保存任何步骤 - 您添加了一个 if 测试,最多只会跳过下一个 if 测试。
  • 在此处查看答案stackoverflow.com/questions/29596432/…Goto 被严重贬值和错误使用。您缺少End If
  • @TimWilliams 您的提示非常有效。代码现在在 5 秒内运行。非常感谢!

标签: excel vba if-statement runtime nested-for-loop


【解决方案1】:

一些建议 - 使用 Variant 数组可能会更快,而且如果 Match 在这里合适(很难说不知道您希望进行多少匹配 - 如果只有一个,那么您也可以 Exit For 打破一旦你得到一个匹配的循环)

Sub PackagingNeeds2PackagingStaging()
       
    Const J As Long = 25 'use Const for fixed values
    Dim i As Long, x As Long, l As Long, k As Long, z As Long
    Dim shtPN As Worksheet, shtPS As Worksheet
    Dim MaterialPN, MaterialPS, WeekPS
    
    'use worksheet variables
    Set shtPN = ThisWorkbook.Sheets("Packaging Needs")
    Set shtPS = ThisWorkbook.Sheets("Packaging Staging")
    
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    
    i = shtPN.Cells(shtPN.Rows.Count, 5).End(xlUp).Row
    l = shtPS.Cells(shtPS.Rows.Count, 1).End(xlUp).Row
    
    For k = 9 To i Step 5 '<< use Step instead of your line below
        MaterialPN = shtPN.Cells(k, 5).Value '<< moved this up
        For x = 5 To l
            MaterialPS = shtPS.Cells(x, 1).Value  '<< moved this up
            WeekPS = shtPS.Cells(x, 12).Value     '<< ...and this
            For z = 14 To J
                If shtPN.Cells(4, z).Value = WeekPS Then
                    If MaterialPN = MaterialPS Then
                        shtPS.Cells(x, 19).Value = shtPN.Cells(k, z).Value
                    End If
                End If
            Next z
        Next x
        'k = k + 5 '<<< don't change the counter inside a For loop!
    Next k
        
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True

End Sub

【讨论】:

    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    相关资源
    最近更新 更多