我想执行VBA代码,其中代码本身是在运行时从字符串构建的
我已经通过现有的SO答案找到了如何做到这一点: How to run a string as a command in VBA
为便于参考,解决方案如下:
Sub Testing()
StringExecute "MsgBox" & """" & "Job Done!" & """"
End Sub
Sub StringExecute(s As String)
Dim vbComp As Object
Set vbComp = ThisWorkbook.VBProject.VBComponents.Add(1)
vbComp.CodeModule.AddFromString "Sub foo()" & vbCrLf & s & vbCrLf & "End Sub"
Application.Run vbComp.Name & ".foo"
ThisWorkbook.VBProject.VBComponents.Remove vbComp
End Sub
简而言之,它在同一工作簿中创建了一个新模块;根据指定的字符串写一个sub;执行子;然后删除模块 - 所有这些都在同一个运行时进程中。这很有效。
但是如果我想在ThisWorkbook之外的任何其他工作簿上执行操作呢?我正在尝试以下修改过的代码:
Option Explicit
Dim NewWB As Workbook
Sub Testing()
Set NewWB = Workbooks.Add
StringExecute "MsgBox" & """" & "Job Done!" & """"
End Sub
Sub StringExecute(s As String)
Dim vbComp As Object
Set vbComp = NewWB.VBProject.VBComponents.Add(1) ' Note the use of NewWB
vbComp.CodeModule.AddFromString "Sub foo()" & vbCrLf & s & vbCrLf & "End Sub"
Application.Run vbComp.Name & ".foo" ' <-- Error on this line
NewWB.VBProject.VBComponents.Remove vbComp
End Sub
如您所见,此代码完全相同,但是用NewWB替换ThisWorkbook。但是它会在Application.Run行导致错误弹出:
运行时错误'1004':无法运行宏'Module1.foo'。宏可能在此工作簿中不可用,或者可能禁用所有宏。
有谁知道为什么这不适用于新工作簿?我已经尝试在创建它之后通过代码向NewWB添加对VBA扩展性的引用(NewWB.VBProject.References.AddFromGuid“{0002E157-0000-0000-C000-000000000046}”,5,0) - 但是这没有帮助。
答案 0 :(得分:2)
Application.Run
将在工作簿中查找创建新工作簿的模块。尝试(未完全测试)这些方面的东西:
application.run newwb.name & "!foo"
答案 1 :(得分:0)
你会相信吗 - 经过18个小时的讨论后,我发布了一个问题,然后在5分钟内我自己意识到答案。
问题在于Application.Run的语法。显然,它可以在[ModuleName]。[ProcedureName]格式中使用,在调用工作簿中运行一个过程;但是要指定另一个工作簿,语法应为[WorkbookName]![ProcedureName]。
所以我所要做的就是将行改为:
Application.Run NewWB.Name & "!foo"
我认为不应该删除我的问题而应该回答它:)