使用许多ElseIf语句优化VBA速度

时间:2018-02-16 10:42:13

标签: excel vba excel-vba

我在VBA中运行代码,运行时间太长。它需要检查一个单元格中的值,确定该值是什么,如果该值被接受,则增加到4个相应计数器中的一个+ 1。单元格中的值可以是64个预定义单词中的任何一个。他们让我的工作方式归结为以下几点。

     Sub Overview

        Application.ScreenUpdating = False 'turns off screen updating to increase macro running speed
        Application.Calculation = xlCalculationManual 'Turns off automatic cell calculation to increase macro running speed

        Dim CountCondition1, SACountCondition1, WBDACountCondition1, StatusCountCondition1 As Long         'Defines counters for condition 1
        Dim CountCondition2, SACountCondition2, WBDACountCondition2, StatusCountCondition2 As Long         'Defines counters for condition 1
        'And so on for all 64 different values

        Dim UnitOverview As Range   'Defines range to use loop
        Dim Dataget As Long         'Defines counter to walk through loop

        ThisWorkbook.Sheets("Datadump").Range("E23").Value = Application.WorksheetFunction.CountA _
        (ThisWorkbook.Sheets("Status").Range("C:C")) - 1 
        'Displays total data amount in file, numbering about 132000 cells in column C

        For Each UnitOverview In ThisWorkbook.Sheets("Status").Range _
        ("A2:A" & ThisWorkbook.Sheets("Datadump").Range("E23").Value + 1) 
        'Create loop to check completion status for entire document. Column A contains the cells which have any of the 64 predefined values, these values are text based

        DataGetCompletion = (DataGetCompletion + 1)

        ThisWorkbook.Sheets("Datadump").Range("E17").Value = DataGetCompletion + 1 
        'Used to move cell reading range for each new loop cycle

        'The following code section counts the number of cells related to each plant
                If UnitOverview.Value = "Condition1" Then         
                   CountCondition1 = CountCondition + 1
                ElseIf UnitOverview.Value = "Condition2" Then
                   CountCondition2 = CountCondition2 + 1
        'This continues for all 64 different variables

        'The following section of code checks SA Terms for each value
        If UnitOverview.Value = "Condition1" And ThisWorkbook.Sheets("Status").Range _
        ("D" & ThisWorkbook.Sheets("Datadump").Range("E17").Value).Value = "Yes" Then
        SACondition1 = SACountCondition1 + 1
        ElseIf UnitOverview.Value = "Condition2" And ThisWorkbook.Sheets("Status").Range
        ("D" & ThisWorkbook.Sheets("Datadump").Range("E17").Value).Value = "Yes" Then
        SACountCondition2 = SACountCondition + 1
        ' Again this continues for all 64 different variables
        ' The same is then being done for the "WBDACOuntCondtion" terms and the "StatusCountCondition" Terms. 

        Next UnitOverview

        'Finally after the loop completes, all the different counters are assigend to cells in order to read them out and do whatever you like with 'em.

        Application.ScreenUpdating = True 'Turns screen updating back on
        Application.Calculation = xlCalculationAutomatic 'Turns automatic cell calculations back on

        End Sub

在A列的所有132000个单元格上运行此代码大约需要15分钟,这是我喜欢的方式。我是这样做的,因为这是我知道的唯一方式。任何帮助将非常感激。我考虑过制作一个列表来检查变量,但不会如何正确设置它,或者它是否比我当前的解决方案更快。

2 个答案:

答案 0 :(得分:2)

我建议使用Excel COUNTIF函数,而不是在VBA中进行计算。例如,要计算A2:A30范围内包含" Condition1"的单元格数量,请添加一个具有以下公式的新单元格:

=COUNTIF(A2:A30,"Condition1")

此值将在填充电子表格时计算,因此您只需从VBA中的单元格中检索该值。

答案 1 :(得分:1)

您似乎有64 * 4个明确定义的计数器 - 即256个明确定义的变量。我首先重新考虑,然后有4个64个元素的数组,每个元素都是计数器值。

Dim CountCondition(1 to 64) As Long
Dim SACountCondition(1 to 64) As Long
Dim WBDACountCondition(1 to 64) As Long
Dim StatusCountCondition(1 to 64) As Long

(如果这是您的偏好,您可以使用0到63索引数组 - 这只是一个示例。)

然后只评估4个案例并增加数组的相应元素。

即使它们是相同的,你也会在循环中重复昂贵的范围评估:

而不是:

ThisWorkbook.Sheets("Status").Range("D" & ThisWorkbook.Sheets("Datadump").Range("E17").Value).Value = "Yes"

...在每次测试中,将该条件(真/假)提取到循环之外/之前的变量中:

Dim status_D_is_yes As Boolean
status_D_is_yes = ThisWorkbook.Sheets("Status").Range("D" & ThisWorkbook.Sheets("Datadump").Range("E17").Value).Value = "Yes"

...然后在检查中使用该布尔变量。

话虽如此,如果你做了第一个建议,那么第二个建议最终可能是多余的。我会先做第二个建议(对不起!),因为它更容易做,并会立即提升性能。