关于这个问题有很多问题。我阅读了其中的许多内容并尝试了一些东西,但它们并没有解决我的问题。
我正在尝试比较两张不同(很长)纸上的线条。如果特定索引匹配,则需要将特定单元格(始终与当前行相同的列)从一张纸复制到另一张纸。
它看起来像这样更大(放大的例子):
Dim ArrayOne() as string
Dim ArrayTwo() as string
Redim ArrayOne (1 to AmountOfRowsSheet1)
Redim ArrayTwo (1 to AmountOfRowsSheet2)
For i = 1 to AmountOfRowsSheet1
ArrayOne(i) = Sheet1.Cells(i, ThisColumn)
next i
For i = 1 to AmountOfRowsSheet2
ArrayTwo(i) = Sheet2.Cells(i, ThatColumn)
next i
for i = 1 to 4600
for j = 1 to 69000
if ArrayOne(i) Like "*" & ArrayTwo(j) then
Sheet1.Cells(i, 5).value = Sheet3.Cells(i,10).value
'the line above is repeated about 20 times just with different columns
'so it gets potentially executed 4600*69000*20 times (6348000000)
end if
next j
next i
For-loop 并且一切正常,它也可以正确复制,但是经过大量行后,我的内存不足。在 TaskManager 中,我可以看到我使用的 RAM 每隔几秒就会增加一次。 Excel 有时会显示一个错误,由于缺乏资源,它无法处理下一次复制。我试过了:
Application.CutCopyMode = False '( at restart of loop)
创建一个空数据对象并将其放入剪贴板。以及我发现的一些 user32.dll 修复。
最佳答案
我把你的例子变成了你将如何使用数组
Option Explicit
Sub Example()
Dim ArrayOne() As Variant
Dim ArrayTwo() As Variant
ArrayOne = Sheet1.Columns(1).Value 'read column 1 into array
ArrayTwo = Sheet2.Columns(2).Value 'read column 2 into array
Dim start
start = Timer
Dim i As Long
For i = 1 To 4600
Dim j As Long
For j = 1 To 69000
If ArrayOne(i, 1) Like "*" & ArrayTwo(j, 1) Then
Sheet.Cells(i, 5).Value = Sheet.Cells(i, 10).Value + 1
End If
Next j
Debug.Print i, start, Timer, "Runtime=" & Timer-start
Stop 'we want to test time of one iteration = 23 seconds
Next i
End Sub
此示例运行 23
j
的一次迭代的秒数(在我的计算机上)环形。所以这将总共运行23*4600
秒,大约是 30
小时。因此,要么删除需要处理的数据,要么使用 Excel VBA 以外的其他工具来更快地获取数据。或者你改变你的整个方法。
请注意,VBA 仅限于单线程。因此,无论您的 CPU 有多少个内核,VBA 都只会使用一个。这使得它实际上是处理大数据的一个非常糟糕的工具。
实际上,您需要摆脱的是对单元格的读/写操作
Sheet.Cells(i, 5).Value = Sheet.Cells(i, 10).Value
每当您访问一个单元格值时,它都会减慢很多。如果没有该行,循环将在 2
中运行。而不是 23
秒(仍然是 2.5
小时的总运行时间)。所以有可能获得更快的速度,但可能不会比 2.5
快多少。小时。如果您无法摆脱多个读/写操作,那么甚至关闭计算
Application.Calculation = xlCalculationManual
在进入循环之前会带来巨大的提升。只是不要忘记打开它Application.Calculation = xlCalculationAutomatic
到底。请注意,只有在循环运行时没有需要计算的公式时,关闭计算才有效(否则会得到错误的结果)。我建议尝试像上面那样改进您的真实代码,并检查运行时是否完整运行内部
j
就像我对 stop
所做的那样循环命令。这样,您可以通过乘以 4600 轻松计算整个运行时间。
关于excel - 将单元格从一张纸复制到另一张纸时出现内存不足错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67107249/