1

I am trying to run a macro that is embedded in each of 100 files without manually opening, running, saving, and closing them. The macro is only in the "target" files that I would like to run.

I found this SO question on how to do this and gotten it to work locally.

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

I put this VBA script in "Controller.xlsm" and I can run the DoWork() macro on a folder of target files with names like "Target1.xlsm", "Target2.xlsm", and so on. But I would like to replace DoWork() with a macro that is only in each of the targets (all the same macro, which calls software on this machine). I tried replacing DoWork() with things like OtherMacro and Filename!OtherMacro, but neither work (where OtherMacro is the identical macro in each of the "Target*.xlsm" files).

Is this possible? Can I run the macro in "Target*.xlsm" while looping through using a macro in "Controller.xlsm"?

It seems there's also the option to run the macro in "Target*.xlsm" and the others on open. If the macro in "Target*.xlsm" files requires 2 hours to run, will this cause problems? That is, will the macr in "Controller.xlsm" try to save and close "Target*.xlsm" before the work is done? Thanks!

4

2 回答 2

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 实例中打开一个新工作簿,所以我认为应该没问题)

只需重新阅读您的问题,我认为您有同样的问题,如果可以修改您的宏,您可以删除循环并改用队列。让宏要么返回一个值以指示其完成,要么使用上面的代码调用主表中的子表来执行下一项。

于 2013-04-16T09:40:29.330 回答
1

我认为您不需要指定宏所在的模块。这应该有效:

Application.Run "'" & wb.name & "'!DoStuff"

请注意,工作簿名称必须用单引号引起来。而且我认为目标工作簿中的宏必须是公共的。

于 2013-04-16T10:02:57.057 回答