优化VBA宏

时间:2016-05-12 07:00:56

标签: excel excel-vba vba

宏的工作原理如下:

  1. 我们有一个程序记录值,间隔为1-120秒,数据来自Sheet2,动态数据范围B:W列
  2. 用户在Sheet3上输入目标和偏差值
  3. 在Sheet2上,如果一行中的最大值大于"目标值减去偏差值"它将开始将行复制到Sheet1
  4. 上的表中
  5. 在Sheet1上的表中,每2分钟需要显示一次值,因此宏将复制每一行X(取决于间隔)
  6. 宏工作正常,但我需要在8个不同的目标值上运行8次。想知道是否有人有任何想法加快速度

    'Cell address with target value"  
    target = Sheets(3).Cells(93, 2).Value   
    'Cell address with deviation value"  
    deviation = Sheets(3).Cells(95, 2).Value 
    
    'Calculate time between measurements'  
    lngRowMultiplier = 120 / Sheets(3).Cells(81, "B").Value 
    
    
    
    'First row to copy into'  
    pasteRow = 34  
    'Row number to search through'  
    For i = 2 To 8000 
    
        'Range to search through'
        s_max_value_range = "B" & i & ":W" & i
    
        'Max value in a row'
        max_value = Application.WorksheetFunction.Max(Sheets(2).Range(s_max_value_range))
    
        If (Abs(target - max_value) <= deviation) Then
    
            'Copy up to 5 hours or until lowest value in a row will be bigger than target value + deviation'
            For j = 1 To 150
    
                'Minimum value in a row'
                min_value = Application.WorksheetFunction.Min(Sheets(2).Range("B" & i + (j - 1) * lngRowMultiplier & ":W" & i + (j - 1) * lngRowMultiplier))
    
                If (min_value <= target + deviation) Then
    
    
                s_copyRange = "B" & i + (j - 1) * lngRowMultiplier & ":W" & i + (j - 1) * lngRowMultiplier
                s_pasteRange = "C" & pasteRow & ":V" & pasteRow
    
                'Copy to Sheet1'
                Sheets(2).Range(s_copyRange).Copy Destination:=Sheets(1).Range(s_pasteRange)
                Sheets(1).Range("B" & pasteRow) = Sheets(2).Range("B" & i + (j - 1) * lngRowMultiplier)
                pasteRow = pasteRow + 1
                End If
            Next j
            i = 8001
        End If
    Next i
    

    所有帮助表示赞赏

1 个答案:

答案 0 :(得分:3)

VBA有一些规则可以让你的代码更快。

规则#1。不要复制和粘贴

复制和粘贴(或 PasteSpecial )功能很慢。使用以下内容复制和粘贴值的速度大约快25倍。

Range("A1:Z100").value = Range("A101:Z200").value

如果您这样做,您的代码可能会正常工作。如果您在许多行上执行此操作,则Mamory可能存在问题。

规则#2。计算

通常,当该单元格或范围的先例发生变化时,Excel将重新计算单元格或一系列单元格。这可能会导致您的工作簿经常重新计算,这会降低性能。您可以使用以下语句阻止Excel重新计算工作簿:

Application.Calculation = xlCalculationManual

在代码结束时,您可以使用以下语句将计算模式设置为自动:

Application.Calculation = xlCalculationAutomatic

但请记住,当计算模式为 xlCalculationManual 时,Excel不会更新单元格中的值。如果您的宏依赖于更新的单元格值,则必须使用类似Worksheets(1).Calculate的.Calculate方法强制执行Calculate事件。

规则#3。 ScreenUpdating

VBA的其他速度问题是,每次VBA将数据写入工作表时,它都会刷新您看到的屏幕图像。刷新图像对性能造成相当大的影响。以下命令将关闭屏幕更新。

Application.ScreenUpdating = FALSE

在宏的末尾使用以下命令重新打开屏幕更新。

Application.ScreenUpdating = TRUE

规则#4忽略事件

如果您为工作簿的Sheet1实现了Worksheet_Change事件。每次在Sheet1上更改单元格或范围时,都会运行Worksheet_Change事件。因此,如果您有一个操作Sheet1上的多个单元格的标准宏,则每次更改该工作表上的单元格时,您的宏必须在Worksheet_Change事件运行时暂停。您可以想象这种行为会如何减慢您的宏。

Application.EnableEvents = False

在代码结束时,您可以使用以下语句将EnableEvents模式设置回True:

Application.EnableEvents = True

规则#5带声明

录制宏时,您经常会多次操作同一个对象。通过使用With语句一次性对给定对象执行多个操作,可以节省时间并提高性能。

以下示例中使用的With语句告诉Excel一次应用所有格式更改:

With Range("A1").Font
.Bold = True
.Italic = True
.Underline = xlUnderlineStyleSingle
End With

养成将动作分块为With语句的习惯不仅可以让你的宏运行得更快,而且还可以更容易地阅读宏代码。