Hôm nay phải viết một cái Macro để copy dữ liệu từ file excel này sang file khác. Dạo gần đây hầu như chỉ đụng tới PHP, C hay Perl, những cái này đại khái có chung ngữ pháp cơ bản nên hôm nay đụng lại VBA thấy quên khá nhiều. Dưới đây là một vài ghi chú về array trong VBA, viết ra để hy vọng sau này không nhầm nữa. ### Cách khai báo Array (static) ```VBA ' 1. Cách đầy đủ Dim arr(0 to 3) as Type ' 2. Cách rút gọn Dim arr(3) as Type ' Type là một trong những kiểu dữ liệu của VBA ``` ### Cách VBA quản lý khai báo Array Không giống như các ngôn ngữ khác, thường quản lý khai báo Array bằng cách khai báo số phần tử có trong đó; VBA chơi theo cách của riêng mình, quản lý bằng cách khai báo _cận dưới (số index nhỏ nhất)_ và _cận trên (số index lớn nhất)_ của Array. Dựa vào cận trên và cận dưới này, VBA sẽ tính số phần tử có trong Array và tự động đánh index (bước nhảy 1) cho các phần tử trong đó. Trong VBA không thể khai báo Array với các phần tử có index không liên tục. Trong ví dụ 1 ở trên, ta sẽ có được 1 array gồm 4 phần tử được đánh index từ 0 -> 3. Trong ví dụ 2 ở trên, ta đã lược bỏ đi cận dưới, chỉ quy định cận trên. _Nếu trong trường hợp thông thường_, ta cũng sẽ được 1 array gồm 4 phần tử được đánh index từ 0 -> 3. Tại sao ở đây lại có thêm vế _"nếu trong trường hợp thông thường"_ thì sẽ giải thích ở bên dưới. ### Câu lệnh "Option Base" sẽ làm thay đổi cách hiểu cận dưới mặc định của VBA Khi khai báo Array mà không quy định cận dưới, tức là ta đã phó mặc việc hiểu cận dưới cho VBA. VBA có 2 cách hiểu cận dưới của một Array (được khai báo theo kiểu rút gọn) đó là 0 hoặc 1, và mặc định nếu không có quy định gì là 0 (giống như các ngôn ngữ khác). Khi muốn thay đổi cách VBA hiểu cận dưới, ta sẽ sử dụng câu lệnh "Option Base" (cái này viết ra để ghi nhớ thôi, chớ chắc chẳng khi nào phải dùng tới). * `Option Base` nhận 1 trong 2 giá trị là 0 hoặc 1, mặc định là 0. * Nếu quy định giá trị `Option Base` là 0, thì mỗi khi khai báo Array theo kiểu rút gọn, VBA sẽ tự động hiểu Array đó có cận dưới là 0, và ngược lại là 1. * `Option Base` chỉ ảnh hưởng trong nội bộ Module mà nó được khai báo. * `Option Base` không ảnh hưởng đến cách đánh index của hàm `Array()`. Dù khai báo `Option Base 1` thì hàm `Array()` vẫn bắt đầu đánh index từ 0. (Mặc dù hàm `Array()` chỉ dùng được với biến kiểu **Variant**, không dùng được cho array thuần túy nhưng ghi vào để nhớ.) Ví dụ minh họa về "Option Base": ```VBA '------------------------ ' Trường hợp không khai báo Option Base hoặc Option Base 0 '------------------------ Option Base 0 Sub testArray() Dim array(2) as integer Debug.print(LBound(array)) ' Sẽ cho kết quả là 0 Debug.print(UBound(array)) ' Sẽ cho kết quả là 2 ' => Số phần tử của array: ' UBound(array) - LBound(array) + 1 = 3 End Sub ``` ```VBA '------------------------ ' Trường hợp Option Base 1 '------------------------ Option Base 1 Sub testArray() Dim array(2) as integer Debug.print(LBound(array)) ' Sẽ cho kết quả là 1 Debug.print(UBound(array)) ' Sẽ cho kết quả là 2 ' => Số phần tử của array: ' UBound(array) - LBound(array) + 1 = 2 End Sub ``` ### Tóm lại * Khi khai báo một Array trong VBA, không nên lười khai báo theo kiểu rút gọn mà nên dùng cách đầy đủ để tránh nhầm lần. * Cách tốt nhất khi muốn duyệt qua toàn bộ phần tử trong Array hay tìm số phần tử của Array là sử dụng đồng thời cận trên và cận dưới của nó. Ví dụ: ```VBA Sub testArray() Dim arr(0 to 3) as integer Dim i as integer, num as integer ' Duyệt toàn bộ phần tử For i=LBound(arr) to UBound(arr) ' Các lệnh khác Next i ' Tìm số phần tử num = UBound(arr) - LBound(arr) + 1 End Sub ``` * Có thể dùng kiểu biến **Variant** thay cho **Array thuần túy** khi muốn viết những code đơn giản, giảm bớt rắc rối của Array.