performance - Excel VBA : Writing an array to cells is very slow

标签 performance vba excel

我正在使用 Excel 中的 VBA 从 Reuters 3000 数据库中检索一些信息。我检索的数据是一个二维数组,其中一列保存日期,另一列保存数值。

在我检索信息后,这个过程不超过 2 秒,我想将此数据写入工作表。在工作表中,我有一列包含日期,而其他几列包含数值,每一列都包含同一类别的值。我遍历数组的行以获取日期和数值并将它们保存在变量中,然后在工作表的日期列上搜索日期,并在找到日期后写入值。这是我的代码:

Private Sub writeRetrievedData(retrievedData As Variant, dateColumnRange As String, columnOffset As Integer)

Dim element As Long: Dim startElement As Long: Dim endElement As Long
Dim instrumentDate As Variant: Dim instrumentValue As Variant
Dim c As Variant: Dim dateCellAddress As Variant

Application.ScreenUpdating = False    
Sheets("Data").Activate
startElement = LBound(retrievedData, 1): endElement = UBound(retrievedData, 1)
Application.DisplayStatusBar = True
Application.StatusBar = "Busy writing data to worksheet"

For element = startElement To endElement
    instrumentDate = retrievedData(element, 1): instrumentValue = retrievedData(element, 2)
    Range(dateColumnRange).Select
    Set c = Selection.Find(What:=instrumentDate, After:=ActiveCell, LookIn:=xlValues, _
            LookAt:=xlWhole, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
            MatchCase:=False, SearchFormat:=False)
    If Not c Is Nothing Then
        c.offset(0, columnOffset).Value = instrumentValue            
    End If
Next element

Application.DisplayStatusBar = False

End Sub

我的问题是这个过程很慢,即使数组中只有 5 行,完成任务也需要大约 15 秒。由于我想多次重复这个过程(我从数据库中检索的每组数据一次),我想尽可能地减少执行时间。

如您所见,我正在禁用屏幕更新,这是提高性能的最常见操作之一。有人对我如何进一步减少执行时间有建议吗?

PS。我知道数据检索过程并不需要太多,因为我已经测试了该部分(检索数据后立即在 MsgBox 上显示值)

先谢谢了。

最佳答案

这是我为提高性能所做的:

  • 避免在要写入值时选择单元格。这是蒂姆·威廉姆斯的建议。
  • 我将属性 Application.Calculation 设置为 xlCalculationManual
  • 我没有使用 Find() 函数来搜索日期,而是将工作表中的所有日期加载到一个数组中并遍历该数组以获取行号。事实证明这比 Find() 函数更快。
    Private Function loadDateArray() As Variant
    
        Dim Date_Arr() As Variant
    
        Sheets("Data").Activate
        Date_Arr = Range(Cells(3, 106), Cells(3, 106).End(xlDown))
        loadDateArray = Date_Arr
    
    End Function
    
    Private Function getDateRow(dateArray As Variant, dateToLook As Variant)
    
        Dim i As Double: Dim dateRow As Double
    
        For i = LBound(dateArray, 1) To UBound(dateArray, 1)
            If dateArray(i, 1) = dateToLook Then
                dateRow = i
                Exit For
            End If
        Next i
    
        getDateRow = dateRow
    
    End Function
    

  • 谢谢大家的帮助!

    关于performance - Excel VBA : Writing an array to cells is very slow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13626001/

    相关文章:

    excel - 从十六进制字符串转换为 Double 会产生错误的结果

    vba - 使用带有 ? 的字符串来自 Visual Basic 中的 Excel 单元格内容

    excel - 根据另一个单元格中的条件将正数值单元格输入更改为同一单元格中的负数值

    html - 使用VBA从网站上的表格中检索<TD>标签并放入excel

    excel - 使用 vlookup 或索引/匹配函数对多行中的值求和

    vba - 自动安装Excel VBA插件

    cocoa - 什么可能会导致 OSX/Cocoa 应用程序中的空窗口调整大小响应迟缓/不稳定?

    mysql - 如何提高带有 NULL 的 MySQL 查询的性能?

    python - 在 Python 列表中存储 Python 对象与固定长度的 Numpy 数组

    android - 为什么膨胀一个 Android 布局需要这么长时间?