I would like to run a VBA macro named MyMacro, which is saved as MyMacro.bas for many excel files. I have the VBS code below, but it is not doing what I want. I would really appreciate if somebody could take a look at it.
I am using Excel 2013. The files are saved as .xls.
Thank you.
Const sRootFolder = "C:\Documents"
Const sExportedModule = "C:\Documents\MyMacro.bas"
Const sMacroName = "MyMacro"
Dim oFSO, oFDR, oFile ' File and Folder variables
Dim oExcel, oWB ' Excel variables (Application and Workbook)
Start
'------------------------------
Sub Start()
Initialize
ProcessFilesInFolder sRootFolder
Finish
End Sub
'------------------------------
Sub ProcessFilesInFolder(sFolder)
' Process the files in this folder
For Each oFile In oFSO.GetFolder(sFolder).Files
If IsExcelFile(oFile) Then ProcessExcelFile oFile.Path
Next
End Sub
'------------------------------
Sub Initialize()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oExcel = CreateObject("Excel.Application")
End Sub
'------------------------------
Sub Finish()
oExcel.Quit
Set oExcel = Nothing
Set oFSO = Nothing
End Sub
'------------------------------
Function IsExcelFile(oFile)
IsExcelFile = (InStr(1, oFSO.GetExtensionName(oFile), "xls", vbTextCompare) > 0) And (Left(oFile.Name, 1) <> "~")
End Function
'------------------------------
Sub ProcessExcelFile(sFileName)
On Error Resume Next
wscript.echo "Processing file: " & sFileName ' Comment this unless using cscript in command prompt
Set oWB = oExcel.Workbooks.Open(sFileName)
oWB.VBProject.VBComponents.Import sExportedModule
oExcel.Run sMacroName
oWB.Save
oWB.Close
Set oWB = Nothing
End Sub
'------------------------------
Here is a vbs code for a single file which works:
Option Explicit
ExcelMacroExample
Sub ExcelMacroExample()
Dim xlApp
Dim xlBook
Dim objWorkbook
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open("C:\Documents\test.xls", 0, True)
Set objWorkbook = xlApp.Workbooks.Open("C:\Documents\test.xls")
xlApp.Run "MyMacro"
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
End Sub
I finally got it working:
Const sRootFolder = "C:\Documents"
Const sExportedModule = "C:\Documents\MyMacro.bas"
Const sMacroName = "Trip"
Dim oFSO, oFile ' File and Folder variables
Dim xlApp, xlBook, objWorkbook
Start
Sub Start()
Initialize
ProcessFilesInFolder sRootFolder
Finish
End Sub
Sub ProcessFilesInFolder(sFolder)
' Process the files in this folder
For Each oFile In oFSO.GetFolder(sFolder).Files
If IsExcelFile(oFile) Then ProcessExcelFile oFile.Path
Next
End Sub
Sub Initialize()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set xlApp = CreateObject("Excel.Application")
End Sub
Sub Finish()
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
Set oFSO = Nothing
End Sub
Function IsExcelFile(oFile)
IsExcelFile = (InStr(1, oFSO.GetExtensionName(oFile), "xls", vbTextCompare) > 0) And (Left(oFile.Name, 1) <> "~")
End Function
Sub ProcessExcelFile(sFileName)
wscript.echo "Processing file: " & sFileName ' Comment this unless using cscript in command prompt
Set xlBook = xlApp.Workbooks.Open(sFileName, 0, True)
Set objWorkbook = xlApp.Workbooks.Open(sFileName)
objWorkbook.VBProject.VBComponents.Import sExportedModule
xlApp.Run sMacroName
End Sub
Also, make sure that Trust access to the VBA project object model enabled. I certainly may be wrong, but the game changer here seems to be this piece:
Set objWorkbook = xlApp.Workbooks.Open(sFileName)
Related
I'm a newbie with vbs and trying to figure out how to reopen excel file.
I have like 100+ excels in one folder, where I need to open them one by one and run the macro.
It is working pretty well except for files, which are already open. I would like to reopen them and edit them.
Could you please advise how to do it?
Bellow is the code:
Const sRootFolder = "C:\test"
Dim oFSO, oFile ' File and Folder variables
Dim xlApp, xlBook, objWorkbook
Start
Sub Start()
Initialize
ProcessFilesInFolder sRootFolder
Finish
End Sub
Sub ProcessFilesInFolder(sFolder)
' Process the files in this folder
For Each oFile In oFSO.GetFolder(sFolder).Files
If IsExcelFile(oFile) Then ProcessExcelFile oFile.Path
Next
End Sub
Sub Initialize()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set xlApp = CreateObject("Excel.Application")
End Sub
Sub Finish()
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
Set oFSO = Nothing
End Sub
Function IsExcelFile(oFile)
IsExcelFile = (InStr(1, oFSO.GetExtensionName(oFile), "xls", vbTextCompare) > 0) And (Left(oFile.Name, 1) <> "~")
End Function
Sub ProcessExcelFile(sFileName)
Set xlBook = xlApp.Workbooks.Open(sFileName, 0, True)
Set objWorkbook = xlApp.Workbooks.Open(sFileName)
xlApp.Run "macro"
End Sub
Sub Save()
xlBook.Save
xlBook.Close
xlApp.Quit
WScript.Echo "Finished."
End Sub
I am trying to create a button in a .xlsm that will convert each of the ~100 .xlsx files in the myFolder directory to .txt. The below VBA code returns an Expected End Suberror. The data is always in `Sheet 1" even though there may be other sheets present.
The Dos command executes and converts the files but they are unreadable (something to do with excels formatting?). I am not sure what to do? Thank you :)
Dos
cd C:\Users\Desktop\folder
Copy *.xlsx *.txt
VBA
Option Explicit
Private Sub CommandButton1_Click()
Dim oFSO, myFolder
Dim xlText
myFolder = "C:\Users\Desktop\folder"
Set oFSO = CreateObject("Scripting.FileSystemObject")
xlText = -4158 'Excel txt format enum
Call ConvertAllExcelFiles(myFolder)
Set oFSO = Nothing
Call MsgBox("Done!")
Sub ConvertAllExcelFiles(ByVal oFolder)
Dim targetF, oFileList, oFile
Dim oExcel, oWB, oWSH
Set oExcel = CreateObject("Excel.Application")
oExcel.DisplayAlerts = False
Set targetF = oFSO.GetFolder(oFolder)
Set oFileList = targetF.Files
For Each oFile In oFileList
If (Right(oFile.Name, 4) = "xlsx") Then
Set oWB = oExcel.Workbooks.Open(oFile.Path)
For Each oWSH In oWB.Sheets
Call oWSH.SaveAs(oFile.Path & ".txt", FileFormat:=xlTextWindows)
Next
Set oWSH = Nothing
Call oWB.Close
Set oWB = Nothing
End If
Next
Call oExcel.Quit
Set oExcel = Nothing
End Sub
The first lines of your code belong in Private Sub CommandButton1_Click()
(it has to be closed by End Sub)
Option Explicit and proper code indentation can help in this situation
Try this version:
Option Explicit
Private Sub CommandButton1_Click()
Dim myFolder As String
myFolder = "C:\Users\Desktop\folder"
ConvertAllExcelFiles myFolder
MsgBox "Done!"
End Sub
Public Sub ConvertAllExcelFiles(ByVal folderPath As String)
Dim xlApp As Object, wb As Workbook, ws As Variant, fso As Object
Dim fileList As Object, itm As Object, fileName As String
Set fso = CreateObject("Scripting.FileSystemObject")
Set fileList = fso.GetFolder(folderPath).Files
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = False
For Each itm In fileList
If Right(itm.Name, 4) = "xlsx" Then
Set wb = xlApp.Workbooks.Open(itm.Path)
fileName = fso.GetParentFolderName(itm.Path) & "\" & fso.GetBaseName(itm.Path)
If True Then 'if converting all sheets use For loop (Change True to False)
wb.Sheets(1).SaveAs fileName & ".txt", FileFormat:=xlTextWindows
Else
For Each ws In wb.Sheets
ws.SaveAs fileName & " - " & ws.Name & ".txt", FileFormat:=xlTextWindows
Next
Set ws = Nothing
End If
wb.Close: Set wb = Nothing
End If
Next
xlApp.Quit
End Sub
I need to automate reporting in word by extracting numbers from Excel. I searched and followed the code sourced from http://www.makeuseof.com/tag/integrate-excel-data-word-document/
Code doesn't run properly and encounters a number of errors.
1. Excel doesn't open
2. Encounter Run-time error '438': Object doesn't support this property or method.
I have used the "early binding" code suggested by website and doesn't work and the researched to use "late binding". still doesn't work. I inserted "Microsoft Excel 14.0 Object Library" and insert "Label" in word doc under "ActiveX Control"
Don't know what went wrong.
Current vba code
Private Sub CommandButton1_Click()
Dim objExcel As Object
Set objExcel = CreateObject("Excel.Application")
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
ThisDocument.DMY.Caption = exWb.Sheets("Summary").Cell(5, 4)
exWb.Close
Set exWb = Nothing
End Sub
Previous code
Private Sub CommandButton1_Click()
Dim objExcel As New Excel.Application
Dim exWb As Excel.Workbook
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
ThisDocument.DMY.Caption = exWb.Sheets("Summary").Cells(5, 4)
exWb.Close
Set exWb = Nothing
End Sub
Adapting code from: https://www.experts-exchange.com/questions/26874253/How-to-loop-with-VBA-on-all-controls-placed-in-a-Word-doc.html
You can write a utility function to get an ActiveX control given its name and the hosting document:
Private Sub CommandButton1_Click()
Dim con As Object
Dim objExcel As Object, exWb As Object
Set con = ActiveXControlByName(ThisDocument, "DMY")
If Not con Is Nothing Then
Set objExcel = CreateObject("Excel.Application")
Set exWb = objExcel.Workbooks.Open("C:\Users\adong\Desktop\Reporting.xlsx")
con.Caption = exWb.Sheets("Summary").Cell(5, 4).Value
exWb.Close False
Set exWb = Nothing
objExcel.Quit
End If
End Sub
Function ActiveXControlByName(doc As Document, theName As String) As Object
Dim ilsh As InlineShape
Dim sh As Shape, ob As Object
For Each ilsh In doc.InlineShapes
If ilsh.Type = wdInlineShapeOLEControlObject Then
Set ob = ilsh.OLEFormat.Object
If ob.Name = theName Then
Set ActiveXControlByName = ob
Exit Function
End If
End If
Next ilsh
For Each sh In ActiveDocument.Shapes
If sh.Type = msoOLEControlObject Then
Set ob = sh.OLEFormat.Object
If ob.Name = theName Then
Set ActiveXControlByName = ob
Exit Function
End If
End If
Next sh
'if got here then control was not found...
Set ActiveXControlByName = Nothing
End Function
I have a script that applies a macro to multiple excel spreadsheets. The code below opens specific file names and runs the script. I would love to modify this to run on all xls files within a specified folder. Any help would be great!
Dim objExcel, objWorkbook, xlModule, strCode
If ReportFileStatus("C:\Billing\Import\IL\3.xls") = "True" Then
OpenFile "C:\Billing\Import\IL\3.xls, ""
If ReportFileStatus("C:\Billing\Import\IL\3.xls") = "True" Then
OpenFile "C:\Billing\Import\IL\3.xls", ""
If ReportFileStatus("C:\Billing\Import\IL\3.xls") = "True" Then
OpenFile "C:\Billing\Import\IL\3.xls", ""
End If
On Error Resume Next
Set xlModule = Nothing
Set objWorkbook = Nothing
objExcel.Quit
Set objExcel = Nothing
On Error GoTo 0
'~~> Sub to open the file
Sub OpenFile(sFile, DestFile)
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = false
objExcel.DisplayAlerts = False
Set objWorkbook = objExcel.Workbooks.Open(sFile)
Set xlModule = objWorkbook.VBProject.VBComponents.Add(1)
strCode = _
"Sub MACRO()" & vbCr & _
'~~> My Macro Here
"End Sub"
xlModule.CodeModule.AddFromString strCode
objExcel.Run "MACRO"
objWorkbook.Close (False) '<~~ Change false to true in case you want to save changes
objExcel.Application.Quit
End Sub
'~~> Function to check if file exists
Function ReportFileStatus(filespec)
Dim fso, msg
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists(filespec)) Then
msg = "True"
Else
msg = "False"
End If
ReportFileStatus = msg
End Function
Thanks
The concept is pretty simple, given a folder path, process all files in it (or only certain files based on extension), and all files within it's subfolder. The simplest method is recursive subs and functions with some global variables in a single thread.
The next thing to consider is to Import .bas file instead of trying to add text to a new module. You need to export a working code from a Module first.
Below assumed the root folder to be "C:\Billing\Import", the exported module .bas file is "C:\Test\Module1.bas", and the Sub name you want to execute is "MACRO".
Const sRootFolder = "C:\Billing\Import"
Const sExportedModule = "C:\Test\Module1.bas"
Const sMacroName = "MACRO"
Dim oFSO, oFDR, oFile ' File and Folder variables
Dim oExcel, oWB ' Excel variables (Application and Workbook)
Start
'------------------------------
Sub Start()
Initialize
ProcessFilesInFolder sRootFolder
Finish
End Sub
'------------------------------
Sub ProcessFilesInFolder(sFolder)
' Process the files in this folder
For Each oFile In oFSO.GetFolder(sFolder).Files
If IsExcelFile(oFile) Then ProcessExcelFile oFile.Path
Next
' Recurse all sub-folders from this folder
For Each oFDR In oFSO.GetFolder(sFolder).SubFolders
ProcessFilesInFolder oFDR.Path
Next
End Sub
'------------------------------
Sub Initialize()
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oExcel = CreateObject("Excel.Application")
End Sub
'------------------------------
Sub Finish()
oExcel.Quit
Set oExcel = Nothing
Set oFSO = Nothing
End Sub
'------------------------------
Function IsExcelFile(oFile)
IsExcelFile = (InStr(1, oFSO.GetExtensionName(oFile), "xls", vbTextCompare) > 0) And (Left(oFile.Name, 1) <> "~")
End Function
'------------------------------
Sub ProcessExcelFile(sFileName)
On Error Resume Next
wscript.echo "Processing file: " & sFileName ' Comment this unless using cscript in command prompt
Set oWB = oExcel.Workbooks.Open(sFileName)
oWB.VBProject.VBComponents.Import sExportedModule
oExcel.Run sMacroName
oWB.Close
Set oWB = Nothing
End Sub
'------------------------------
Feel free to ask if you get stuck understanding the program flow.
I try to apply a VBA macro kept in personl.xls to all files in a given directory,
but I hit an error in line 29..
I'm afraid I got things mixed up here:
Option Explicit
On Error Resume Next
Dim xlApp
Dim xlBook
Dim No_Of_Files
Dim i
Dim File_Path
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = True
File_Path = "C:\Dokumente und Einstellungen\kcichini\Eigene Dateien\Stuff\Test\"
With xlApp.FileSearch
.NewSearch
.LookIn = File_Path
.Filename = "*.xls"
.SearchSubFolders = False
.Execute
No_Of_Files = .FoundFiles.Count
For i = 1 To No_Of_Files
Set xlBook = xlApp.Workbooks.Open(.FoundFiles(i), 0, False)
xlApp.Run "'C:\Dokumente und Einstellungen\kcichini\Anwendungsdaten\Microsoft\Excel\XLSTART\PERSONL.XLS'!SASXLSFormat"
xlApp.ActiveWorkbook.Close
Next i
End With
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing
I obviously was on a completedly wrong track.
But this seems to work properly:
Option Explicit
On Error Resume Next
Dim xlApp
Dim xlBook
Dim sPath
Dim fso
Dim ObjFolder
Dim ObjFiles
Dim ObjFile
'make an object with the excel application
Set xlApp = CreateObject("Excel.Application")
xlApp.DisplayAlerts = True
'Creating File System Object
Set fso = CreateObject("Scripting.FileSystemObject")
'Getting the Folder Object
Set ObjFolder = fso.GetFolder("C:\Dokumente und Einstellungen\kcichini\Eigene Dateien\Stuff\Test")
'Getting the list of Files
Set ObjFiles = ObjFolder.Files
'Running the macro on each file
For Each ObjFile In ObjFiles
'MsgBox (ObjFolder & "\" & ObjFile.Name)
Set xlBook = xlApp.Workbooks.Open(ObjFolder & "\" & ObjFile.Name, 0, False)
xlApp.Run "'C:\Dokumente und Einstellungen\kcichini\Anwendungsdaten\Microsoft\Excel\XLSTART\PERSONL.XLS'!SASXLSFormat"
xlApp.xlBook.Close
Next
xlApp.Quit
Set xlBook = Nothing
Set xlApp = Nothing