I gave a very useful link to slippyk , I recommend to get acquainted with it.
To what is written there, I add the following from myself:
- It is useful for performance not only to read / write cells using a two-dimensional array. More universal advice: avoid, if possible, any calls in the loop to VBA library objects.
Worksheet , Range , Borders , etc. are all COM objects, and each call to their methods / properties is an additional overhead.
Accordingly, if you write cells with an array in one call .Range(...).Value = array , and then you want to format the table, setting the number formats, cell borders, etc., then process the cells with ranges too. If the formatting for different columns of the table should differ, treat each column as one range. But in no case in large tables do not process the cells one by one.
- Turning off the screen update, be sure to ensure that the Excel operation mode is restored so that an error during the macro execution will not lead the user to an empty application window. It will close Excel through the task manager and is not well expressed to the programmer :) Use the "On Error" operators.
Below I enclose a sample code that demonstrates the speed of filling a sheet with a million values ββ(a table of 10,000 lines per 100 columns). To run the code:
create an Excel workbook and two sheets in it
open the VBA editor window
rename sheets to "Sheet_1" and "Sheet_2"
on Sheet_1, you can enter several numeric values ββ(by entering a string or date, you can later see how the macro responds to the error)
create a module and insert macro code into it
run the macro (I have about 1.5 seconds) and go to the Excel window to see the results
Option Explicit Public Sub Test() Dim i As Long, j As Long, sum As Long Dim iLastRow As Long, iLastCol As Long Dim src_data As Variant Dim dst_data() As Variant ' ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ On Error GoTo lbl_error ' ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠ½ΠΊΡΠΈΠΉ, ΡΠΏΠΎΡΠΎΠ±Π½ΡΡ
Π·Π°ΠΌΠ΅Π΄Π»ΠΈΡΡ ΠΈΠ»ΠΈ ΠΏΡΠΈΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠ°ΠΊΡΠΎΡΠ° Application.ScreenUpdating = False Application.EnableEvents = False Application.DisplayAlerts = False ' ΡΡΠ΅Π½ΠΈΠ΅ ΠΈΡΡ
ΠΎΠ΄Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
Π² Π΄Π²ΡΠΌΠ΅ΡΠ½ΡΠΉ ΠΌΠ°ΡΡΠΈΠ² Variant With Sheet_1 iLastRow = .UsedRange.Row + .UsedRange.Rows.Count - 1 iLastCol = .UsedRange.Column + .UsedRange.Columns.Count - 1 src_data = .Range(.Cells(3, 3), .Cells(iLastRow, iLastCol)).Value End With ' ΠΊΠ°ΠΊΠ°Ρ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΈΡΡ
ΠΎΠ΄Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
(Π½Π΅Π²Π°ΠΆΠ½ΠΎ ΠΊΠ°ΠΊΠ°Ρ) sum = 0 For i = LBound(src_data, 1) To UBound(src_data, 1) For j = LBound(src_data, 2) To UBound(src_data, 2) sum = sum + CLng(src_data(i, j)) Next j Next i ' ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΠΈΠ²Π° Π΄Π°Π½Π½ΡΡ
10 000 * 100 = 1 000 000 Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ReDim dst_data(0 To 9999, 0 To 99) For i = 0 To 9999 For j = 0 To 99 dst_data(i, j) = sum + i + j Next j Next i ' Π·Π°ΠΏΠΈΡΡ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΠΈΠ²Π° Π² ΠΌΠ΅ΡΡΠΎ Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΡ With Sheet_2 .Range(.Cells(2, 2), .Cells(10001, 101)).Value = dst_data End With ' ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΡ With Sheet_2 ' ΡΠΎΡΠΌΠ°ΡΡ ΠΏΠ΅ΡΠ²ΡΡ
ΡΡΡΡ
ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ .Range(.Cells(2, 2), .Cells(10001, 2)).NumberFormat = "0.00" .Range(.Cells(2, 3), .Cells(10001, 4)).HorizontalAlignment = xlRight ' Π³ΡΠ°Π½ΠΈΡΡ Π½Π° Π²ΡΡ ΡΠ°Π±Π»ΠΈΡΡ With .Range(.Cells(2, 2), .Cells(10001, 101)) Call .BorderAround(xlContinuous, xlThin) With .Borders(xlInsideHorizontal) .LineStyle = xlContinuous .Weight = xlHairline End With With .Borders(xlInsideVertical) .LineStyle = xlContinuous .Weight = xlHairline End With End With End With ' ΠΏΠ΅ΡΠ΅ΠΏΡΡΠ³Π½ΡΡΡ Π±Π»ΠΎΠΊ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ GoTo lbl_finish ' ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΎΠΊ lbl_error: Call MsgBox("ΠΡΠΈΠ±ΠΊΠ° " & CStr(Err.Number) & ": " & Err.Description, vbCritical) On Error Resume Next ' Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ΅ΠΆΠΈΠΌ ΡΠ°Π±ΠΎΡΡ Excel lbl_finish: Application.DisplayAlerts = True Application.EnableEvents = True Application.ScreenUpdating = True ' ΠΏΠΎΠΊΠ°Π·Π°ΡΡ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π»ΠΈΡΡ Sheet_2.Activate End Sub
Application.ScreenUpdating=False), and do not forget to turn it back on. Option 2 - accumulate changes in a two-dimensional array, and then copy it in one line to the desired range. However, both are possible at the same time. - Akina