【问题标题】:Most Efficent Way to Add Formatting Excel - VBA添加格式 Excel 的最有效方法 - VBA
【发布时间】:2009-12-05 05:07:28
【问题描述】:

我有一个宏,可以将数百行数据添加到 Excel 电子表格中。我从插入每一行数据的循环中调用一个过程。每次插入该数据时,我一直在应用该行的格式。但是,在我的测试过程中,我发现当我不逐行应用格式化而是一次全部应用时,我可以将所有数据的插入速度提高约 3/4 秒(3.3 秒对 4.11 秒)。我要克服的问题是并非每一行都具有相同的格式。但是,有一个可预测的模式。两行一种格式和一行不同格式。有没有一种无需循环即可同时应用这两种不同格式的方法,可以让我保持所获得的性能提升(用户希望看到低于 2 秒的响应,因此这可能是一个很大的提升)。

我目前正在使用以下代码(在此期间屏幕更新、计算和事件等应用程序设置均已关闭)

Private Sub BuildTerminalSummary(ByRef terminals, ByVal timeFrame)
    Dim terminal As clsTerminal
    Dim curSheet As Worksheet
    Dim breakLoop As Boolean
    Dim terminalCode As String
    Dim rowNumber As Long

    Set terminal = New clsTerminal
    Set curSheet = Sheets("Terminal Summary")

    rowNumber = 7

    'Remove all content, borders, and tint
    ClearPage curSheet, rowNumber

    For Each terminal In terminals         
        AddDetailData curSheet, terminal.InfoArray, rowNumber
        AddDetailData curSheet, terminal.PriorInfoArray, rowNumber + 1
        AddDiffPercentFormulas curSheet, terminal.DiffPercentInfoArray, rowNumber + 2

        rowNumber = rowNumber + 2

    Next terminal

    'Make sure the columns are wide enough to display the numbers
    curSheet.Cells.EntireColumn.AutoFit

End Sub

Private Sub AddDetailData(ByRef curSheet, ByRef data, ByVal rowNumber)
    With curSheet
        With .Cells(rowNumber, 3).Resize(1, 16)
            .value = data
            .Style = "Comma"
            .NumberFormat = "_(* #,##0_);_(* (#,##0);_(* ""-""??_);_(@_)"
        End With
        'This overides the formatting in the revenue columns with currency instead of comma style
        With .Cells(rowNumber, 5).Resize(1, 2)
            .Style = "Currency"
            .NumberFormat = "_($* #,##0_);_($* (#,##0);_($* ""-""??_);_(@_)"
        End With
        With .Cells(rowNumber, 13).Resize(1, 6)
            .Style = "Currency"
        End With
    End With

End Sub

Private Sub AddDiffPercentFormulas(ByRef curSheet, ByRef data, ByVal rowNumber)
    With curSheet.Cells(rowNumber, 3).Resize(1, 16)
        .value = data
        .NumberFormat = "0.00%"
    End With

End Sub

【问题讨论】:

    标签: excel optimization vba


    【解决方案1】:

    如果您想避免使用复制/粘贴,您可以使用 AutoFill 将格式应用于范围。

    Range("A1:F3").AutoFill Destination:=Range("A1:F21"), Type:=xlFillFormats
    

    注意:源范围(“A1:F3”)需要是目标范围(“A1:F21”)的一部分

    您还可以使用通常的 vba 优化方法将计算设置为手动并禁用 ScreenUpdating 。尽管我认为它们不会对您的情况有任何显着的速度改进。

    Dim calc As XlCalculation
    calc = Application.Calculation
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
    Application.ScreenUpdating = True
    Application.Calculation = calc
    

    【讨论】:

      【解决方案2】:

      您有两种格式,一种模式为 2 行,另一种模式为 1 行。我称之为 2row 和 1row 格式。

      您可以将 2cell 格式应用于整个列/整个数据区域,然后仅循环通过 1cell 格式。

      【讨论】:

      • 我没有得到我想要的性能提升,但这确实有帮助。
      【解决方案3】:

      您可以重写 AddDetail() 以在同一个调用中获取两个数组,这样您就可以避免 50% 的调用,并且能够一次性格式化两行。这将节省大量时间。花费时间的是调用,而不是格式。

      尝试使用 .range(cell(rownum, 3), cell(rownum, 19)) 代替 .Resize(1, 16) ,它执行得更快。

      另一种快速的方法是格式化第一行并将完整的行格式复制到第二行,如

      MyRange(row, col).EntireRow.Copy
      MyRange(row+1, col).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
                                       SkipBlanks:=False, Transpose:=False
      

      除了我不能完全遵循您的代码之外,您使用 rownum 和 rownum+1 调用 AddDetail(),然后使用 rownum+2 调用 AddDiff...(),但最后您仅将 rownum 增加 2 .. . 您不应该将其增加 3 ... 还是要“覆盖”您使用 AddDetail() 创建的行之一。

      祝你好运 迈克D

      【讨论】:

      • 感谢您提供的信息,我将尝试一下并回复您。该示例的代码实际上被删减了,这就是为什么行编号似乎有点不对。
      • 我尝试了这些建议,但在性能方面没有看到任何好处。测试 resize 与其他方法的使用并没有减轻任何性能问题,并且复制粘贴实际上增加了整个过程的时间。
      猜你喜欢
      • 2020-10-18
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 2013-07-14
      相关资源
      最近更新 更多