Cân nhắc việc tận dụng các biến để làm việc với dữ liệu trong bộ nhớ thay vì tham chiếu trực tiếp đến trang tính.
Tránh tham khảo quá nhiều
Khi gọi một phương thức hoặc thuộc tính của một đối tượng, nó cần phải thông qua giao diện IDispatch của thành phần OLE. Cuộc gọi đến các thành phần OLE này mất thời gian, do đó việc giảm số lượng tham chiếu đến các thành phần OLE có thể cải thiện tốc độ của mã macro.
Để gọi các thuộc tính hoặc phương thức đối tượng, phương thức biểu diễn của Object.Method thường được sử dụng, nghĩa là "." biểu tượng được sử dụng để gọi các thuộc tính và phương thức.
Do đó, số lượng lệnh gọi phương thức hoặc thuộc tính có thể được đánh giá theo số lượng ký hiệu ".". Càng ít dấu "." biểu tượng, mã chạy càng nhanh.
Ví dụ: câu lệnh sau bao gồm 3 ký hiệu ".".
ThisWorkbook.Sheet1.Range("A1").Value = 100
Câu lệnh sau chỉ có một ký hiệu ".".
Activewindow.Top = 100
Dưới đây là một số thủ thuật để giảm số lượng ký hiệu "." để chạy nhanh hơn
Đầu tiên, khi bạn cần tham chiếu nhiều lần đến cùng một đối tượng, bạn có thể đặt đối tượng đó thành một biến để giảm số lượng lệnh gọi. Ví dụ: đoạn mã sau yêu cầu hai cuộc gọi trên mỗi dòng.
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = 100
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = 200
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = 300
Vì đối tượng Sheets("Sheet1") cần được tham chiếu nhiều lần nên trước tiên nó có thể được đặt thành một biến sht để mỗi mã chỉ cần được gọi một lần.
Set sht = ThisWorkbook.Sheets("Sheet1")
sht.Cells(1, 1) = 100
sht.Cells(2, 1) = 200
sht.Cells(3, 1) = 300
Thứ hai, nếu bạn không muốn khai báo biến tạm thời sht, bạn cũng có thể sử dụng câu lệnh With đã đề cập trước đó. Như thể hiện trong ví dụ sau:
With ThisWorkbook.Sheets("Sheet1")
.Cells(1, 1) = 100
.Cells(2, 1) = 200
.Cells(3, 1) = 300
End With
Thứ ba, khi có nhiều vòng lặp, hãy cố gắng giữ các thuộc tính và phương thức bên ngoài vòng lặp. Khi sử dụng lại giá trị thuộc tính của cùng một đối tượng trong vòng lặp, trước tiên bạn có thể gán giá trị thuộc tính cho một biến được chỉ định bên ngoài vòng lặp, sau đó sử dụng biến trong vòng lặp, điều này có thể đạt được tốc độ nhanh hơn. Như thể hiện trong ví dụ sau:
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = Cells(1, 2).Value
Next i
Mỗi vòng lặp trong ví dụ này lấy thuộc tính Giá trị của ô Ô (1,2). Nếu bạn gán thuộc tính Giá trị của Ô (1.2) cho một biến trước khi vòng lặp bắt đầu, bạn sẽ chạy nhanh hơn. Như thể hiện trong ví dụ sau:
tmp = Cells(1, 2).Value
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = tmp
Next i
Đoạn mã trên gọi ThisWorkbook.Sheets("Sheet1") mỗi khi nó lặp lại. Bạn có thể thực hiện việc này nhanh hơn bằng cách sử dụng câu lệnh With để di chuyển cuộc gọi đến ThisWorkbook.Sheets("Sheet1") bên ngoài vòng lặp. Như thể hiện trong ví dụ sau:
tmp = Cells(1, 2).Value
With ThisWorkbook.Sheets("Sheet1")
For i = 1 To 1000
.Cells(1, 1) = tmp
.Cells(2, 1) = tmp
.Cells(3, 1) = tmp
Next i
End With
Tránh sử dụng các loại biến thể
Những người mới bắt đầu thường thích sử dụng các biến kiểu Variant, có ưu điểm là ít phức tạp hơn vì có thể sử dụng bất kỳ loại dữ liệu nào mà không gặp vấn đề tràn bộ nhớ nếu dữ liệu quá lớn đối với kiểu dữ liệu Integer hoặc Long. Tuy nhiên, dữ liệu loại Varienmt yêu cầu nhiều dung lượng bộ nhớ hơn các loại được chỉ định khác (2 byte cho dữ liệu Số nguyên, 4 byte cho dữ liệu Dài và 16 byte cho dữ liệu Biến thể), VBA yêu cầu nhiều thời gian hơn để xử lý dữ liệu loại Biến thể so với các loại được chỉ định khác Dữ liệu. Như ví dụ sau đây cho thấy.
Sub VariantTest()
Dim i As Long
Dim ix As Integer, iy As Integer, iz As Integer
Dim vx As Variant, vy As Variant, vz As Variant
Dim tm As Date
vx = 100: vy = 50
tm = Timer
For i = 1 To 1000000
vz = vx * vy
vz = vx + vy
vz = vx - vy
vz = vx / vy
Next i
Debug.Print "Variant types take " & Format((Timer - tm), "0.00000") & " seconds"
ix = 100: iy = 50
tm = Timer
For i = 1 To 1000000
iz = ix * iy
iz = ix + iy
iz = ix - iy
iz = ix / iy
Next i
Debug.Print "Integer types take " & Format((Timer - tm), "0.00000") & " seconds"
End Sub
Trong đoạn mã trên, các dòng 8 đến 13 thực hiện 1 triệu phép tính cộng, trừ, nhân và chia các biến Biến thể và các dòng 17 đến 22 thực hiện 1 triệu phép tính cộng, trừ, nhân và chia các biến Số nguyên. Trên máy tính của tôi, thao tác của biến Variant mất khoảng 0,09375 giây, trong khi thao tác của biến Integer mất khoảng 0,03125 giây. Kết quả có thể khác nhau tùy theo từng máy tính, nhưng biến Variant chậm hơn đáng kể so với biến Integer .
Vì lý do này, bạn nên tránh sử dụng các biến Variant khi bạn có thể sử dụng rõ ràng kiểu dữ liệu đã chỉ định .