我正在尝试运行嵌入在每个100个文件中的宏,而无需手动打开,运行,保存和关闭它们。宏只在我想要运行的“目标”文件中。
我找到了SO question关于如何做到这一点并让它在本地工作。
Sub ProcessFiles()
Dim Filename, Pathname As String
Dim wb As Workbook
Pathname = ThisWorkbook.Path
Wildcard = "Target*.xlsm"
Filename = Dir(Pathname & "\" & Wildcard)
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & "\" & Filename)
DoWork wb
wb.Close SaveChanges:=True
Filename = Dir()
Loop
End Sub
Sub DoWork(wb As Workbook)
With wb
'Do your work here
.Worksheets(1).Range("A1").Value = "Goodbye World!"
End With
End Sub
我把这个VBA脚本放在“Controller.xlsm”中,我可以在名为“Target1.xlsm”,“Target2.xlsm”等目标文件的文件夹上运行DoWork()
宏。但是我想用仅在每个目标中的宏替换DoWork()
(所有相同的宏,它调用此机器上的软件)。我尝试将DoWork()
替换为OtherMacro
和Filename!OtherMacro
之类的内容,但都不起作用(其中OtherMacro
是每个“Target * .xlsm”文件中的相同宏)。
这可能吗?在使用“Controller.xlsm”中的宏循环时,我可以在“Target * .xlsm”中运行宏吗?
似乎还可以选择在“Target * .xlsm”中运行宏,其他人在打开时运行。如果“Target * .xlsm”文件中的宏需要2个小时才能运行,这会导致问题吗?也就是说,“Controller.xlsm”中的macr会在工作完成之前尝试保存并关闭“Target * .xlsm”吗?谢谢!
答案 0 :(得分:1)
我有一个关于我作为评论添加的链接的游戏,它可以工作,但它确实需要您更改安全权限。如果您知道宏的名称及其位置(模块名称),您应该只能使用Application.Run
。
我试过没有指定模块名称,但它一直给我一个错误。
Sub ProcessFiles()
Dim Filename, Pathname As String
Dim wb As Workbook
Pathname = ThisWorkbook.Path
Wildcard = "Target*.xlsm"
Filename = Dir(Pathname & "\" & Wildcard)
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & "\" & Filename)
Application.Run wb.name & "!Module1.DoStuff"
wb.Close SaveChanges:=True
Filename = Dir()
Loop
End Sub
我确信Application.Run
的工作方式与任何其他VBA子工作方式相同,并且它会在执行下一个命令之前等待它完成,但由于似乎没有办法返回一个值,不? (你在同一个excel实例中打开一个新工作簿,所以我认为应该没问题)
重新阅读你的问题,我认为你有同样的问题,如果可以修改你的宏,你可以删除循环并使用队列代替。让宏返回一个值来表示它已完成,或者使用上面的代码调用主表中的sub来执行下一个项目。
答案 1 :(得分:1)
我认为您不需要指定宏所在的模块。这应该有效:
Application.Run "'" & wb.name & "'!DoStuff"
请注意,工作簿名称必须用单引号括起来。我认为目标工作簿中的宏必须是公共的。