3
votes

I have an excel macro saved in a blank workbook and multiple data workbooks.

I currently open the macro file and each data file individually, running the macro on each one with a keyboard shortcut.

Is there a way to run the macro on all the data workbooks without opening them, either with

  • a batch file,
  • VBA/VBScript,
  • powershell,
  • or something similar?
5
You could put all the data files into a folder and then use Dir() to loop over them, opening each one and running the macro.Tim Williams
Thanks everyone, the solution I used was a combination of using the PERSONAL.XLSB file (which I knew nothing about before it was mentioned) and a powershell script tutorial found here.Jonathan

5 Answers

3
votes

One way to do this is to add your macro's to the file PERSONAL.XLSB. This file will be loaded in the background every time you start Excel. Initially the PERSONAL.XLSB file will NOT be there. To automatically create this file, just start recording a "dummy" macro (with the record button on the left-bottom of a spreadsheet) and select "Personal Macro Workbook" to store it in. After recording your macro, you can open the VBA editor with [Alt]+[F10] and you will see the PERSONAL.XLSB file with the "dummy" macro. I use this file to store loads of general macro's which are always available. I have added these macro's to my own menu ribbon. One disadvantage of this common macro file is that if you launch more than one instance of Excel, you will get an error message that the PERSONAL.XLSB file is already in use by Excel instance Nr. 1. This is no problem as long as you do not add new macro's at this moment.

2
votes

Two potential solutions below,

  1. which can be run directly as a vbs file
  2. A solution to be run from within Excel (as per Tim Williams suggestion)

solution

Dim objFSO
Dim objFolder
Dim objFil
Dim objXl
Dim objWb
Dim objExcel
Set objExcel = CreateObject("Excel.Application")
Set objFSO = CreateObject("scripting.filesystemobject")
Set objFolder = objFSO.getfolder("c:\temp")
For Each objFil In objFolder.Files
    If InStr(objFil.Type, "Excel") > 0 Then
        Set Wb = objExcel.Workbooks.Open(objFil.Path)
        wscript.echo Wb.name
        Wb.Close False
    End If
Next

solution

Sub OpenFilesVBA()
    Dim Wb As Workbook
    Dim strFolder As String
    Dim strFil As String

    strFolder = "c:\Temp"
    strFil = Dir(strFolder & "\*.xls*")
    Do While strFil <> vbNullString
        Set Wb = Workbooks.Open(strFolder & "\" & strFil)
        Wb.Close False
        strFil = Dir
    Loop
End Sub
1
votes

I sort of stumbled across your post just now, maybe very late, but for all future searches. It is possible to launch your Macro by creating a .vbs file. To do this, open notepad and add the following:

objExcel = CreateObject("Excel.Application")

objExcel.Application.Run <insert macro workbook file path, module and macro name here>
objExcel.DisplayAlerts = False
objExcel.Application.Save
objExcel.Application.Quit

Set objExcel = Nothing

save the file as follows ("your filename".vbs)

By double clicking (opening) the saved .vbs file, it will launch your macro without you having to open your excel file at all.

Hope this helps.

0
votes

You could keep the macro in your personal.xls, or a masterfile, and loop through the workbooks with vba, and activate them before running your macro. As far as I know, you still have to open them with vba though.

You could use something like this:

sub LoopFiles
  Dim sFiles(1 to 10) as string  'You could also read this from a range in a masterfile
      sFiles(1) = "Filename1.xls"
         .
         .
      sFiles(10) = "Filename10.xls"
  Dim wb as Workbook
  Dim iCount as integer
     iCount = ubound(sFiles)
  Dim iCount2 as integer

  For iCount2 = 1 to iCount
     Workbooks(sFiles(iCount2)).open
     Workbooks(sFiles(iCount2)).activate
     Call YourMacro
     Workbooks(sFiles(iCount2)).close
  next iCount2
end sub
0
votes

Other way,

Sub LoopAllWorkbooksOpened()

Dim wb As Workbook

For Each wb In Application.Workbooks
    Call YourMacroWithWorkbookParam(wb)
Next wb

End Sub

Sub YourMacroWithWorkbookParam(wb As Workbook)
    MsgBox wb.FullName
End Sub