@chủ thớt: những điều tôi nói sau đây chỉ chuyên về lý thuyết, giành cho các bạn đã có kinh nghiệm nhiều về VBA. Như bạn tự nhận mình "mới học mẫu giáo về môn VBA này" thì không cần đọc tiếp. Bạn nên tìm các bài nói về biến và tầm vực biến mà đọc. Ở dễn đàn có mấy bài nói của các tay kỳ cựu giải thích rất rõ từ nhập môn tới nâng cao (không phải của tôi, vì tôi chỉ chuyên về ý thuyết).
Khi nào bạn chèn 1 module mới mà bạn thấy có dòng Option Explicit viết sẵn ngay đầu code như vầy:
...
thì bắt buộc ban phải đặt biết (nếu có dùng tới). Nếu không nó sẽ báo lỗi
Ngược lại hổng thấy dòng đó thì đặt hay không cũng không việc gì xảy ra
Hiểu nôm na như thế này: Biến (variable) là một tên gọi đi kèm theo sau nó là 1 kiểu dữ liệu (Data Type) để máy tính lưu trữ tạm thời trong bộ nhớ khi sử dụng trong một thủ tục.
Bạn nên hiểu các kiểu dữ liệu (Data Type) gồm: Boolean, Integer, Long, Double, Currency, Date, String để dùng khi cần trong khai báo biến.
Trong hộp thoại Options nếu bạn đánh dấu vào Require variable Declaration (Yêu cầu Tuyên bố biến), nếu bạn sử dụng một biến trong một thủ tục mà không khai báo sẽ phát sinh lỗi.
Tôi xin giải thích trên quan điểm
lý thuyết về cách làm việc cùa trình dịch VBA, vấn đề "
lúc nào thì phải khai báo biến" và "
khai báo như thế nào"
Option Explicit có tác dụng trong module. Nó bắt buộc các biến trong module phải được khai báo rõ rệt chứ không được mặc định. Mặc định là như thế nào thì xem bên dưới.
Options - Require Variable Declaration cũng giống như Option Explicit, nhưng có tác dụng cả project. Nói cách khác, ta có thể Option Explicit cho module1 và khong bắt buộc cho module2. Nhưng nếu "Options - Require Variable Declaration" thì mặc nhiên tất cả module đều coi như có "Option Explicit"
Biến mặc định như thế nào?
Các chỗ (1),(2),(3) là chỗ cần xem chú thích thuật ngữ.
Đầu tiên hết, định nghĩa tầm vực của biến gồm có:
Biến khai báo bên trong sub/function là biến nội bộ, chỉ hiện hữu trong sub/function đó và khi end/exit sub/fucntion nó sẽ được tiêu huỷ. Điều ngoại lệ là biến nọi bộ được khai báo với từ khoá Static, khi end/exit sub/function chúng khong bị tiêu huỷ; giá trị vẫn giữ để làm việc nếu sub/function được gọi lại.
Biến được khai báo trong code module, nhưng bên ngoài sub/function là biến toàn cục, hiện hữu trong suốt chương trình chạy. (1)
Biến được khai báo trong class module là biến thuộc về class. Muốn động đến chúng thì phải đi qua đối tượng của class. Cái này không thể bàn nhiều ở đây vì chúng thuộc về hướng đối tượng.
Cách VBA nhận dạng biến:
Khi VBA biên dịch đến đoạn thấy tên biến thì nó tìm về bảng địa chỉ. Nếu biến đã có ghi trong bảng địa chỉ của biến nội bộ, tức là đã được cấp phát vùng nhớ (2) rồi thì VBA cứ việc dùng vùng nhớ ấy.
Nếu biến không có sẵn trong bảng biến nội bộ thì VBA tìm qua bảng biến toàn cục. Nếu tìm được thì nó sử dụng luôn.
Nếu biến không tìm được trong bảng biến toàn cục. Vì lý do không hề được khai báo, hoặc được khai báo trong module khác dưới dạng private (3) thì VBA sẽ làm như sau:
- Nếu project hoặc module có điều kiện "bắt buộc khai báo trước" thì VBA sẽ báo lỗi "biến chưa được khai báo" (hay đại khái thế).
- Nếu khong có điều kiện "bắt buộc khai báo trước" thì VBA liệt biến vào trường hợp mặc định, và tự động khai báo ngay tại chỗ đó. Và đương nhiên vì khai báo tại chỗ cho nên biến là một biến nôi bộ, và kể từ sau đó, tên này coi như đã được khai báo rồi.
(1) bộ nhớ trong chương trình chia ra làm 2 phần, phần vùng nhớ chung (heap) dùng chung cho cả project, và vùng nhớ ngăn xếp (stack) dùng riêng bên trong hàm/sub
(2) lưu ý: vùng nhớ không nhất thiết phải trực tiếp chứa dữ liệu. Chỉ những loại biến đơn giản mới chứa dữ liệu trực tiếp. Các loại phức tạp thì vùng nhớ chỉ là con trỏ tới vùng dữ liệu thực thụ.
(3) các biến toàn cục được khai báo dưới điều kiện private thì chúng cũng nằm trong danh sách bảng biến toàn cục, nhưng chúng chỉ cho phép những sub/function trong cùng module sử dụng mà thôi. Nói theo tiếng chuyên môn là chúng được module che lại, các module khác không động đến được.
Chú thích: ở đây tôi chỉ nói về khai báo tên biến, tức là ghi danh/điểm danh thôi. Việc khai báo kiểu biến thì cũng có lý thuyết riêng, bàn ở đây dài quá.