Good afternoon,
I have tried searching different forums to no avail.
I have the below VBA code that will loop through all files in a folder and generate in a msge box the total number of rows of every file looped in that folder.
What I need your help on if possible is generate a summary report.
Ideally
The summary report will show File name and show how many rows with data in column H.
Sub LoopThroughFiles()
Dim folderPath As String
folderPath = ThisWorkbook.Path & "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename, ReadOnly:=True)
For Each sh In wb.Sheets
If Application.CountA(sh.Range("H:H")) > 0 Then
myCount = myCount + sh.Range("H" & Rows.Count).End(xlUp).Row
End If
Next
wb.Close False
Filename = Dir
Set wb = Nothing
Loop
MsgBox myCount
End Sub
You could try opening a "home" workbook where all values are stored. Basically, what you'll need to do is open a new workbook, and during your loop through each of the files, you'll paste the file path and the row count in the new workbook. Hopefully this will help, or at least give you an idea of how to do what you're trying to do. `
Sub LoopThroughFiles()
Dim folderPath As String
Dim summarySheet as Workbook
set summarySheet = workbook.add
folderPath = ThisWorkbook.Path & "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Set wb = Workbooks.Open(folderPath & Filename, ReadOnly:=True)
For Each sh In wb.Sheets
If Application.CountA(sh.Range("H:H")) > 0 Then
myCount = myCount + sh.Range("H" & Rows.Count).End(xlUp).Row
End If
Next
wb.Close False
summarySheet.activate
Range("A:A").insert Shift:=xlDown
Cells(1,1) = Filename
Cells(1,2) = myCount
Filename = Dir
Set wb = Nothing
Loop
MsgBox myCount
End Sub`
Related
I am trying to do a loop to unfilter the column A for all the workbooks (as they are the same, alwyas column A).
I want to show all the cells as the filter romve the empty cells.
I have many of folders ( more than 50) so the loop is very useful and important for the next step of my code.
I have a code that works for one folder:
`Sub unfilterr()
Dim y As Workbook, myfile, FolderPath, path
Dim ws As Excel.Worksheet
Set y = Workbooks.Open("Z:\VBA\Copie de Devis_65 Version
avec G35.xlsx")
With y.Worksheets("Para RF")
If Not y.Worksheets("Para RF").AutoFilter Is Nothing Then
y.Sheets("Para RF").Range("A1").AutoFilter Field:=1
End If
End With
End Sub`
and now trying to do the loop:
`Sub unfilter1()
Dim y As Workbook, myfile, FolderPath, path
Dim ws As Excel.Worksheet
'## Open workbooks first:
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
FolderPath = "Z:\VBA\Test\"
path = FolderPath & "*.xls*"
myfile = Dir(FolderPath & "*.xls*")
Do While myfile <> ""
Set y = Workbooks.Open(path) 'I put path instead of myfile because I have error if I put myfile
Set ws = y.Worksheets("Para RF")
'With ws
If Not ws.AutoFilter Is Nothing Then
y.Sheets("Para RF").Range("A1").AutoFilter Field:=1
End If
'End With
myfile = Dir()
y.Close saveChanges:=True
Loop
MsgBox ("Task Complete")
End Sub
can you please tell what is the problem with this loop!?
I am trying it on 4 workbooks in the test folder! only the first one is unfiltered while the others are not. It seems like the loop is repeting on only the first workbook in the folder.
So with this loop no error message but the result is unsatisfing.
Thank you a lot for your help.
cheers!
The Workbook.Open() method needs a full path and the filename.
Replace
Set y = Workbooks.Open(path)
With
Set y = Workbooks.Open(FolderPath & myfile)
and you should be good to go.
You don't need the path variable.
Edit: I minimized your whole script to the bare minimum to loop through all ".xls" files and open all off them within a folder:
Sub OpenWorkbooks()
Dim y As Workbook
Dim myfile As String
Dim FolderPath As String
FolderPath = "C:\TestDirectory\"
myfile = Dir(FolderPath & "*.xls*")
Do While myfile <> ""
Set y = Workbooks.Open(FolderPath & myfile)
myfile = Dir()
Loop
End Sub
The above opens each Excel file in C:\TestDirectory\ on my machine.
N.b. make sure you have the "\" at the end of the FolderPath variable, otherwise it'll look for C:\TestDirectorySomeFileName.xlsx which is not going to work.
I have a folder with nearly 1000 .csv files. Each of these files contains 2 columns, and I would like to copy only one of these columns and transpose it onto a new workbook. The new workbook will contain all the data from each of these files. The following code is what I have generated:
Sub AllFiles()
Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
folderPath = "J:etc. etc. etc." 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
Filename = Dir(folderPath & "*.csv")
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
Application.CutCopyMode = False
Selection.Copy
ActiveWorkbook.Close True
Windows("Compiled.xlsm").Activate
Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Transpose:=True
Filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
For whatever reason the code does not work and a box pops-up saying "Code execution has been interrupted." Once I hit "Debug" the following line is highlighted:
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
I am not experienced with VBA at all and I am having trouble troubleshooting this issue. Any idea on what this means and what I can do?
The highlighted line is referring to a range on the workbook that is running the macro as opposed to the range within the workbook you have opened. Try replacing with this:
wb.Range(wb.Range("B1"), wb.Range("B1").End(xlDown)).Select
However I would suggest you avoid using the Select function altogether as it tends to slow down code. I've trimmed the loop a bit to avoid using Select and Activate:
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
wb.Range(wb.Cells(1,"B"), wb.Cells(Rows.Count,"B").End(xlUp)).Copy
Workbooks("Compiled.xlsm").Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Transpose:=True
wb.Close True
Filename = Dir
Loop
Once you open file file, the active workbook is the book just opened and the active sheet is also established.
Your code fails primarily because of the wb.. (In general you would use a sheet reference instead), but in this case, replace:
wb.Range(Range("B1"), Range("B1").End(xlDown)).Select
with:
Range("B1").End(xlDown)).Select
(You also do not need Select to accomplish a copy/paste)
try with below
Sub AllFiles()
Application.EnableCancelKey = xlDisabled
Dim folderPath As String
Dim Filename As String
Dim wb As Workbook
folderPath = "c:\work\test\" 'contains folder path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
Filename = Dir(folderPath & "*.xlsx")
Do While Filename <> ""
Application.ScreenUpdating = False
Set wb = Workbooks.Open(folderPath & Filename)
Range("B1:B" & Range("B" & Rows.count).End(xlUp).Row).Copy
Workbooks("Compiled").Worksheets("Sheet1").Range("A" & Range("A" & Rows.count).End(xlUp).Row + 1).PasteSpecial Transpose:=True
Workbooks(Filename).Close True
Filename = Dir
Loop
Application.ScreenUpdating = True
End Sub
wb.Range(...) will never work since wb is a Workbook object. You need a Worksheet object. Try:
Dim ws As Worksheet
Set ws = wb.Activesheet
ws.Range(ws.Range("B1"), ws.Range("B1").End(xlDown)).Select
In a quest to further never do anythign manual ever again
I made an it.xlsm that you have to put together in a folder with a specific file that has to be processed.
This it.xslm has three modules:
Masterfile
- renames the categories in C
-makes a worksheet per category in C
-saves those worksheets as .xslx. This results in 8 new files in a /Departement folder
Littlefiles
-renames the categories in E
-makes tabs for each category
-cleans up empty columns.
placeholder
Opens the .xls with the data
Applies Masterfile
Opens all the files created by masterfiles
makes tabs and cleans up empty columns.
Placeholder's code:
Sub OpenBigFile()
Dim wb As Workbook
Dim ws As Worksheet
Dim Lastrow As Long
'open main file, apply masterfile moduke
Set wb = Workbooks.Open(ThisWorkbook.path & "\Depositformulier (Reacties).xlsx")
Call masterfile.total
wb.Close SaveChanges:=True
End Sub
This works fine.
Sub OpenAllFiles()
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
myPath = ThisWorkbook.path & "\" & "Departement" & "\"
myFile = Dir(myPath & "*.xlsx")
Do While Len(Filename) > 0
DoEvents
Set wb = Workbooks.Open(myPath & myFile, True, True)
Call LittleFiles.total
wb.Close False
myFile = Dir
Loop
End Sub
Here I find myself in problems. I tried to rewrite it many times, using many examples, but always it seems to be stuck at Set wb = Workbooks.Open(Filename:=myPath & myFile)
What am I doing wrong?
Do you need my Littlefiles code?
Also, in general, is it correct that 'ThisWorkbook' will always refer to the this.xlm,even if in the mean time another workbook is active (this being ActiveWorkbook)?
Thanks a bunch
Here's my attempt, i think this way it'll be harder to go wrong as you will have the full path of the file already stored:
Sub OpenAllFiles()
'create an array
Dim myFiles As Variant
ReDim myFiles(500)
myPath = ThisWorkbook.Path
If Right(myPath, 1) <> "\" Then
myPath = myPath & "\"
End If
'search for at least 5 files in the folder specified above, add the entire path to the array
While myCount < 5
If Dir(myPath & "*.xlsm") <> "" Then
potentialFileToLoad = Dir(myPath & "*.xlsm")
While potentialFileToLoad <> ""
myFiles(myCount) = myPath & potentialFileToLoad
myCount = myCount + 1
potentialFileToLoad = Dir
Wend
End If
Wend
'change size of array to ammount of files found
ReDim Preserve myFiles(myCount - 1)
For Each ii In myFiles
'(Insert Open, Run code, close code here)
Workbooks.Open (ii), True, True
Call LittleFiles.Total
ActiveWorkbook.Close
Next ii
End Sub
try something similar to this
path = "path2folder" & "\" 'this is fairly important and probably why your code breaks?_
you cant add the backslash like you do above
Filename = Dir(path & "*.xl??")
Do While Len(Filename) > 0
DoEvents
Set wbk = Workbooks.Open(path & Filename, True, True)
'add your code
wbk.Close False
Filename = Dir
Loop
I am trying to copy data from a couple of workbooks present in a folder into a single workbook. I am looping through the folder to fetch the data from the various workbooks but I need to paste the data spanning from A5:D5 in loop.
i.e A5:D5 in the destination sheet is one workbook's data in the folder, I need the other set of data to be copied into A6:D6 and so on for the number of workbooks in the folder. Please help me loop through this.
Private Sub CommandButton1_Click()
Dim wbk As Workbook
Dim Filename As String
Dim Path As String
Path = "D:\Macro_Demo\estimation_sheets\"
Filename = Dir(Path & "*.xls")
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
'--------------------------------------------
'OPEN EXCEL FILES
Do While Len(Filename) > 0 'IF NEXT FILE EXISTS THEN
Set wbk = Workbooks.Open(Path & Filename)
target.Sheets("Metrics_Data").Range("A5").Value = wbk.Sheets("summary").Range("I5").Value
target.Sheets("Metrics_Data").Range("B5").Value = wbk.Sheets("summary").Range("I6").Value + wbk.Sheets("summary").Range("I7")
target.Sheets("Metrics_Data").Range("C5").Value = wbk.Sheets("summary").Range("I8").Value
target.Sheets("Metrics_Data").Range("D5").Value = wbk.Sheets("summary").Range("I9").Value
MsgBox Filename & " has opened"
wbk.Close True
Filename = Dir
Loop
MsgBox "Task complete!"
End Sub
Try this:
Private Sub CommandButton1_Click()
Dim wbk As Workbook, target As Workbook, excelFile As String, path As String, rw As Integer
path = "D:\Macro_Demo\estimation_sheets\"
excelFile = Dir(path & "*.xls")
rw = 5
Set target = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest")
Do While excelFile <> ""
Set wbk = Workbooks.Open(path & excelFile)
With target.Sheets("Metrics_Data")
.Range("A" & rw) = wbk.Sheets("summary").Range("I5")
.Range("B" & rw) = wbk.Sheets("summary").Range("I6") + wbk.Sheets("summary").Range("I7")
.Range("C" & rw) = wbk.Sheets("summary").Range("I8")
.Range("D" & rw) = wbk.Sheets("summary").Range("I9")
End With
wbk.Close True
rw = rw + 1
excelFile = Dir
Loop
MsgBox "Task complete!"
End Sub
You need to find the next available row on your destination sheet, store that in a variable, and write the data relative to that cell. Like this
Private Sub CommandButton1_Click()
Dim shSource As Worksheet, shDest As Worksheet
Dim sFile As String
Dim rNextRow As Range
Const sPATH As String = "D:\Macro_Demo\estimation_sheets\"
'Open the destination workbook
Set shDest = Workbooks.Open("D:\Macro_Demo\Metrics_Macro_dest.xls").Worksheets("Metrics_Data")
sFile = Dir(sPATH & "*.xls")
Do While Len(sFile) > 0
Set shSource = Workbooks.Open(sPATH & sFile).Worksheets("summary")
'start at row 1000 and go up until you find something
'then go down one row
Set rNextRow = shDest.Cells(1000, 1).End(xlUp).Offset(1, 0)
'Write the values relative to rNextRow
With rNextRow
.Value = shSource.Range("I5").Value
.Offset(0, 1).Value = shSource.Range("I6").Value
.Offset(0, 2).Value = shSource.Range("I8").Value
.Offset(0, 3).Value = shSource.Range("I9").Value
End With
'Close the source
shSource.Parent.Close False
sFile = Dir
Loop
MsgBox "Done"
End Sub
I have a source folder that contains many xls files. I want to create a master file - collect all information into one database from all files in the given source.
The following code creates 2 columns in master file and enters 2 values from the given source file (one file):
Sub getData()
Dim XL As Excel.Application
Dim WBK As Excel.Workbook
Dim scrFile As String
Dim myPath As String
myPath = ThisWorkbook.path & "\db\" 'The source folder
scrFile = myPath & "1.xlsx" 'Select first file
' Sheet name in the master file is "Sh"
ThisWorkbook.Sheets("Sh").Range("A1").Value = "Column 1"
ThisWorkbook.Sheets("Sh").Range("B1").Value = "Column 2"
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
ThisWorkbook.Sheets("Sh").Range("A2").Value = WBK.ActiveSheet.Range("A10").Value
ThisWorkbook.Sheets("Sh").Range("B2").Value = WBK.ActiveSheet.Range("C5").Value
WBK.Close False
Set XL = Nothing
Application.ScreenUpdating = True
End Sub
Now I want to loop through all files and save the values from cells "A10" and "C5" from each file in one database, so the loop should select the next row to save new values.
I have an idea how to loop through all files, but don't know how to switch to the next row:
scrFile = Dir(myPath & "*.xlsx")
Do While scrFile <> ""
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
' Here should be the code to save the values of A10 and C5 of the given file
'in the loop in next available row of the master file.
WBK.Close False
Set XL = Nothing
scrFile = Dir
Loop
Any help will be highly appreciated! :)
For simplicity, just use a counter:
scrFile = Dir(myPath & "*.xlsx")
n = 1 ' skip the first row with headers
Do While scrFile <> ""
n = n + 1
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
' save the values of A10 and C5 of the given file in the next row
ThisWorkbook.Sheets("Sh").Range("A" & n).Value = WBK.ActiveSheet.Range("A10").Value
ThisWorkbook.Sheets("Sh").Range("B" & n).Value = WBK.ActiveSheet.Range("C5").Value
WBK.Close False
Set XL = Nothing
scrFile = Dir
Loop
msgbox n & " files imported."
BTW, you don't need to start a second Excel instance (CreateObject("Excel.Application")) just to open a second workbook. This will slow down your code a lot. Just open, read and close it. Address your master workbook not by ThisWorkbook but assign a varible to it:
Dim masterWB As Excel.Workbook
set masterWB = ThisWorkbook
...
masterWB.Sheets("Sh").Range("A" & n).Value = WBK.ActiveSheet.Range("A10").Value
You need to recalculate last row in the loop wtih End() function.
Like this for range .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0)
Or to have an integer .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Row
Give this a try :
Sub getData()
Application.ScreenUpdating = False
Dim XL As Excel.Application, _
WBK As Excel.Workbook, _
MS As Worksheet, _
scrFile As String, _
myPath As String
'Sheet name in the master file is "Sh"
Set MS = ThisWorkbook.Sheets("Sh")
'The source folder
myPath = ThisWorkbook.Path & "\db\"
MS.Range("A1").Value = "Column 1"
MS.Range("B1").Value = "Column 2"
Set XL = CreateObject("Excel.Application")
scrFile = Dir(myPath & "*.xlsx")
Do While scrFile <> ""
Set WBK = XL.Workbooks.Open(scrFile)
' Here should be the code to save the values of A10 and C5 of the given file
'in the loop in next available row of the master file.
With MS
.Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Value = WBK.ActiveSheet.Range("A10").Value
.Range("B" & .Rows.Count).End(xlUp).Offset(1, 0).Value = WBK.ActiveSheet.Range("C5").Value
End With
WBK.Close False
scrFile = Dir
Loop
XL.Quit
Set XL = Nothing
Set MS = Nothing
Set WBK = Nothing
Application.ScreenUpdating = True
End Sub
I actually have a code here that will loop through each file and deposit the code into your main file. You are also able to choose the directory of the target folder.
Sub GatherData()
Dim sFolder As String
Application.ScreenUpdating = True
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder..."
.Show
If .SelectedItems.Count > 0 Then
sFolder = .SelectedItems(1) & "\"
Else
Exit Sub
End If
End With
Call Consolidate(sFolder, ThisWorkbook)
End Sub
Private Sub Consolidate(sFolder As String, wbMaster As Workbook)
Dim wbTarget As Workbook
Dim objFso As Object
Dim objFiles As Object
Dim objSubFolder As Object
Dim objSubFolders As Object
Dim objFile As Object
Dim ary(3) As Variant
Dim lRow As Long
'Set Error Handling
On Error GoTo EarlyExit
'Create objects to enumerate files and folders
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFiles = objFso.GetFolder(strFolder).Files
Set objSubFolders = objFso.GetFolder(strFolder).subFolders
'Loop through each file in the folder
For Each objFile In objFiles
If InStr(1, objFile.Path, ".xls") > 0 Then
Set wbTarget = Workbooks.Open(objFile.Path)
With wbTarget.Worksheets(1)
ary(0) = .Range("B8") 'here you can change the cells you need the data from
ary(1) = .Range("B12")
ary(2) = .Range("B14")
End With
With wbMaster.Worksheets(1)
lRow = .Range("E" & .Rows.Count).End(xlUp).Offset(1, 0).Row 'here you can change the row the data is deposited in
.Range("E" & lRow & ":G" & lRow) = ary
End With
wbTarget.Close savechanges:=False
End If
Next objFile
'Request count of files in subfolders
For Each objSubFolder In objSubFolders
Consolidate objSubFolder.Path, wbMaster
Next objSubFolder
EarlyExit:
'Clean up
On Error Resume Next
Set objFile = Nothing
Set objFiles = Nothing
Set objFso = Nothing
On Error GoTo 0
End Sub