2012-11-29 168 views
1

我正在使用Excel中的VBA从路由器3000数据库中检索一些信息。我检索的数据来自一个二维数组,其中包含一列保存日期和其他列保存数值。Excel VBA:将数组写入单元格非常慢

我检索信息后,一个过程不超过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 

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

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

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

感谢高级。

+2

为什么你有可能把整个范围,并把它在一个二维数组?然后在代码中执行处理,并将其哑至该范围?你能给我看一张你的数据表的照片,我会试试看。 – bonCodigo

+2

你有没有在工作表中的公式?如果你这样做,你可能想要关闭计算。那在过去导致了我的胃灼热。也许你可以为你的值创建一个散列表并从线性数组中填充列表?我怀疑搜索是永恒的。 – Bmo

+3

在循环中使用Find()有时会很慢。加载一个带有乐器名称的字典作为键和每个乐器的范围,如果你有很多单元可以找到,那么这个值会快得多。你应该总是避免在你的代码中选择范围:你可以这样做'c.Offset(0,colOffset)。价值= instrumentValue' –

回答

5

这是我做过什么,以提高性能:

  • 避免选择当值将会写入单元格。这是Tim Williams的建议。
  • 我设置属性Application.Calculation到xlCalculationManual
  • 除了使用查找()函数来搜索日期,我都装在工作表的日期到一个数组,遍历这个数组以得到行数。事实证明,这比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 
    

谢谢大家的帮助!

+0

如果您的“比较”项目列表非常大,我推荐一本词典。 – Pynner

1

通过不选择工作表,您可以添加更多的速度。取而代之的

Sheets("Data").Activate 
Date_Arr = Range(Cells(3, 106), Cells(3, 106).End(xlDown)) 
loadDateArray = Date_Arr 

尝试

With Sheets("Data") 
Date_Arr = .Range(Cells(3, 106), Cells(3, 106).End(xlDown)) 
End With 
相关问题