我希望根据打开的工作簿的文件名调用子例程。我有一个名为" SubModel_OtherAdmin"我正在执行子程序和工作簿B,其中存储了VBA逻辑(子程序,函数等)。我在工作簿B中创建一个名为" Assumptions_OtherAdmin"的子例程。而不是使用:
Call Assumptions_OtherAdmin
我想根据工作簿A中的文件名调用该特定子例程。大图片,工作簿A可以是其他工作簿,例如" SubModel_Marketing"或" SubModel_Revenue"等。其中每个都有自己的Assumptions子程序名称,并在工作簿B中存储。
我最初的想法是定义一个字符串然后使用Call String
,但这导致了一个错误。我的第二个想法是在工作簿B的选项卡中构建一个表/网格,其中存储子例程,将我将使用的可能文件名链接到其各自的Assumptions子例程名称。例如,在B列row2中,我将文件名" SubModel_OtherAdmin"在C列第2行中,我会将" Assumptions_OtherAdmin"等等。如果我要通过在B列中查找文件名并使用同一行中C列中的名称来创建调用子例程的函数,我试图进行头脑风暴。我发现自己回到了与上面提到的使用Call String
相同的错误。我正在考虑的另一条途径是使用精选案例,但我已经陷入了规划过程。任何想法或建议将不胜感激。
答案 0 :(得分:4)
Call
关键字只是一种不推荐/过时的调用过程的方式。
此:
Call Assumptions_OtherAdmin
与此相同:
Assumptions_OtherAdmin
我真的没有理由使用Call
,只是因为语言的旧版本需要它,并且由于向后兼容的原因它仍然存在
您可以通过多种方式按名称调用过程,尤其是在excel-vba中。它的工作方式取决于程序的位置。
如果代码是标准代码模块中的Public
过程,因为Excel的Application
对象具有Run
方法,给定Workbook
个对象,一个String
程序名称,您可以这样做:
Public Sub CallMacroByName(ByVal book As Workbook, ByVal procedure As String)
Dim qualifiedName As String
If InStr(1, procedure, "'!") = 0 Then
qualifiedName = "'" & book.FullName & "'!" & procedure
Else
qualifiedName = procedure 'assume procedure is qualified already
End If
Application.Run qualifiedName
End Sub
你会这样做:
Public Sub DoSomething()
Dim book As Workbook
Set book = ActiveWorkbook
CallMacroByName book, "MyProcedure"
End Sub
如果您拥有的只是工作簿的全名,则可以调整此代码,使其无需参考相关图书即可使用。
如果您需要调用的过程是位于类模块中的对象成员,那么您需要更加努力地工作并传递公开要调用的成员的对象实例。优点是,无论您的主机应用程序是否支持Application.Run
,它都有效,因为您将使用VBA.Interaction.CallByName
标准库函数:
Public Sub CallObjectMemberByName(ByRef instance As Object, ByVal procedure As String)
'assumes procedure isn't a property accessor:
CallByName instance, procedure, VbMethod
End Sub
你会这样做:
Public Sub DoSomething(ByRef owner As Class1)
'assumes owner instance is provided by something else
CallObjectMemberByName owner, "MyProcedure"
End Sub
如果您要致电的程序是Private
,那么您运气不佳。