格式化单元格时极其缓慢的VBA代码

时间:2014-08-03 19:59:04

标签: vba excel-vba excel

尝试格式化工作簿中的2列时,宏的执行速度非常慢。要格式化大约4000行,需要10分钟以上。

日期从外部源填充,将外部源存储为字符串。

评论代码时,加载时间不超过60秒。

代码

'Discover last row of data
    RowsToProcess = Range("A" & Rows.Count).End(xlUp).Row

    For i = 6 To RowsToProcess
    Worksheets("Data").Range("B" & i).Select
    Selection.NumberFormat = "dd/mm/yy;;"
    Selection.Value = CDate(Selection.Value)

    Worksheets("Data").Range("C" & i).Select
    Selection.NumberFormat = "dd/mm/yy;;"
    Selection.Value = CDate(Selection.Value)

    Next i

以下代码也不会格式化所需格式的单元格。

Worksheets("Data).Columns("C").NumberFormat = dd/mm/yy;;"

1 个答案:

答案 0 :(得分:1)

与@elgoa链接的帖子是现货。如果加速代码的标准Application.ScreenUpdating选项不够,我会转向Variant数组。

(如果您想查看我如何使用Application.ScreenUpdating等,并将其包含在GoFast函数中,请在此处查看我的答案:VBA code optimization

以下脚本的工作方式如下:

  1. 将列B和C中定义的Range加载到Variant数组
  2. 在那里应用CDate逻辑(而不是每次都访问Sheet
  3. CDate - 已修改的数组写入Sheet
  4. 但有一点需要注意 - 我在上面评论中关于区分mm / dd和dd / mm(例如2014年5月6日对2014年6月5日)的问题仍然存在。我会根据您的想法修改下面的代码。谢谢!

    Option Explicit
    Sub ProcessDates()
    
    Dim AryColBandC As Variant
    Dim DateFormatB As Date, DateFormatC As Date
    Dim RngColBandC As Range
    Dim LastRow As Long, Counter As Long
    Dim MySheet As Worksheet
    
    'set references up-front
    Set MySheet = ThisWorkbook.Worksheets("Sheet1")
    With MySheet
        LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
        Set RngColBandC = .Range(.Cells(6, 2), .Cells(LastRow, 3))
    End With
    
    'load the B-C column range into a variant array
    AryColBandC = RngColBandC
    
    'loop through the variant array, applying the date
    'conversion to each entry in the array and writing back
    For Counter = LBound(AryColBandC) To UBound(AryColBandC)
        DateFormatB = CDate(AryColBandC(Counter, 1)) '<~ temporarily store
        DateFormatC = CDate(AryColBandC(Counter, 2)) '<~ dates here
    
        AryColBandC(Counter, 1) = DateFormatB
        AryColBandC(Counter, 2) = DateFormatC
    Next Counter
    
    'write the results out to the sheet
    For Counter = LBound(AryColBandC) To UBound(AryColBandC)
        MySheet.Cells(5 + Counter, 2) = AryColBandC(Counter, 1)
        MySheet.Cells(5 + Counter, 3) = AryColBandC(Counter, 2)
    Next Counter
    
    End Sub