【问题标题】:Excel VBA: Variants in Array VariablesExcel VBA:数组变量中的变体
【发布时间】:2011-11-22 18:01:09
【问题描述】:

关于变体的问题。我知道 Excel vba 中的变体既是默认数据类型,也是低效的(从大型应用程序过度使用的角度来看)。但是,我经常使用它们将数据存储在具有多种数据类型的数组中。我目前正在进行的一个项目本质上是一项需要对非常糟糕的代码(c.7000 行)进行大量优化的任务——这让我开始思考;有没有办法解决这个问题?

解释;该代码经常将数据存储在数组变量中。所以考虑一个 10 列乘以 10000 的数据集。这些列是多种不同的数据类型(字符串、双精度、整数、日期等)。假设我想将这些存储在一个数组中,我通常会;

dim myDataSet(10,10000) as variant

但是,据我所知,如果代码评估每个项目以确定它是什么数据类型,这将是非常低效的(实际上我知道我期望什么)。另外,我失去了对单个数据类型进行标注给我的控制。所以,(假设前 6 个是字符串,接下来的 4 个是双打,以便于解释这一点),我可以;

dim myDSstrings(6,10000) as string
dim myDSdoubles(4,10000) as double

这让我恢复了控制和效率——但也有点笨拙(实际上,类型是混合的和不同的——我最终在每个元素中都有奇数个元素,最终不得不单独分配它们在代码中而不是在质量上)。所以,这是一个案例;

myDSstrings(1,r) = cells(r,1)
myDSdoubles(2,r) = cells(r,2)
myDSstrings(2,r) = cells(r,3)
myDSstrings(3,r) = cells(r,4)
myDSdoubles(3,r) = cells(r,5)
..etc...

这比哪个丑多了;

myDataSet(c,r) = cells(r,c)

所以——这让我开始思考——我一定是在这里遗漏了什么。存储不同数据类型数组的最佳方式是什么?或者,假设没有办法做到这一点——存储混合数据类型数组的最佳编码实践是什么?

【问题讨论】:

标签: arrays excel vba types variant


【解决方案1】:

在没有先进行测量的情况下,切勿优化您的代码。您可能会对代码最慢的地方感到惊讶。我使用 Professional Excel Development 中的 PerfMon 实用程序,但您也可以自己使用。

从 Excel Ranges 读取和写入是一个很大的时间消耗。即使变体会浪费大量内存,这

Dim vaRange as Variant
vaRange = Sheet1.Range("A1:E10000").Value
'do something to the array
Sheet1.Range("A1:E10000").Value = vaRange

通常比遍历行和单元格更快。

我更喜欢使用具有多种数据类型的数组的方法是根本不使用数组。相反,我将使用自定义类模块并为元素创建属性。这不一定是性能提升,但它使代码更易于编写和阅读。

【讨论】:

  • 谢谢迪克——这是我所追求的东西。所需的循环和优化程度都与此无关 - 代码需要 15 分钟才能运行,并且我对哪些位导致瓶颈有相当详细的了解(过度使用变体当然不是重要原因!)。这更像是一个笼统的问题。我没有想过使用类模块来构建属性——我可能会根据我能找到的资源发布一个关于这种方法的新问题。非常感谢。
  • 发现这个 Q 有很好的例子来说明如何做到这一点。 stackoverflow.com/questions/2161666/…
【解决方案2】:

我不确定您的瓶颈是否来自数组的 Variant 类型。

顺便说一下,要将数组中的值设置为 Excel 范围,您应该使用(在 Excel 8 或更高版本中):

Range("A1:B2") = myArray

在以前的版本中,您应该使用以下代码:

Sub SuperBlastArrayToSheet(TheArray As Variant, TheRange As Range)
  With TheRange.Parent.Parent 'the workbook the range is in
    .Names.Add Name:="wstempdata", RefersToR1C1:=TheArray
    With TheRange
      .FormulaArray = "=wstempdata"
      .Copy
      .PasteSpecial Paste:=xlValues
    End With
    .Names("wstempdata").Delete
  End With
End Sub

来自this source,您应该阅读以了解 VBA 优化。

不过,您应该分析您的应用以了解您的瓶颈在哪里。请参阅 this question from Issun 以帮助您对代码进行基准测试。

【讨论】:

  • 反之亦然:myArray = range("a1:b2") !!
  • myArray = range("a1:b2").value
猜你喜欢
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多