Xin bạn cho nhận xét hay khác biệt, nếu không xài như bạn nêu mà vầy:
...
Đầu tiên, hai hàm ấy hoàn toàn độc lập nhau. A gọi B không có nghĩa là B phải biết A. Những gì A muốn B biết thì phải truyền qua tham số. Không có tham số thì bắt buộc các liên lạc phải qua biến toàn cục. Tôi nghĩ là bạn có khai biến toàn cục, nhưng cái bạn đưa lên không thấy phần ấy. Biến toàn cục có cái bất lợi của chúng. Điển hình là chúng làm giảm tính chất độc lập của hàm. Hai hàm A và B phải biết chính xác những gì tồn tại trong biến toàn cục. Điển hình là trường hợp code của bạn, A khi gọi B lần thứ nhất đã dựa vào thực tế rằng các biến toàn cục mang trị khởi đầu mặc định từ VBA; lần thứ hai thì A đã dựa vào thực tế rằng B đã được gọi 1 lần trước đó, các biến toàn cục tiếp tục mang trị mà chúng đã mang khi B kết thúc lần thứ nhất.
Bỏ qua phần ấy, hãy để ý rằng: A thay vì gọi B có thể gọi hàm khác thay thế, B chả sao cả nếu không được A gọi.
Mặt khác, A có thể bảo vệ biến của mình bằng cách chỉ truyền qua value.
Chính bản thân tôi cũng không thích lênh SoSub. Nhưng có một số người, nhất là dân viết Basic từ thế kỷ trước, vì các lý do sau đây:
- Khỏi phải khai báo lại thành biến toàn cục
- Sub dạng GoSub không phải là độc lập. Đấy là hàm nội của hàm chính. Tất cả tài nguyên (biến/hằng các hàm nội khác) đều được hàm nội này biết và toàn quyền sử dụng. Với hàm độc lập, gặp parameter list dài một chút thì truyền hơi mệt. Mà module chứa một đống biến toàn cục cũng hơi gay. Bởi hàm có thể khai báo biến nội che qua biến toàn cục cho nên hơi khó đọc code (*1). Trong trường hợp này, hàm nội giải quyết vấn đề code được lặp đi lặp lại nhiều lần một cách hiệu quả mà không cần tới vòng lặp.
- Code của hàm chính tự do chạy qua hàm nội nếu không có gì cản trở. Vì vậy, câu lệnh Exit Sub khi hết code hàm chính là tối quan trọng. Không có câu lệnh này, code sẽ chạy vào hàm nội và đưa đến run time error khi thấy lệnh Return.
- Vì Sub dạng GoSub không hoàn toàn độc lập cho nên lúc gọi VBA chỉ phải save địa chỉ lệnh gọi vào ngăn xếp và 'pop' ra lúc gặp lệnh Return. Khác với hàm đọc lập, VBA phải save một đống khác vào ngăn xếp. Vì vậy SoSub có khả năng nhanh hơn hàm độc lập.
- Ngày xưa, bộ nhớ không nhiều cho nên hầu hết các chương trình được viết dùng hàm nội. Đó là lý do tại sao các tay viết Basic thế kỷ trước thich viết kiểu này.
(*1) Có biến trùng tên với biến toàn cục được khai báo lại là biến nội thì VBA sẽ mặc định là hàm sử dụng biến nội.
Muốn VBA biết rằng hàm muốn dùng biến toàn cục thì thêm tiền tố là tên module nó được khai báo. Theo VBA thì biến/hằng toàn cục là properties của Module; biến/hằng khai báo trong sub/function là properties của sub/function.
Chạy thử code sau đây sẽ rõ:
Dim a
Sub tt()
Dim a
a = 10
Module1.a = 1
Debug.Print a, Module1.a
End Sub
Xin lỗi các bạn khác:
Cách hoạt động của compiler và tầm vực của biến là nơi mà tôi tự hào rằng kiến thức của mình không thua bất cứ người nào ở diễn đàn này.
Vì vậy gặp dịp thì hơi ngứa mồm một chút. Thôi thì cứ coi như ở điểm này tôi quá tự phụ đi.