Bài viết: Tầm vực truy xuất, thời gian sống của biến & thủ tục

Liên hệ QC

TranThanhPhong

Ngày mai trời lại sáng!
Thành viên danh dự
Tham gia
16/3/07
Bài viết
2,104
Được thích
19,153
Giới tính
Nam
Một điều rất quan trọng khi làm việc với các biến là hiểu rõ về tầm vực (hay phạm vi hoạt động) của chúng. Tầm vực mô tả khả năng truy cập/ trông thấy hoặc thời gian sống của biến.

vba_var_scope_1.JPG

Tầm vực truy xuất biến

  • Tầm vực của một biến là tập các lệnh được phép truy xuất biến đó.
  • VBA cho phép 4 cấp độ tầm vực sau :

vba_var_scope_2.JPG



Cục bộ trong thủ tục (Procedure Scope): bất kỳ lệnh nào trong thủ tục đều có thể truy xuất được biến cục bộ trong thủ tục đó.
1. Biến này sử dụng từ khóa Dim hay Static khi khai báo biến trong thủ tục hay hàm.
2. Biến này chỉ truy cập được trong nội bộ thủ tục/ hàm.

Ví dụ: Tầm vực trong một Procedure, biến iCntr chỉ truy cập được trong nội bộ thủ tục.

Mã:
Sub sbScopeProcedureLevel() 
Dim iCntr As Integer 'Khai báo biến cục bộ thủ tục
iCntr = 2000
MsgBox "Biến cục bộ trong thủ tục iCntr = " & iCntr
End Sub

Cục bộ trong module (Module Scope): bất kỳ lệnh nào trong module đều có thể truy xuất được biến cục bộ trong module đó.
1. Biến này sử dụng từ khóa Dim hay Private khi khai báo biến nằm trước thủ tục đầu tiên trong module.
2. Biến này có thể được truy cập bởi mọi thủ tục có trong module.

Ví dụ: Tầm vực trong một Module, biến lRow có thể được truy cập bởi mọi thủ tục có trong module.

Mã:
Option explicit 
'Khai báo biến có tầm vực module
Dim lHang as long
Private lCot as long
lHang = 1000
lCot = 500
 
Sub sbprocedure1()
Msgbox "Biến có tầm vực module lHang = ” & lHang & " lCot = " & lCot
End sub
 
Sub sbprocedure2()
Msgbox "Biến có tầm vực module lHang = ” & lHang & " lCot = " & lCot
End sub

Toàn cục (Global Scope): bất kỳ lệnh nào trong chương trình cũng có thể truy xuất được biến toàn cục.
1. Biến này sử dụng từ khóa Public trước Dim khi khai báo biến nằm trước thủ tục đầu tiên trong một Public Module bất kỳ.
2. Biến này được truy cập bởi mọi thủ tục trong cùng module, khác module, form, class và cả trong workbook khác.
3. Nếu có nhiều biến cùng tên giữa các Project thì thêm tên Project trước tên biến khi truy xuất. Ví dụ như Project1.SomeVar

Mã:
'Trong Module 1 của ProjectA
Option Explicit
 
'Khai báo biến toàn cục trong Module1
Public lRow As Long
 
Sub sbProcedure1()
lRow = 220
MsgBox "Biến toàn cục lRow = " & lRow
End Sub
 
 
'Trong Module 2 của ProjectA
Sub sbProcedure2()
MsgBox "Gọi biến toàn cục trong Module1 từ Module2 lRow = " & lRow
End Sub
 
 
'Trong Module1 của ProjectB (Đã tham chiếu đến ProjectA trong Tools | References)
Sub sbProcedure3()
MsgBox "Gọi biến toàn cục trong Module1 của ProjectA từ Module1 của ProjectB lRow = " & ProjectA.lRow
End Sub

Tầm vực Project (Project Scope): Khi ta muốn biến được khai báo với từ khóa Public trong Public Module chỉ được truy cập trong nội bộ Project. Khi đó ta thêm vào cụm Option Private Module nằm trước thủ tục đầu tiên trong Module. Biến này được truy cập bởi mọi thủ tục trong cùng module, khác module, form, class trong cùng Project.

Mã:
'Trong Module1
Option Explicit
Option Private Module
Public lRow As Long  'Khai báo biến với từ khóa Public có tầm vực Project
 
Sub sbProcedure1()
lRow = 220
MsgBox "Bến có tầm vực Project lRow = " & lRow
End Sub
 
'Trong Module 2
Sub sbProcedure2()
MsgBox "Gọi biến tầm vực Project trong Module1 từ Module2 lRow = " & lRow
End Sub

Nếu bạn gọi biến lRow từ Project khác sẽ nhận được thông báo lỗi sau:

vba_var_scope_3.JPG


Trong một ngữ cảnh (cùng 1 thủ tục, cùng 1 module, hay cấp Project), không thể dùng hai biến cùng tên (VBA không phân biệt chữ HOA hay chữ thường).


Thời gian sống của biến


Biến là 1 thực thể nên cũng có thời gian sống hữu hạn, thời gian sống của biến thường phụ thuộc vào tầm vực của biến đó:

  • Biến cục bộ trong thủ tục: được tạo ra lúc thủ tục được gọi và mất đi khi thủ tục kết thúc việc xử lý và điều khiển được trả về lệnh gọi.
  • Biến cục bộ trong module: được tạo ra lúc module được tạo ra và mất đi khi module bị xóa.
- Các (standard) modules có thời gian sống từ lúc chương trình chạy cho đến khi chương trình kết thúc.
- Các đối tượng của class module hay form module được tạo ra khi có yêu cầu cụ thể. Tạo đối tượng nghĩa là tạo các thuộc tính của nó, các thuộc tính của đối tượng sẽ mất đi khi đối tượng bị xóa.

  • Biến toàn cục: được tạo ra lúc chương trình bắt đầu chạy và mất đi khi chương trình kết thúc.

Muốn kéo dài thời gian sống của 1 biến, ta thường dùng 2 cách sau:


  • Nâng cấp tầm vực: từ cục bộ trong thủ tục lên cục bộ trong module hay lên toàn cục... Cách này ít được dùng tường minh vì nó sẽ thay đổi tầm vực của biến. Để khắc phục điều này, VBA cung cấp khái niệm "Static" kết hợp với biến: biến có thuộc tính "Static" sẽ tồn tại mãi và chỉ mất đi khi chương trình kết thúc bất chấp tầm vực của nó ra sao.
  • Ghi giá trị biến ra môi trường chứa tin bền vững (file trên đĩa) trước khi biến bị xóa. Khi cần lại giá trị của biến này, ta đọc giá trị của nó từ file vào. Đây là phương pháp thông dụng để trao đổi dữ liệu giữa 2 ứng dụng khác nhau hay giữa 2 lần chạy khác nhau của cùng 1 ứng dụng.

Lưu ý về khai báo biến Static

Biến được khai báo ở cấp thủ tục và nó vẫn giữ lại giá trị của nó trong khi thủ tục đã kết thúc. Biến chỉ được giải phóng khi từ khóa End trong thủ tục được thực thi. Biến này chỉ thấy (truy xuất) được trong nội bộ thủ tục.

Ví dụ: Chạy thủ tục này 3 lần để xem biến Static được nạp, giữ lại và giải phóng.

Mã:
Sub MySub()     'Gia tri bien Static van khong mat sau khi chay thu tuc
    Static Counter As Integer
    Dim Msg As String
 
    Counter = Counter + 1
        Msg = "Day la lan chay thu tuc thu:  " & Counter
    MsgBox Msg
End Sub
 
 
Sub Start()     'Giai phong bien Static khi End thuc thi
    Static RunCount As Integer
    Static MyVariable As String
  
    RunCount = RunCount + 1
    If MyVariable = "" Then MyVariable = "Hello GPE lan "
   
    MsgBox "Tai lan chay " & RunCount & vbLf & "Bien Myvariable = " & MyVariable & RunCount, , Now()
   
    If RunCount = 2 Then
        MsgBox "Cac bien Static MyVariable va Runcount se duoc giai phong."
        End
    End If
End Sub


Tầm vực thủ tục/ hàm

Giống như biến, thủ tục cũng có tầm vực của chúng. Có hai loại tầm vực của thủ tục đó là Public Private.

Thủ tục có từ khóa Public có thể được truy cập từ tất cả các thủ tục khác trong Project và cả Project khác. Excel mặc định thủ tục là Public do vậy bạn có thể không khai báo từ khóa này trước tên thủ tục. Hai cách khai báo thủ tục sau là như nhau:

Mã:
Public Sub XinChao()
    Debug.Print "Xin chao"
End Sub
 
Sub TheProcName()
    Debug.Print "Xin chao"
End Sub

Thủ tục có từ khóa Private chỉ có thể truy cập được từ các thủ tục khác trong cùng module.

Mã:
Private Sub TheSub()
    Debug.Print "GPE xin chao!"
End Sub
Cũng giống như biến, muốn thủ tục Public chỉ được truy cập trong nội bộ Project thì ta đặt từ khóa Option Private Module vào trước thủ tục đầu tiên trong module. Khi đó các thủ tục trong module này sẽ chỉ được truy xuất trong nội bộ của Project.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Web KT
Back
Top Bottom