Đối số có thể giản lược trong thủ tục và hàm VBA

tuhocvba

Administrator
Thành viên BQT
Chào các bạn. Hôm nay tôi sẽ giới thiệu cho các bạn cách khai báo một đối số giản lược trong thủ tục và hàm của VBA.
Mã:
Sub TenThuTuc(Optional DoiSo As String = "GiaTriMacDinh")

End Sub
Nếu bạn không chỉ định giá trị mặc định cho đối số, thì giá trị khởi tạo ban đầu sẽ phụ thuộc vào kiểu dữ liệu của biến số đó.
Mã:
Sub TenThuTuc(Optional DoiSo As String)

End Sub
Chúng ta có thể khai báo các đối số optional ở phía cuối.
Mã:
Sub TenThuTuc(DoiSo1 As Integer, Optional DoiSo2 As Integer = 2)

End Sub

Sub TenThuTuc(DoiSo1 As Integer, Optional DoiSo2 As Integer = 2, Optional DoiSo3 As Integer = 3)

End Sub

Nếu như bạn khai báo đối số Optional lên trên đầu thì không được. Ví dụ lỗi:

Mã:
' Không khai báo được như thế này nhé
Sub TenThuTuc(Optional DoiSo1 As Integer = 1, DoiSo2 As Integer)

End Sub
Bạn có thể sử dụng ByVal , ByRef . Nhưng không thể sử dụng ParamArray .
Ví dụ:
Mã:
Sub TenThuTuc(Optional ByVal DoiSo1 As Integer = 1, Optional ByRef DoiSo2 As Integer = 2)

End Sub

' Không được khai báo như thế này nhé
Sub TenThuTuc(Optional ParamArray DoiSo1() As Variant)

End Sub
Ví dụ minh họa cho các bạn dễ hiểu:
Mã:
Sub THVBA()
    Dim BienSo As Integer
    BienSo = 2

    Call vidu        ' 1 Khi gian luoc thi gia tri mac dinh la 1
    Call vidu(BienSo)  '2 Khi truyen gia tri thi gia tri bay gio la 2
End Sub

' Thu tuc con
Sub vidu(Optional DoiSo As Integer = 1)
    Debug.Print(DoiSo)
End Sub
Nguồn tham khảo:
 
T

thanhphong

Guest
Để làm rõ giá trị của đối số khi chúng bị giản lược, ta xem xét tiếp ví dụ sau:
Mã:
Sub ThucThi()
    Call Vidu("Truoc")         ' Truoc23
    Call Vidu(, "Giua")       ' 1Giua3
    Call Vidu(, , "Sau")     ' 12Sau
    Call Vidu("Truoc", , "Sau") ' Truoc2Sau
End Sub
      
' Thu tuc con
Sub Vidu(Optional DoiSo1 As String = "1", Optional DoiSo2 As String = "2", Optional DoiSo3 As String = "3")
    Debug.Print(DoiSo1 & DoiSo2 & DoiSo3)
End Sub
Cách viết trên khiến chúng ta thấy nó chưa dễ hiểu.
Tiếp theo, ta hãy xem cách truyền đạt giá trị thông qua chỉ định tên:
Tên_Đối_Số:=Giá_Trị
Mã:
Sub ThucThi()
    Call ViDu(DoiSo1:="Truoc")              ' Truoc23
    Call ViDu(DoiSo3:="Sau", DoiSo2:="Giua") ' 1GiuaSau
    Call ViDu("Truoc", DoiSo3:="Sau")        ' Truoc2Sau
End Sub

'Thu tuc con
Sub ViDu(Optional DoiSo1 As String = "1", Optional DoiSo2 As String = "2", Optional DoiSo3 As String = "3")
    Debug.Print(DoiSo1 & DoiSo2 & DoiSo3)
End Sub
Xin chú ý, khi chỉ định tên, thì khi truyền giá trị cho các đối số đều phải theo cách này. Ví dụ dưới đây là ví dụ lỗi:
Mã:
Sub ThucThi()
    Call ViDu(DoiSo1:=1, 2)        ' Loi xay ra、DoiSo2 cung can chi dinh bang ten
    Call ViDu(DoiSo2:=2, 1)        ' Loi xay ra、DoiSo1 cung can chi dinh bang ten
    Call ViDu(DoiSo1:=1, DoiSo2:=2) ' OK
End Sub

' thu tuc con
Sub ViDu(DoiSo1 As String,  DoiSo2 As String)
End Sub
Cách viết sau thì đúng (trường hợp 1), bởi vì đối số phía sau có thể giản lược, và trường hợp 2 thì sai:
Mã:
Sub ThucThi()
    Call ViDu(DoiSo1:=1)    ' OK, doi so thu 2 co the gian luoc
    Call ViDu(DoiSo1:=1, 2) ' Loi xay ra , doi so thu 2 phai chi dinh bang ten
End Sub

' thu tuc con
Sub ViDu(DoiSo1 As String, Optional DoiSo2 As String = "2")
    
End Sub
Lý do chỉ định tên:
Hãy xem ví dụ dưới đây:
Mã:
Sub ThucThi()
    Call ViDu(, , , , 5, , , , ,10) ' Co biet bao nhieu la DoiSo, cach viet nay that su kho hieu
    Call ViDu(DoiSo5:=5, DoiSo10:=10)  ' Khi viet bang ten DoiSo, that de hieu
End Sub
Khi sử dụng biến logic, cũng nên viết theo cách chỉ định tên:
Mã:
Sub ThucThi()
    Call Vidu(True)        ' Cai gi la True, that kho hieu
    Call Vidu(ChoPhep:=True)  ' That de hieu phai khong nao
End Sub
Nguồn tham khảo:
 
Top