【发布时间】:2019-02-28 01:56:37
【问题描述】:
我有一个大型工作表(~250K 行,22 列,~40MB 纯数据),它必须将其内容传输到 Intranet API。格式无关紧要。问题是:当访问像
这样的数据时Const ROWS = 250000
Const COLS = 22
Dim x As Long, y As Long
Dim myRange As Variant
Dim dummyString As String
Dim sb As New cStringBuilder
myRange = Range(Cells(1, 1), Cells(ROWS, COLS)).Value2
For x = 1 To ROWS
For y = 1 To COLS
dummyString = myRange(x, y) 'Runtime with only this line: 1.8s
sb.Append dummyString 'Runtime with this additional line 163s
Next
Next
我得到了一个很棒的二维数组,但我无法有效地收集数据以进行 HTTP 导出。
数组上的 X/Y 循环和访问 myRange[x, y] 的运行时间 > 1 分钟。我找不到有助于获取 2D 数组的内爆/编码内容的数组方法。
我目前的解决方法是误用剪贴板 (Workaround for Memory Leak when using large string),它工作得很快,但在我看来是一个肮脏的解决方法,并且有一个主要问题:我得到的值是格式化的,“.Value”而不是“.Value2”,所以我必须在使用前再次转换服务器站点上的数据,例如将货币单元格格式化为浮点数。
处理数据数组的另一个想法是什么?
【问题讨论】:
-
myRange是什么类型的对象?我怀疑您将其声明为Range对象,而不是实际的变体。如果您声明为变体,则循环遍历它会快得多。 See example here -
请显示您现有的循环代码。有一个“stringbuilder”类的 VBA 实现,这可能是你想要的。还有“250M”行 - 你的意思是 250k 吗?
-
Scott:是的,它是一个变种,
set被错误地复制了。蒂姆:250K,不是 250M,谢谢。我用完整的测试功能更新了问题 -
您可能希望将
Dim sb As New cStringBuilder替换为Dim sb As cStringBuilder: Set sb = new cstringbuilder。所以每次引用对象的实例都不需要检查。 -
我认为您的 stringbuilder 类/对象正在使用某种形式的
join来减少连接不可变字符串的开销——因此相当有效。
标签: vba excel large-data