为什么VBA函数为集合提供编译错误但不为字符串提供编译错误

时间:2019-06-07 21:38:24

标签: excel vba

我正在尝试将集合传递给VBA函数,但遇到了似乎无法修复的编译错误。

这是给出错误的简化示例。

Sub test()
    Dim fooString As String
    Dim fooCollection As collection
    Set fooCollection = New collection
    useString (fooString)
    useCollection (fooCollection)
End Sub

Public Function useString(foo As String)
    MsgBox ("here")
End Function

Public Function useCollection(foo As collection)
    MsgBox ("here")
End Function

我没有发现自己在做的事情与示例所显示的有所不同,例如以下示例:How do I sort a collection?

这是我遇到的错误(编译错误:参数不是可选的):

enter image description here

4 个答案:

答案 0 :(得分:5)

由于隐式的“有用”默认成员,您将收到此对话框。在“对象浏览器”中,导航到“类”窗格中的“集合”,在成员中,您将看到“项目”是默认成员,由深青色图标指定。

Default member of Collection class

这是另一个例子。问问自己它将打印什么,并在运行代码之前大声说出来。

Public Sub DontWrapIt()
    Dim foo As Range
    Set foo = Sheet1.Range("A1")
    GiveMeARange foo
    GiveMeARange (foo)
End Sub

Private Sub GiveMeARange(ByVal param As Variant)
    Debug.Print TypeName(param)
End Sub

用括号包装对象会导致对对象进行评估,这将导致对“有用的”默认成员的隐式调用...这需要未提供的Index参数-因此,“参数不是可选的”

答案 1 :(得分:1)

我不知道为什么会给出该特定错误(而不是信息量更大的错误),但是当您调用一个子程序或函数作为子程序(不使用返回值)时,您不应在括号内论据。以下作品:

Sub test()
    Dim fooString As String
    Dim fooCollection As collection
    Set fooCollection = New collection
    useString fooString
    useCollection fooCollection
End Sub

Public Function useString(foo As String)
    MsgBox "here"
End Function

Public Function useCollection(foo As collection)
    MsgBox "here"
End Function

但是-如果您的函数没有真正返回任何内容,则可以将它们定义为以subs开头的子函数。在VBA中,制作像C这样的语言中的void函数确实没有任何意义。

答案 2 :(得分:0)

只需调用另一个子即可。

如果没有任何参数,则只能按名称调用:

useCollectionCall useCollection

如果它确实有参数,则可以不带括号地调用它,或者使用Call

useCollection parameterCall useCollection(parameter)

Sub test()
    Dim fooString As String
    Dim fooCollection As Collection
    Set fooCollection = New Collection
    useString (fooString)

    fooCollection.Add "test message", "test"
    useCollection fooCollection
    Call useCollection(fooCollection)
End Sub

Public Function useString(foo As String)
    MsgBox ("here")
End Function

Public Function useCollection(foo As Collection)
    MsgBox foo(1)
End Function

查看有关Call statement的更多信息:

  

在调用过程时,不需要使用 Call 关键字。但是,如果使用 Call 关键字来调用需要参数的过程,则 argumentlist 必须括在括号中。如果省略 Call 关键字,则还必须省略 argumentlist 周围的括号。如果使用 Call 语法调用任何内部函数或用户定义的函数,则该函数的返回值将被丢弃

答案 3 :(得分:0)

这有效:

select formatpystring('{foo}.{bar}', '{"foo": "win", "bar": "amp"}');
 formatpystring 
----------------
 win.amp