Làm cách nào để kiểm tra xem các đối số tùy chọn có được cung cấp hay không?


77

Làm cách nào để kiểm tra xem các đối số tùy chọn có được cung cấp hay không? - trong VB6 / VBA

Function func (Optional ByRef arg As Variant = Nothing)

    If arg Is Nothing Then   <----- run-time error 424 "object required"
        MsgBox "NOT SENT"
    End If

End Function 

Câu trả lời:


98

Sử dụng IsMissing:

If IsMissing(arg) Then
    MsgBox "Parameter arg not passed"
End If

Tuy nhiên, nếu tôi nhớ không nhầm thì điều này không hoạt động khi đưa ra giá trị mặc định cho đối số và trong mọi trường hợp, nó làm cho việc sử dụng đối số mặc định trở nên thừa.


29
Ngoài ra tôi nghĩ IsMissing chỉ hoạt động nếu đối số được khai báo là một biến thể
Jon Fournier

5
@Jon: true, vì IsMissingđược triển khai dưới dạng cờ trong VARIANTcấu trúc (IIRC, VT_EMPTY). Tôi đã không đề cập đến điều này vì câu hỏi của OP đã được sử dụng Variant.
Konrad Rudolph

22

Bạn có thể sử dụng Hàm IsMissing (). Nhưng cái này chỉ hoạt động với kiểu dữ liệu Biến thể.

Sub func(Optional s As Variant)
   If IsMissing(s) Then
      ' ...
   End If
End Sub

10

Nếu bạn đang sử dụng biến chuỗi hoặc số, bạn có thể kiểm tra giá trị của biến. Ví dụ:

Function func (Optional Str as String, Optional Num as Integer)

If Str = "" Then
    MsgBox "NOT SENT"
End If

If Num = 0 Then
    MsgBox "NOT SENT"
End If

End Function

Điều này cho phép bạn sử dụng các biến không phải là biến thể.


2
Tuy nhiên, nó không thể phân biệt cách sử dụng hoàn toàn hợp lệ: func("", 0)sẽ gắn cờ sai các thông số chưa được đặt. Nói chung không có cách nào để có sự phân biệt này mà không sử dụng Variants.
Konrad Rudolph

@KonradRudolph Đó là một điểm rất tốt. Bạn muốn đảm bảo rằng bạn chưa bao giờ sử dụng nó trong trường hợp bạn có thể gửi một chuỗi rỗng hoặc một số 0.
OSUZorba


3

Bạn có thể sử dụng một cái gì đó như:

function func(optional vNum as integer:=&HFFFF) '&HFFFF value that is NEVER set on vNum

If vNum = &HFFFF Then
    MsgBox "NOT SENT"
End If

End Function

1

Với một biến thể, tôi sẽ sử dụng hàm NZ :

Function func (Optional ByRef arg As Variant = Nothing)
    If nz ( arg, 0 ) = 0 Then
        MsgBox "NOT SENT"
    End If
End Function 

Nó cũng có thể được sử dụng với các kiểu dữ liệu khác, chỉ cần lưu ý rằng Zero không được tính là Null hoặc Zero-Length, vì vậy nz(0,"")vẫn trả về 0.


1

Hầu hết chúng đề cập đến loại biến thể hoặc kiểm tra xem một giá trị có trống không.

Tuy nhiên, đôi khi bạn muốn kiểm tra xem một phạm vi, sổ làm việc, trang tính hoặc loại đối tượng khác có được chuyển hay không mà không cần kiểm tra những thứ như tên trang tính.

Trong trường hợp đó:

DesiredRange is Nothing

Trả về một boolean. Ví dụ:

    If DestinationRange Is Nothing Then
        MsgBox "Need a destination range when importing data"
    Else
        'We're happy
    End If

1
Phần khó khăn là không phải mọi loại đối tượng đều có thể được kiểm tra bằng cách sử dụng is Nothingtrong khi bất kỳ đối tượng nào cũng có thể được lưu trữ trong một Variantloại. Vì vậy, để được rõ ràng, đây một giải pháp cho các đối tượng như Ranges hoặc Worksheets nhưng không phải với nhiều loại khác nhưString
Marcucciboy2

-1

"IsMissing" ... Được biết sẽ phải có một cách. Cảm ơn tất cả!

SQL có một hàm, In (), nơi bạn có thể truyền nhiều đối số để xem liệu giá trị đích có trong danh sách hay không. Tôi luôn thích đó là một giải pháp, vì vậy đây là lý do của tôi, hy vọng nó sẽ giúp:

Public Function IsIn(ByVal TestVal, ByVal VersusVal1, _
            Optional ByVal VersusVal2, Optional ByVal VersusVal3, _
            Optional ByVal VersusVal4, Optional ByVal VersusVal5, _
            Optional ByVal VersusVal6, Optional ByVal VersusVal7, _
            Optional ByVal VersusVal8, Optional ByVal VersusVal9, _
            Optional ByVal VersusVal10, Optional ByVal VersusVal11, _
            Optional ByVal VersusVal12, Optional ByVal VersusVal13, _
            Optional ByVal VersusVal14, Optional ByVal VersusVal15, _
            Optional ByVal VersusVal16, Optional ByVal VersusVal17, _
            Optional ByVal VersusVal18, Optional ByVal VersusVal19, _
            Optional ByVal VersusVal20) As Boolean

Dim CheckVals(1 To 20) as Variant
VersusVals(1) = VersusVal1
VersusVals(2) = VersusVal2
VersusVals(3) = VersusVal3
VersusVals(4) = VersusVal4
VersusVals(5) = VersusVal5
VersusVals(6) = VersusVal6
VersusVals(7) = VersusVal7
VersusVals(8) = VersusVal8
VersusVals(9) = VersusVal9
VersusVals(10) = VersusVal10
VersusVals(11) = VersusVal11
VersusVals(12) = VersusVal12
VersusVals(13) = VersusVal13
VersusVals(14) = VersusVal14
VersusVals(15) = VersusVal15
VersusVals(16) = VersusVal16
VersusVals(17) = VersusVal17
VersusVals(18) = VersusVal18
VersusVals(19) = VersusVal19
VersusVals(20) = VersusVal20

On Error Goto 0

IsIn = False

For x = 1 To 20
   If Not IsMissing(VersusVals(x)) Then
      If TestVal = VersusVals(x) Then
         IsIn = True
         Exit For
      End If
   End If
Next x

End Function

Vì vậy, đó rõ ràng là lý do tại sao tôi cần "IsMissing"; không hoạt động nếu không có nó.


4
Thực ra bạn không cần và không nên sử dụng IsMissingở đây. Thay vào đó, đây là một ứng dụng cho một ParamArray.
Konrad Rudolph
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.