【问题标题】:Optimizing VBA macro优化 VBA 宏
【发布时间】:2016-05-12 07:00:56
【问题描述】:

宏的工作原理如下:

  1. 我们有一个程序以 1-120s 的间隔记录值,来自它的数据在 Sheet2 上,动态数据范围 B:W 列
  2. 用户正在 Sheet3 上输入目标和偏差值
  3. 在 Sheet2 上,如果一行中的最大值大于“目标值减去偏差值”,它将开始将行复制到 Sheet1 上的表中
  4. Sheet1 表格中的值需要每 2 分钟显示一次,因此宏将复制每 X 行(取决于间隔)

宏工作正常,但我需要在 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

感谢所有帮助

【问题讨论】:

标签: excel vba


【解决方案1】:

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


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

复制和粘贴(或PasteSpecial)功能很慢。使用以下方法复制和粘贴值大约快 25 倍。

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

如果您这样做,您的代码可能会起作用。如果您对多行执行此操作,Mamory 可能存在问题。


规则 #2。计算

通常,当单元格或单元格区域的先例发生更改时,Excel 将重新计算该单元格或单元格区域。这可能会导致您的工作簿过于频繁地重新计算,从而降低性能。您可以使用以下语句阻止 Excel 重新计算工作簿:

Application.Calculation = xlCalculationManual

在代码的最后,您可以使用以下语句将计算模式设置回自动:

Application.Calculation = xlCalculationAutomatic

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


规则 #3。屏幕更新

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 语句中的习惯,不仅可以让您的宏运行得更快,还可以让您的宏代码更容易阅读。


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多