我想这样做:“如果有一个模块 X 包含一个函数 Y 然后调用它,否则不要。”
我知道我可以使用CallByName(Object, MethodName, ...)
来调用对象实例的方法或属性。
是否可以调用未绑定到对象的全局子/函数?
//Module1
Public Sub DoSomething
End Sub
//Module2
Public Sub TriggerDoSomething
On Error Resume Next
CallByName2 "Module1", "DoSomething", ...
End Sub
我知道,最好重构我的代码以将DoSomething
包装到一个类中,但目前这是不可能的,因为它会以一种无法修复的方式破坏我的同事的代码几个小时。
答案 0 :(得分:4)
CallByName一个类真的会更容易 - 你不能只用一个重定向调用模块的类来包装模块吗?
可以使用FunctionDelegator按名称调用模块中的例程。 Matt Curland的优秀书籍Advanced Visual Basic 6对此进行了解释。
谷歌搜索可能会使用CallWindowProc找到一些黑客,但马特·柯兰德说这很危险。这几乎是关于此事的最后一句话:)
编辑:RS Conley的答案不使用模块,使用具有GlobalMultiUse实例属性的类,您将能够使用CallByName。如果您的代码在DLL而不是EXE中,这将有效。 RS Conley建议,在任何情况下,使用DLL中几乎所有功能的最小EXE都会更灵活:这可能是真的。
答案 1 :(得分:1)
条件编译可以解决您的问题吗?
//Module2
Public Sub TriggerDoSomething
#If DoSomething_IsPresent Then
DoSomething
#End if
End Sub
然后在项目设置中添加以下条件编译参数:
顺便说一下,请注意:
中的“On Error Resume Next”//Module2
Public Sub TriggerDoSomething
On Error Resume Next
CallByName2 "Module1", "DoSomething", ...
End Sub
如果Module1中存在DoSomething但有未处理的错误,您将不会注意到它。
答案 2 :(得分:1)
不要使用模块,使用具有GlobalMultiUse实例属性的类,并且您将能够使用CallbyName
答案 3 :(得分:1)
应该这样做的人。 我接受捐款。
Public Sub callbyname2(proc As String)
Dim vbComp As VBComponent
For Each vbComp In ActiveWorkbook.VBProject.VBComponents
On Error Resume Next
Application.Run (vbComp.name & "." & proc)
If Err.Number <> 1004 Then
Exit For
End If
Next
End Sub