excel - 将单元格从一张纸复制到另一张纸时出现内存不足错误

标签 excel vba out-of-memory

关于这个问题有很多问题。我阅读了其中的许多内容并尝试了一些东西,但它们并没有解决我的问题。
我正在尝试比较两张不同(很长)纸上的线条。如果特定索引匹配,则需要将特定单元格(始终与当前行相同的列)从一张纸复制到另一张纸。
它看起来像这样更大(放大的例子):

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/

相关文章:

java - 是否可以使用 java 在不读取行的情况下合并两个文本文件?

Ruby 组合两个数组导致进程耗尽内存

python - 将不同列中的数据连接到单个列中(pandas、python)

xml - 在 VBA 中使用 DOM 解析 XML 时出错

arrays - Excel VBA - 将公式结果分配给数组

excel - 在另一张纸上查找值并复制整行

excel - 使用 Excel VBA 控制 Internet Explorer 本地 Intranet

excel - 出错时转到在一个模块中工作,但不在另一个模块中

excel - 使用vba在excel中设置求和公式

android - 内存不足错误 viewpager + imageView