VBA函数的可选参数

23

我需要多次调用特定的一段代码,因此我想要使用可选参数。 我可以写出如下代码:

Public Sub main()

strA = "A"

'Calling the function
CalculateMe (strA)

End Sub

Public Sub CalculateMe(strA As String)

    Set rs = DB.OpenRecordset("tbl_A")
    rs.MoveFirst
        Do Until rs.EOF
            If rs.Fields(0) = strA Then
                dblA = rs.fields(2).Value
            End If
            rs.MoveNext
        Loop
End Sub

我该如何更改函数以支持超过1个可选参数?

类似于:

Public Sub main()
strA = "A"
strB = "B"

'Calling the function
CalculateMe (strA, strB)

more code
End Sub

Public Sub CalculateMe(Optional strA As String, Optional strB as String)

    Set rs = DB.OpenRecordset("tbl_A")
    rs.MoveFirst
        Do Until rs.EOF
            If rs.Fields(0).Value = strA And rs.Fields(1).Value = strB Then
                dblA = rs.Fields(2).Value
            End If
            rs.MoveNext
        Loop
End Sub

在Pankaj Jaju的建议下,我成功地将其更改为以下内容:

Public Sub main()
strA = "A"
strB = "B"

'Calling the function
dblA = CalculateMe (strA, strB)

End Sub

Public Function CalculateMe(Optional ByVal strA As String, Optional ByVal strB as String)

Set rs = DB.OpenRecordset("tbl_A")
rs.MoveFirst
    Do Until rs.EOF
        If rs.Fields(0).Value = strA And rs.Fields(1).Value = strB Then
            dblA = rs.Fields(2).Value
        End If
        rs.MoveNext
    Loop
End Sub
现在,我该如何清除可选参数的值? 这对于某些计算很必要。类似这样的东西:
Set strA = Nothing

我知道这是一个老问题了,但你是想传递一个数组吗?然后循环遍历数组中的x个项目? - jcarroll
1
不,我没有;只有2个字符串变量。当时我对语法不熟悉,Pankaj Jaju帮助解决了这个问题。将函数更改为子程序并添加ByVal使得能够执行我想要做的事情。忽略任何其他帖子/评论;它们只会让人困惑。 - ProtoVB
4个回答

19

更改您的子程序并添加ByVal

Public Sub CalculateMe(Optional ByVal strA As String, Optional ByVal strB As String)

7
运行时,如何判断可选参数是否已经提供? - Throw Away Account
@ThrowawayAccount3Million - 当你调用 CalculateMe 函数时,你可以选择指定要传递的参数。例如,如果你只想使用 strB 参数,则调用 CalculateMe(,"second")。同样地,如果你只想使用第一个参数,则调用 CalculateMe("first")。如果你不想发送任何参数,只需调用 CalculateMe 即可。 - Pankaj Jaju
6
既然你忽略了他的问题,我会再问一遍 ;) 在运行时,你如何知道可选参数是否已被提供? - MushyPeas
1
@ThrowawayAccount3Million 使用此语句将比较您的参数与“Nothing”,并根据此执行操作:If TheParameter Is Nothing Then [statements...] 我对其进行了测试,并将TheParameter用作字符串...所以我猜它适用于任何类型的对象。 - Sreenikethan I
1
@ThrowawayAccount3Million,请参考以下来自Chip Pearson的答案。 - Christopher Peisert
@MushyPeas 请看下面从Chip Pearson摘录的答案。 - Christopher Peisert

12
Public Sub CalculateMe(Optional varA As Variant, Optional varB as Variant)

摘自Chip Pearson的优秀解释:

有关使用可选参数的规则:

  • 必须使用Optional关键字来使参数变为可选。
  • 数据类型应该是(但不一定是,参见下文)Variant数据类型。
  • 可选参数必须位于参数列表的末尾。
  • IsMissing函数只能用于声明为Variant的参数。如果与其他数据类型一起使用,它将返回False
  • 用户定义类型(UDT)不能作为可选参数。

示例

Function Test(L1 As Long, L2 As Long, _
    Optional P1 As Variant, Optional P2 As Variant) As String

    Dim S As String

    If IsMissing(P1) = True Then
        S = "P1 Is Missing."
    Else
        S = "P1 Is Present (P1 = " & CStr(P1) & ")"
    End If

    If IsMissing(P2) = True Then
        S = S & "  " & "P2 Is Missing"
    Else
        S = S & "  " & "P2 Is Present (P2 = " & CStr(P2) & ")"
    End If

    Test = S
End Function

这里需要L1和L2,但是P1和P2是可选的。由于两者都是Variant类型,我们可以使用IsMissing来确定参数是否已传入。如果省略了Variant参数,IsMissing将返回True,如果包含Variant参数,则返回False。如果可选参数的数据类型不是VariantIsMissing会返回False


4

Instead of CalculateMe(,strB) you can use

dblA = CalculateMe strB:="B"

这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Ankit Bajpai
3
@AnkitBajpai 再次说明,这确实是一个回答。 - Rob

0

我不确定你是否真的意思是“可选的”。在你的例子中,你将args列为可选项,但仍然将两个参数传递给函数。

无论如何,在这里你传递了两个参数:

Public Sub main()
strA = "A"
strB = "B"

'Calling the function
dblA = CalculateMe(strA, strB)

more code
End Sub

如果你只想传递其中一个参数,那么可以这样做:
dblA = CalculateMe(, strB)

或者:

dblA = CalculateMe(strA)

否则,如果您始终传递两个参数,则将它们设置为Optional就没有意义。

这是正确的,我正在传递机器人参数,但在另一个子例程中调用相同的函数时,我将其中一个参数(字符串变量)设置为= vbNullString。 - ProtoVB
为什么要这样做呢?你可以简单地传递一个空字符串:Calculate("", strB)等等...老实说,听起来你试图用一种过于花哨的方法来解决问题,而没有真正理解你在做什么。 - David Zemens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接