How to Fix Excel VBA 'Out of Memory' Error When Copying Large Arrays to a Worksheet
The Problem: Why Large Arrays Cause Out of Memory Crashes
When working with massive datasets in Excel VBA (such as 500,000 rows and 30 columns), processing the data in a memory-resident Variant array is incredibly fast. However, writing that array back to a worksheet in one single operation often triggers Run-time error '7': Out of memory or causes Excel to crash entirely.
Even on 64-bit Excel, which has access to virtually unlimited virtual memory, this crash occurs because Excel's COM interface attempts to serialize the entire array into memory before flushing it to the grid. This creates an enormous, contiguous memory spike that exceeds Excel's internal limits for single-operation transactions.
The Solution: Chunking (Batching) the Array
The most reliable way to prevent this crash is to write the array to the worksheet in smaller, manageable "chunks" (e.g., 50,000 rows at a time). This keeps memory usage low and allows Excel's garbage collector to release memory between writes.
Here is an optimized, production-ready VBA macro that demonstrates how to write a large array in chunks:
Sub WriteArrayInChunks()
Dim MyArray() As Variant
' (Assume MyArray is already populated with 500,000 rows and 30 columns)
Dim totalRows As Long, totalCols As Long
totalRows = UBound(MyArray, 1)
totalCols = UBound(MyArray, 2)
Dim chunkSize As Long
chunkSize = 50000 ' Write 50,000 rows at a time
Dim ws As Worksheet
Set ws = Sheets("Output")
Dim startRow As Long, endRow As Long
Dim currentRows As Long
Dim tempArray() As Variant
Dim r As Long, c As Long
' Turn off Excel features to boost performance
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
For startRow = 1 To totalRows Step chunkSize
endRow = startRow + chunkSize - 1
If endRow > totalRows Then endRow = totalRows
currentRows = endRow - startRow + 1
' Resize temp array for the current batch
ReDim tempArray(1 To currentRows, 1 To totalCols)
' Copy block from main array to temp array
For r = 1 To currentRows
For c = 1 To totalCols
tempArray(r, c) = MyArray(startRow + r - 1, c)
Next c
Next r
' Write to worksheet using Value2 for better performance
ws.Cells(startRow, 1).Resize(currentRows, totalCols).Value2 = tempArray
Erase tempArray
DoEvents ' Yield execution to let Excel clear memory
Next startRow
' Restore settings
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End SubAdditional Optimizations to Prevent Crashes
- Use
Value2instead ofValue:Range.Value2is faster and uses less memory because it does not attempt to parse date and currency formats during the assignment. - Call
DoEvents: InsertingDoEventsinside the chunking loop yields execution back to the operating system, allowing Excel to clean up temporary COM objects and prevent memory leaks. - Avoid
Application.Transpose: Never useTransposeon large datasets, as it is limited to 65,536 rows and will throw an error.
By implementing chunking and utilizing Value2, you can process millions of data points in Excel VBA without ever hitting the dreaded 'Out of Memory' ceiling.