使用VB / VBA中的“CallByName”调用模块中包含的Sub或Function

时间:2010-04-22 23:21:17

标签: vba

使用CallByName调用classModule中的函数很容易 标准模块内部的功能怎么样?

''#inside class module
''#classModule name: clsExample
  Function classFunc1()
     MsgBox "I'm class module 1"
  End Function
''# 
''#inside standard module
''#Module name: module1
  Function Func1()
     MsgBox "I'm standard module 1"
  End Function
''#
''# The main sub
Sub Main()
''# to call function inside class module
dim clsObj as New clsExample
Call CallByName(clsObj,"ClassFunc1")

''# here's the question... how to call a function inside a standard module
''# how to declare the object "stdObj" in reference to module1?
Call CallByName(stdObj,"Func1") ''# is this correct?

End Sub

5 个答案:

答案 0 :(得分:4)

我认为jtolle的回答最好地解决了这个问题 - 对Application.Run的小参考可能就是答案。提问者不想简单地使用func1或Module1.func1 - 首先想要使用CallByName的原因是在编译时不知道所需的function.sub名称。在这种情况下,Application.Run确实有效,例如:

Dim ModuleName As String
Dim FuncName As String
Module1Name = "Module1"
FuncName = "func1"
Application.Run ModuleName & "." & FuncName

您还可以在ModuleName之前添加项目名称,并添加另一个句点“。”。 不幸的是,Application.Run不会返回任何值,因此当您可以调用函数时,您将无法获得其返回值。

答案 1 :(得分:2)

CallByName仅适用于类对象。

如果您的子程序在标准模块中,您可以这样做:

Sub Main()
    Module1.Func1
End Sub

如果它是一个函数,那么你可能想要捕获返回值;像这样的东西:

Sub Main()
    Dim var
    var = Module1.Func1
End Sub

答案 2 :(得分:1)

VB6和VBA中的模块类似于静态类,但遗憾的是VB不接受Module1作为对象。您可以像C.Func1一样编写Module1.Func1(C是某些Class1的实例),但这显然是由编译器完成的,而不是在运行时。

想法:将Module1转换为类,在启动模块中创建“Public Module1 as Module1”,在“Sub Main”中创建“Set Module1 = New Module1”。

答案 3 :(得分:1)

尽管这是一个古老的问题,OP在标准模块中要求提供CallByName,但正确的建议却分散在答案和评论中,至少在2020年,这样的建议可能不够准确。 正如SlowLearner所说,Application.run确实会返回Variant,这样,除了处理错误外,下面的两个分支都是等效的,正如围绕Horowitz的答案所述:

Dim LoadEnumAndDataFrom as Variant
'FunctionName returns a Variant Array
if fCallByName then
    LoadEnumAndDataFrom = CallByName(ClassObj, "FunctionNameAtClass", VbMethod)
else
    'After moving back function for a standard module
    LoadEnumAndDataFrom = Application.Run("StandardModuleName" & "." & "FunctionNameAtStandard")
endif

我实际上只是在上面这样做,并且完全没有错误,在Word,Excel和Access中进行了测试,并且都返回相同的数组。

不幸的是,有一个例外:Outlook的对象模型受到了过多保护,并且没有Run方法。

答案 4 :(得分:0)

很遗憾,无法在ProjectName之前添加ModuleName并添加其他期间“。”在MS Word中,这会引发运行时错误438.该调用仅限于使用ModuleName.ProcName