... nhưng mà mình đi dạy nên phải phòng các trường hợp người ta có thể hỏi mình bất cứ thứ gì, nên phải phòng trước ...
Nếu tôi đi dạy thì tôi chỉ cho học sinh căn bản cách sử dụng bảng để thành lập bảng tính thôi. Tất cả những gì còn lại người ta sẽ từ kinh nghiệm mà suy ra. Một khi có căn bản về cơ cấu bảng tính thì nghiệm cái gì cũng dễ.
Để trả lời việc gán trị cho mảng thì lý thuyết như sau:
Như tôi đã có trình bày trong một thớt nọ (quên mất rồi, tự tìm lấy), người ta cũng dịch một range là mảng cho nên đôi khi gây ra sự lầm lẫn.
Trong Excel VBA, cái application là một object, object này có một collection là workbooks, mỗi workbook trong collection trên thì lại có collection worksheets. Mỗi worksheet là một object item (phần tử) của collection worksheets. Object worksheet có nhiều thuộc tính (tôi thỉnh thoảng quen gọi theo ngôn ngữ tổng quát là hàm). Trong những thuộc tính đó có thuộc tính Range. Vì range là đối tượng của một class cho nên chính nó cũng có nhiều thuộc tính và phương thức. Một trong những tính chất này là phép ngầm chuyển từ giá trị của range sang mảng và ngược lại (bạn nói mình đã học qua C++, thì có thể tạm coi như range có phép viết hàm chồng phép gán, toán tử =).
Lợi dụng tính chất này, VBA có thể sử dụng range theo nhiều cách khác nhau. Điển hình là 2 cách rất phổ biến trên diễn đàn này:
1. chuyển dữ liệu từ một range sang array và ngược lại. vd arr = Range("a1:b2")
2. Điển hình thứ hai là cách viết tắt hàm Evaluate của worksheet, tức là dấu []. vd [a1:b2]
Tất cả phần trên, bạn đã biết rồi. Còn phần nữa bạn cũng biết sử dụng nhưng không rõ cơ cấu lý thuyết của nó (lưu ý từ "cơ cấu", đó là tại sao tôi nói bạn hiểu cơ cấu thì học rất dễ): trong workbook/worksheet có cái gọi là range ảo, tức là một object range được excel tạo ra trong bộ nhớ. Và vì là ảo cho nên nó thiếu nhiều thuộc tính của range thường (ví dụ offset, address,...). Trên worksheet, bạn dùng ký tự {} để tạo ra cái range này. Đó là cái mà bạn gọi là mảng. { 1, 2, 3, 4 } tương đương với một mảng 4 phần tử. Vì là range cho nên tối đa nó chỉ có tới 2 chiều.
Lợi dụng tính chất range ảo này. Và lợi dụng cách viết tắt của hàm Evaluate, và lợi dụng đặc tính phép gán của range. Ta có thể tạo một mảng và đặt trị khởi đầu của nó như sau:
arr = [ { 1, 2, 3, 4 } ] ==> Dùng hàm evaluate của worksheet, tạo một range ảo với 4 cells 1,2,3,4, copy trị vào arr.
Như vậy, bạn cũng có thể dùng những tính chất này để gán cho mảng 2 chiều. Nhưng lưu ý:
Vì là range cho nên nó chỉ cho phép bạn tối đa 2 chiều. Và vì là phép ép range cho nên mảng được gán có chỉ số đầu tiên là 1.
Phép gán qua range như trên chỉ áp dụng được cho trị hằng, bởi vì range ảo của Excel chỉ có thể dùng trị hằng. Nếu một trong những trị cần gán là biến thì bắt buộc phải dùng hàm Array để gán. Hàm Array nhận tham là mảng tham cho nên chỉ gán được mảng 1 chiều.
Bạn có thể dùng
arr = Array( Array( 1, 2), Array( 3, 4) )
Nhưng kết quả vẫn là mảng 1 chiều, mỗi phần tử của nó là một mảng. Tức là bạn cóp thể dùng arr(1)(1), chứ không thể dùng arr(1,1).
Chú thích:
Việc bạn nói về định nghĩa mảng như thế nào cho đúng lại là việc khác, nếu rảnh tôi sẽ viết trong bài khác. Lưu ý là nếu viết, tôi cũng sẽ thêm ý kiến chứ không bài bác cách định nghĩa của người khác.
Thuộc tính keys của object dictionary lại là một việc khác nữa. Nếu tôi rảnh, tôi sẽ bàn trong bài khác.