Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Sub or Function contained in a module using "CallByName" in VB/VBA

Tags:

vba

It is easy to call a function inside a classModule using CallByName How about functions inside standard module?

''#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
like image 824
Kratz Avatar asked Apr 22 '10 23:04

Kratz


2 Answers

Although it is an old question and OP asked for CallByName in a standard module, the correct pieces of advice are scattered through answers and comments, and some may not be that accurate, at least in 2020. As SlowLearner stated, Application.run DOES return a Variant, and in that way both branchs below are equivalent, except by handling errors, as commented around Horowitz's answer:

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

I actually just did this above and had no errors at all, tested in Word, Excel and Access, and both return the same Array.

Unfortunately, there is an exception: Outlook's object Model is too protected and it does not have the Run method.

like image 169
Marcelo Scofano Diniz Avatar answered Oct 22 '22 23:10

Marcelo Scofano Diniz


I think jtolle's response addressed the question best - the small reference to Application.Run may be the answer. The questioner doesn't want to use simply func1 or Module1.func1 - the reason one would want to use CallByName in the first place is that the desired function.sub name is not known at compile time. In this case, Application.Run does work, e.g.:

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

You can also prepend the Project Name before the ModuleName and add another period ".". Unfortunately, Application.Run does not return any values, so while you can call a function, you won't get its return value.

like image 23
David Horowitz Avatar answered Oct 23 '22 00:10

David Horowitz