I am trying to achieve the following using a VBA macro:
I have multiple .xls files, all of which have just one sheet
In my macro, I want to append all the data from the other files into one sheet, by appending them at the bottom of the document behind each other. I have figured out the iterating through files, but copying and appending data is what is bugging me.
The code I have until now is as follows (missing parts are described within the comments)
Sub Iterate_Files()
Dim Fso As Object, objFolder As Object, objSubFolder As Object
Dim FromPath As String
Dim FileInFolder As Object
FromPath = ActiveWorkbook.Path
Set Fso = CreateObject("Scripting.filesystemobject")
Set objFolder = Fso.GetFolder(FromPath)
For Each objSubFolder In objFolder.subfolders
For Each FileInFolder In objSubFolder.Files
'Copy the data from sheet one of the FileInFolder
'to the end of sheet in this file :/
Next FileInFolder
Next objSubFolder
End Sub
The following code appears to have solved the problem:
Sub Iterate_Files()
Dim Fso As Object, objFolder As Object, objSubFolder As Object
Dim FromPath As String
Dim FileInFolder As Object
FromPath = ActiveWorkbook.Path
Set Fso = CreateObject("Scripting.filesystemobject")
Set objFolder = Fso.GetFolder(FromPath)
Set TargetWb = ActiveWorkbook
R = 0
For Each objSubFolder In objFolder.subfolders
For Each FileInFolder In objSubFolder.Files
Set wbSource = Workbooks.Open(FileInFolder)
wbSource.Worksheets(1).UsedRange.Copy Destination:=TargetWb.Worksheets(2).Cells(R + 1, 1)
R = R + 15
wbSource.Close SaveChanges:=False
Next FileInFolder
Next objSubFolder
End Sub
Private Sub Rokaj_Click()
Iterate_Files
End Sub
Related
I have a main Excel file and CSV data in several subfolders. I want now to load the CSVs from one subfolder, start another VBA-Script and then go to the next subfolder.
Example:
MyExcelFile.xlsm
Country 1
../Data1.csv
../Data2.csv
Country 2
../Data3.csv
../Data4.csv
Country1 Report1.csv Report2.csv Country2
Report3.csv Report4.csv
Load all CSVs from Country1, generate a Report, then go to Country2 and generate the report with this data.
Here is my VBA to load the CSVs (thanks to the Author mentioned):
Sub ImportCSVs()
'Author: Jerry Beaucaire
'Date: 8/16/2010
'Summary: Import all CSV files from a folder into separate sheets
Dim fPath As String
Dim fCSV As String
Dim wbCSV As Workbook
Dim wbMST As Workbook
Set wbMST = ThisWorkbook
fPath = (Application.ActiveWorkbook.Path & "\") 'path to CSV files, include the final \
Application.ScreenUpdating = False 'speed up macro
Application.DisplayAlerts = False 'no error messages, take default answers
fCSV = Dir(fPath & "*.txt") 'start the CSV file listing
On Error Resume Next
Do While Len(fCSV) > 0
Set wbCSV = Workbooks.Open(fPath & fCSV, xlDelimited, Delimiter:=",", Format:=6, Local:=False) 'open a CSV file
wbMST.Sheets(ActiveSheet.Name).Delete 'delete sheet if it exists
ActiveSheet.Move After:=wbMST.Sheets(wbMST.Sheets.Count) 'move new sheet into Mstr
Columns.AutoFit 'clean up display
fCSV = Dir 'ready next CSV
Loop
Application.ScreenUpdating = True
Set wbCSV = Nothing
End Sub
Can anyone explain me, how I can go to all Subfolders and hand over the "Subfolder-Name" the the ImportCSVs-CSV? I was looking for this the whole afternoon, but couldn't find an answer.
Thank you so much in advance :-)
Thank you so much for your help. I managed to do exactly what i wanted with the following code:
Sub RunAll()
Dim Fso As Object, objFolder As Object, objSubFolder As Object, tempFolder
As Object
Dim FromPath As String
Dim fpath As String
Dim FileInFolder As Object
Dim ToPath As String
Dim temporaryFolder As String
temporaryFolder = "Temp"
fpath = (Application.ActiveWorkbook.Path & "\")
FromPath = fpath
ToPath = fpath & temporaryFolder & "\"
Set Fso = CreateObject("Scripting.filesystemobject")
Set objFolder = Fso.GetFolder(FromPath)
'clean Masterfolder first
Set tempFolder = Fso.GetFolder(ToPath)
'loop through each subfolders
For Each objSubFolder In objFolder.subfolders
For Each File In tempFolder.Files
File.Delete
Next File
For Each FileInFolder In objSubFolder.Files
If FileInFolder.Name Like "*REPORT*.txt" Then 'criteria
FileInFolder.Copy ToPath
End If
Next FileInFolder
'Check if folder is empty
If Dir(ToPath & "*.*") = "" Then
Else
Call ImportCSVs
Call ImportData
Call PrintPDF
End If
Next objSubFolder
Call CloseFile
End Sub
Creating objects is the concept here. My way is loop through all CSV files in the target folder(includes its subfolders) , and then import those CSV meet my criteria into a new temp folder.
Then you can use your current code to load all CSV to mastersheet, rename and control the temp folder whatever. Hope this helps.
Dim Fso As Object, objFolder As Object, objSubFolder As Object, tempFolder As Object
Dim FromPath As String
Dim FileInFolder As Object
Dim ToPath As String
ToPath = "V:\MasterFolder\"
FromPath = "V:\TargetFolder\"
Set Fso = CreateObject("Scripting.filesystemobject")
'clean Masterfolder first
Set tempFolder = Fso.GetFolder(ToPath)
For Each File In tempFolder.Files
File.Delete
Next File
'loop through each subfolders
For Each objSubFolder In objFolder.subfolders
For Each FileInFolder In objSubFolder.Files
If FileInFolder.Name Like "*DATA*" Then 'criteria
FileInFolder.Copy ToPath
End If
Next FileInFolder
Next objSubFolder
I have a shered folder in perforce where I have many sub-folders and inside of them more then 1000 excel files, I'm running the following code for a specific macro i use (that changed things in wb) .
I also need to apply that macro inside those files. I mean that I want that macro will be available inside every excel file after the code run on the files for re-use in other computer is that possible?
Sub ProcessFiles()
Dim objFolder As Object
Dim objFile As Object
Dim objFSO As Object
Dim MyPath As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then Exit Sub ' < can use Exit Sub instead of GoTo
MyPath = .SelectedItems(1)
End With
Application.DisplayAlerts = False ' <-- add this line
Application.ScreenUpdating = False
Set objFSO = CreateObject("Scripting.FileSystemObject")
Call GetAllFiles(MyPath, objFSO)
Call GetAllFolders(MyPath, objFSO)
' restore default settings
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Complete."
End Sub
Sub GetAllFiles(ByVal strPath As String, ByRef objFSO As Object)
Dim objFolder As Object
Dim objFile As Object
Set objFolder = objFSO.GetFolder(strPath)
For Each objFile In objFolder.Files
DoWork objFile.Path
Next objFile
End Sub
Sub GetAllFolders(ByVal strFolder As String, ByRef objFSO As Object)
Dim objFolder As Object
Dim objSubFolder As Object
Set objFolder = objFSO.GetFolder(strFolder)
For Each objSubFolder In objFolder.subfolders
Call GetAllFiles(objSubFolder.Path, objFSO)
Call GetAllFolders(objSubFolder.Path, objFSO)
Next objSubFolder
End Sub
Sub DoWork(strFile As String)
Dim wb As Workbook
If Right(strFile, 4) = ".xls" Then
Set wb = Workbooks.Open(Filename:=strFile)
With wb
'Do your work here
......
.Close True
End With
End If
End Sub
As explained in the above comment, you can put your code in a .bas module file an then import it into each Excel file through VBE.
workbook.VBProject.VBComponents.Import ("mymodule.bas")
Be careful your Excel spreadsheets are not password protected!
You may want to look at using an AddIn also, then you can just load the AddIn to make the code available to others, so ProcessFiles would be coded as MyAddIn.ProcessFiles.
I am trying to copy a worksheet from a file that is in a certain folder in my computer. I would like to have a main workbook (Workbook1) where I press a button that takes the 1st sheet from every xls or xlsm file from the certain folder (C:\Location). What I currently have is below.
Sub read_a_folder()
Dim MainWB As String
strPath = "C:\Location\"
MainWB = ActiveWorkbook.Name
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFso.GetFolder(strPath)
For Each objFile In objFolder.Files
If objFso.GetExtensionName(objFile.Path) = "xls" Or objFso.GetExtensionName(objFile.Path) = "xlsm" Then
End If
Next
End Sub
So im missing the way to copy the sheet as it is to my main workbook. I have tried using ActiveSheet.QueryTables.Add but the special format of the copied sheets makes it unreadable. Ctrl+Shift+End and CTRL+C works when I do it manually.
Any help is much needed.
Thank you.
just to follow up Dave's code (-> credits to him!) with some enhancements (and one little revision)
Option Explicit
Sub read_a_folder()
Dim objFso As FileSystemObject
Dim objFolder As Folder
Dim objFile As File
Dim MainWB As Workbook
Dim strPath As String
strPath = "C:\Location\"
Set MainWB = ActiveWorkbook '<~~ Workbook is an object -> you must "Set" it
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFso.GetFolder(strPath)
Application.ScreenUpdating = False '<~~ this will reduce the flickering and speed it all up
For Each objFile In objFolder.Files
If objFso.GetExtensionName(objFile.Path) Like "xls*" Then '<~~ use "Like" operator to check for all "xls..." extensions in a single check
With Workbooks.Open(objFile.Path, False, True) '<~~ no need to set an object, just instantiate it and work with it! Furthermore let's use some of the "Open" method parameters to avoid prompts popping out
.Worksheets(1).Copy After:=MainWB.Sheets(MainWB.Sheets.Count) 'copies after last worksheet
.Close False
End With
End If
Next
Application.ScreenUpdating = True '<~~ turn screen updating on
End Sub
The following may help:
Sub read_a_folder()
Dim MainWB As Workbook
Dim objSheet As Worksheet
strPath = "C:\Location\"
MainWB = ActiveWorkbook.Name
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFso.GetFolder(strPath)
For Each objFile In objFolder.Files
If objFso.GetExtensionName(objFile.Path) = "xls" Or objFso.GetExtensionName(objFile.Path) = "xlsm" Then
Set objWb = Workbooks.Open objFile.Path
Set objSheet = objWb.Worksheets(1) ' sets first sheet
objSheet.Copy After:=MainWB.Sheets(MainWB.Sheets.Count) 'copies after last worksheet
objWb.Close
Set objSheet = Nothing
Set objWb = Nothing
End If
Next
End Sub
I see this issue has come up a handful of times on this forum however none of the solutions have helped me. The code below actually did work, but then it started throwing an application-defined or objected defined error and now will not work. The code runs from within an Excel template, opens up each Excel report in the directory, then pastes 2 worksheets into the document.
Sub updateED()
Dim pathout, pathin As String
Dim WbOutput As Workbook
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(filepath)
'step through each xls file
For Each objFile In objFolder.Files
If InStr(objFile, ".xls") Then
Set WbOutput = Workbooks.Open(objFile)
Application.DisplayAlerts = False
'drop in additional templates
ThisWorkbook.Sheets(Array("Business Entity", "Facility")).Copy before:=WbOutput.Sheets("Mbr_Detail_ED")
End If
Next
End Sub
See if this helps
Option Explicit
Sub updateED()
Dim Pathout As String
Dim Pathin As String
Dim WbOutput As Workbook
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\Temp\")
'step through each xls file
For Each objFile In objFolder.Files
If InStr(objFile, ".xls") Then
Set WbOutput = Workbooks.Open(objFile)
Application.DisplayAlerts = False
'drop in additional templates
ThisWorkbook.Sheets(Array("Business Entity", "Facility")).Copy before:=WbOutput.Sheets("Mbr_Detail_ED")
End If
Next
End Sub
Can someone help me with VBA code to rename the subfolder with the part of file name as given below
Folder : C:\Test
Sub folders : C:\Test\a , C:\Test\b , C:\Test\a .... Goes on
It has some file contents and I have to match a file with name starting with VDX_000674 and get last 4 characters and rename the Folder with that.
I have tried the below code but with no use any edits will be appreciated
Sub Rename()
Call Test_Rename("C:\Users\shanmso\Desktop\VN\Output")
End Sub
Sub Test_Rename(MyPath As String)
Dim FileSys As FileSystemObject
Dim objFolder As Folder
Dim objSubFolder As Folder
Dim objFile As File
Dim Riname As String
Set FileSys = CreateObject("Scripting.FileSystemObject")
Set objFolder = FileSys.GetFolder(MyPath)
For Each objFile In objFolder.Files
If Left(objFile.Name, 15) = "DEX-VH_00000374" Then
Riname = Mid(objFile.Name, 17, 3)
Name objFolder As Riname
Exit For
End If
Next objFile
For Each objSubFolder In objFolder.SubFolders
Test_Rename MyPath & "\" & objSubFolder.Name
Next objSubFolder
Set FileSys = Nothing
Set objFolder = Nothing
Set objSubFolder = Nothing
Set objFile = Nothing
End Sub
untested. but I think FreeMan is right Name objFolder As Riname should be something more like this Call MkDir(MyPath & "\" & Riname)
Also I don't think you need the second For Each loop so I removed it. I'm guessing you thought this was actually creating the subfolders, but it isn't. Its easier to just rename the folders in the first For each loop
Sub Test_Rename(MyPath As String)
Dim FileSys As FileSystemObject
Dim objFolder As Folder
Dim objSubFolder As Folder
Dim objFile As File
Dim Riname As String
Set FileSys = CreateObject("Scripting.FileSystemObject")
Set objFolder = FileSys.GetFolder(MyPath)
For Each objFile In objFolder.Files
If Left(objFile.Name, 15) = "DEX-VH_00000374" Then
Riname = Mid(objFile.Name, 17, 3)
Call MkDir(MyPath & "\" & Riname)
Exit For
End If
Next objFile
Set FileSys = Nothing
Set objFolder = Nothing
Set objSubFolder = Nothing
Set objFile = Nothing
End Sub