HeSanbi
Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
- Tham gia
- 24/2/13
- Bài viết
- 2,610
- Được thích
- 4,046
- Giới tính
- Nam
(*Đọc xong bài viết và các bạn hãy thử viết một hàm đăng lên chủ đề này!)
Các bạn đã biết lập trình mảng động trong VBA là gì hay chưa? Các bạn sẽ biết ngay sau khi bỏ ra vài phút để đọc bài viết này.
Định nghĩa "mảng động": hiểu đơn giản là dữ liệu hoặc mảng dữ liệu gốc trong bảng tính thay đổi thì mảng trả kết quả cũng thay đổi theo.
Có hai kiểu lập trình xử lý mảng động, lập trình mảng động cơ bản và lập trình mảng động phụ thuộc WinAPI.
A. Lập trình Mảng động căn bản:
B. Lập trình Mảng động phụ thuộc WinAPI:
----------------
Các bạn đã biết lập trình mảng động trong VBA là gì hay chưa? Các bạn sẽ biết ngay sau khi bỏ ra vài phút để đọc bài viết này.
Định nghĩa "mảng động": hiểu đơn giản là dữ liệu hoặc mảng dữ liệu gốc trong bảng tính thay đổi thì mảng trả kết quả cũng thay đổi theo.
Có hai kiểu lập trình xử lý mảng động, lập trình mảng động cơ bản và lập trình mảng động phụ thuộc WinAPI.
A. Lập trình Mảng động căn bản:
Các bạn đã từng vận dụng các Hàm mảng động Excel như UNIQUE , SORT, SORTBY, FILTER, SEQUENCE, RANDARRAY, SINGLE, tùy vào phiên bản, tùy vào hàm nhưng thường thì áp dụng các hàm trên vào bảng tính Excel là sự kết hợp của tổ hợp phím "Ctrl+Shift+Enter".
Và với Lập trình Mảng động căn bản cũng vận dụng tổ hợp phím như vậy để áp dụng hàm.
1. Cách viết hàm mảng động:
+ Viết một hàm trả về kết quả mảng bình thường.
+ Khởi tạo hàm nhận trả kết quả có cặp ngoặc tròn () đằng sau kiểu khởi tạo. Hoặc đằng sau mảng khi trả kết quả.
+ Có hoặc không đặt Application.Volatile vào hàm: Buộc tính toán lại khi giá trị của một ô trong bảng tính thay đổi, nếu có nhiều hàm có Application.Volatile sẽ khiến độ trễ của việc tính toán Excel càng lúc càng lớn.
Ví dụ 1:
PHP:
'Cách 1:'
Function CopyRangeValue(ByVal oRange As Object) As Variant()
Application.Volatile
CopyRangeValue = oRange.Value
End Function
'Cách 2:'
Function CopyRangeValue(ByVal oRange As Object)
Dim Arr()
Application.Volatile
Arr = oRange.Value
CopyRangeValue = Arr()
End Function
----------------
Ví dụ 2:
PHP:
Function RandomNumbers(ByVal Number As Long, _
ByVal Row As Integer, _
ByVal Column As Integer, _
Optional ByVal optVolatile As Boolean) As Variant()
If optVolatile Then Application.Volatile
Dim Arr(), R As Integer, C As Integer
ReDim Arr(1 To Row, 1 To Column)
Randomize
For R = 1 To Row
For C = 1 To Column
Arr(R, C) = R + Rnd
Next C
Next R
RandomNumbers = Arr()
End Function
----------------
2. Hàm được hiển thị trong Cell như thế nào?
{=RandomNumbers(2, 10, 2, True)} |
3. Cách áp dụng:
Kéo chuột Chọn một vùng Range để áp dụng
Với =RandomNumbers(2, 10, 2, True) thì vùng chọn là A1:B10, sau khi chọn xong gõ hàm vào thanh công thức, và ấn tổ hợp Ctrl+Shift+Enter.
4. Ưu điểm và nhược điểm:
+ Nhược điểm: Khi đã tạo Mảng động, không thể chèn xóa hàng cột thuộc mảng động. Phải sử dụng tổ hợp phím Ctrl+Shift+Enter để hoàn thành. Phải chọn vùng trước khi nhập hàm.
B. Lập trình Mảng động phụ thuộc WinAPI:
Lập trình Mảng động phụ thuộc WinAPI sẽ tạo nên một sự phong phú và đa dạng trong lập trình VBA, giúp phát triển Hàm tốt hơn rất nhiều so với Mảng động căn bản.
1. Cơ chế hoạt động của quy trình sử dụng WinAPI:
Sau khi hàm đã được gõ vào Ô trong bảng tính. Hàm bắt đầu khởi tạo và gán các đối số vào các biến cục bộ như Vùng chọn, giá trị, ... . Sau đó đặt một lệnh để WinAPI sẽ thực hiện, và Hàm WinAPI sẽ tự động gọi một hàm trung gian sau khi Hàm chính tính toán xong.
2. Ứng dụng: Viết các hàm tương đương với các Hàm mảng động Excel như UNIQUE , SORT, SORTBY, FILTER, SEQUENCE, RANDARRAY, SINGLE. Và viết đa dạng kiểu hàm mảng động tùy vào "sức mạnh và tư duy lập trình của các bạn".
3. Hướng dẫn: (*Sẽ cập nhật sau)
4. Ví dụ:
Copy Code dưới đây vào Module và thực hiện:
Gõ vào A1: =RandomNumbers(B1, 10, 5) (*Không cần đến tổ hợp phím để hoàn thành)
Gõ vào B1: một số ngẫu nhiên
JavaScript:
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As LongPtr, ByVal lpTimerFunc As LongPtr) As Long
Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
#Else
Private Declare Function SetTimer Lib "user32" (ByVal HWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal HWnd As Long, ByVal nIDEvent As Long) As Long
#End If
Private fRN_TimerID As Long, fRN_Number&, fRN_Row%, fRN_Column%, fRN_Range As Range
Function RandomNumbers(ByVal Number&, ByVal Row%, ByVal Column%)
RandomNumbers = "RandomNumbers:"
Set fRN_Range = Application.Caller
fRN_Number = Number: fRN_Row = Row: fRN_Column = Column
On Error Resume Next
If fRN_TimerID <> 0 Then KillTimer 0&, fRN_TimerID
fRN_TimerID = SetTimer(0&, 0&, 1, AddressOf printRandomNumbers)
End Function
Private Sub printRandomNumbers()
On Error Resume Next
KillTimer 0&, fRN_TimerID: fRN_TimerID = 0
If fRN_Number = 0 Or fRN_Row = 0 Or fRN_Column = 0 Or fRN_Range Is Nothing Then GoTo Ends
Dim SU As Boolean, AC As Long
SU = Application.ScreenUpdating
AC = Application.Calculation
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Dim Arr(), R%, C%
ReDim Arr(1 To fRN_Row, 1 To fRN_Column)
Randomize
For R = 1 To fRN_Row
For C = 1 To fRN_Column
Arr(R, C) = CLng((fRN_Number + 1) * Rnd + fRN_Number)
Next C
Next R
fRN_Range(2, 1).Resize(fRN_Row, fRN_Column).value = Arr
Application.ScreenUpdating = SU
Application.Calculation = AC
fRN_Number = 0: fRN_Row = 0: fRN_Column = 0
Ends: Set fRN_Range = Nothing
End Sub
Lần chỉnh sửa cuối: