Delimit/text to columns .CSV file before extracting data - vba

I have a code that goes through .xlsx , .xls, and .csv files(many files). But the .csv file data are usually all in column A separated by "|". How can I delimit these files first before looping through them and pulling an extract? It can be complicated because sometimes not only Col A has data but Col B may have a few rows.
EDIT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sub ColumnHeaders()
'includes filling down
'Skips unreadable files
Dim wb As Workbook, fileNames As Object, errCheck As Boolean
Dim wsReport As Excel.Worksheet
Set wsReport = ActiveWorkbook.Sheets("Sheet1") 'Whatever sheet you want to write to
Dim lRow As Long
lRow = 1
' Turn off screen updating and automatic calculation
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
'get user input for files to search
Set fileNames = CreateObject("Scripting.Dictionary")
errCheck = UserInput.FileDialogDictionary(fileNames)
If errCheck Then
Exit Sub
End If
'''
For Each Key In fileNames 'loop through the dictionary
On Error Resume Next
Set wb = Workbooks.Open(fileNames(Key))
If Err.Number <> 0 Then
Set wb = Nothing ' or set a boolean error flag
End If
On Error GoTo 0 ' or your custom error handler
If wb Is Nothing Then
wksSkipped.Cells(wksSkipped.Cells(wksSkipped.Rows.Count, "A").End(xlUp).Row + 1, 1) = fileNames(Key)
Else
Debug.Print "Successfully loaded " & fileNames(Key)
wb.Application.Visible = False 'make it not visible
'--------------------DATA Extraction ----------------------------------------
Dim iIndex As Integer
Dim lCol As Long
Dim lOutputCol As Long
'Loop through the worksheets in the current workbook.
For iIndex = 1 To wb.Worksheets.Count
'Set the current worksheet
Set ws = Application.Worksheets(iIndex)
'List out the workbook and worksheet names
wsReport.Range("A" & lRow).Value = wb.Name
wsReport.Range("B" & lRow).Value = ws.Name
'Start a counter of the columns that we are writing to
lOutputCol = 3
'Loop through the columns.
For lCol = 1 To ws.UsedRange.Columns.Count
'Write the header
wsReport.Range(Col_Letter(lOutputCol) & lRow).Value = ws.Range(Col_Letter(lCol) & "1").Value
'Increment our column counters.
lOutputCol = lOutputCol + 1
Next lCol
'Increment the row we are writing to
lRow = lRow + 1
Next iIndex
'-----------------------Data Extraction END-------------------------------------
wb.Close savechanges:=False 'close the workbook do not save
Set wb = Nothing 'release the object
End If
Next 'End of the fileNames loop
Set fileNames = Nothing
' Reset system settings
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
.Visible = True
End With
End Sub

Two possible approaches.
APPROACH #1
Your code first opens the file as text, then prepends (inserts as the first line) to the file this:
sep=|
Next, your code then opens as CSV in Excel. If your text qualifiers are normal quotes, this will work surprisingly well.
I know that prepending is a little tricky in VBA. If the file is not too big, then you would create a new file with that first line followed by the rest of the original file (e.g. http://www.ozgrid.com/forum/showthread.php?t=163510).
The advantage of this approach is that your VBA doesn't need to do text-to-columns, etc.
APPROACH #2
The VBA loops through all rows and columns to clean up first before performing text-to-columns. As you said, if the delimiter is non-standard, you often end up with values in column B or C or even more so you need "clean up" first by putting them all back into column A.
I used to run my own little macro to do this cleaning up for exactly this reason i.e. "|" as a delimiter.
Later, I discovered that I could insert "sep=|" (e.g. using Notepad++) before opening in Excel.
I wrote a short article on both approaches and offered my code here: https://wildwoollytech.wordpress.com/2015/12/11/combine-excel-cells-into-one/

Related

Macro to loop through all worksheets except the first two and copy a cell and range into another workbook

I have a master workbook that I have that already looks through all the files in a folder. However, one of the tabs needs to look through all the tabs in a different selected workbook "Data". The workbook has roughly 30 worksheets, and I need to loop through each worksheet except "Investments" and "Funds". If it makes it easier these are the first two tabs in the workbook. I then need to copy cell F9 in each worksheet, paste it into a different workbook "Master" cell "C4", go back to the same worksheet in the "data" workbook and copy range "C16:C136" and paste that into cell "E4" of the "master" workbook. Then it would need to loop to the next worksheet in the "data" workbook and continue the loop. For each new worksheet, I need it to paste one row lower in the "master" file. i.e. the second worksheet would paste in "C5" and "E5".
If it makes it easier I can split this up into two macros. And Just paste all the data from the worksheets into a new blank sheet in the data work book and then I can have another one to copy all of that over into the "master" workbook once done.
Thanks in Advance
Sub ImportInformation()
WorksheetLoop
End Sub
Function WorksheetLoop()
Dim wb As Workbook
Dim ws As Worksheet
Dim foundCell As Range
Dim strFind As String
Dim fRow, fCol As Integer
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
' This allows you to use excel functions by typing wf.<function name>
Set wf = WorksheetFunction
'Set the name of your output file, I assume its fixed in the Master File
‘Please note that I am running this out of the master file and I want it all in the Noi tab
Set NOI = ThisWorkbook.Worksheets("NOI")
'Retrieve Target File Path From User
Set FilePicker = Application.FileDialog(msoFileDialogFolderPicker)
‘This only selects a folder, however I would like it to select a SPECIFIC FILE
With FilePicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
' initialize the starting cell for the output file
pasterow = 4
‘I need this to be referring to the file that I choose
For Each ws In wb.Worksheets
If ws.Name <> "Funds" And ws.Name <> "Investments" Then
Next ws
Wb.Worksheets.Range.("F9").Copy
NOI.Range("C" & pasterow).PasteSpecial xlPasteValues, Transpose:=False
'Get find String
strFind = NOI.Range("C2").Value
'Find string in Row 16 of each row of current ACTIVE worksheet
Set foundCell = wb.Worksheets.Range("A16:IT16").Find(strFind, LookIn:=xlValues)
'If match cell is found
If Not foundCell Is Nothing Then
'Get row and column
fRow = foundCell.Row
fCol = foundCell.Column
'Copy data from active data worksheet “data” and copy over 300 columns (15 years).
‘ This is needed to find what specific date to start at. This portion works, I just need it to loop through each worksheet.
wb.Worksheets.active.Range(Cells(fRow + 1, fCol).Address & ":" & Cells(fRow + 1, fCol + 299).Address).Copy
'Paste in NOI tab of mater portfolio
NOI.Range("E" & pasterow).PasteSpecial xlPasteValues, Transpose:=False
wb.Application.CutCopyMode = False
Else
Call MsgBox("Try Again!” vbExclamation, "Finding String")
End If
Next Ws
wb.Close SaveChanges:=False
End Function
Please show us your first attempt. Feel free to put in comments like
' I need this to do XXXX here, but I don't know how
Here are a some hints:
To loop through all sheets in a workbook, use:
For each aSheet in MyWorkbook.Sheets
To skip some specific sheets, say:
If aSheet.Name <> "Investments" And aSheet.Name <> "Funds"
To copy from aSheet to MasterSheet, start by setting the initial destinations:
set rSource = aSheet.range("F9")
set rDestin = MasterSheet.range("C4")
Then in your loop you do the copy:
rDestin.Value = rSource.Value
...and set up the next set of locations
set rSource = rSource.offset(1,0)
set rDestin = rDestin.offset(1,0)
Does that help?
EDIT: Briefly looking at your version, I think this part won't work:
If ws.Name <> "Funds" And ws.Name <> "Investments" Then
Next ws
Don't you want to delete that last line?
EDIT 2: You use this a lot:
wb.Worksheets.<something>
But that does not refer to a specific worksheet. You want to use "ws", like this:
ws.Range("F9")
BIG EDIT:
Step through this version carefully and see how it works:
Sub ImportInformation()
WorksheetLoop
End Sub
Function WorksheetLoop()
Dim wb As Workbook
Dim ws As Worksheet
Dim foundCell As Range
Dim strFind As String
Dim fRow, fCol As Integer
'*** Adding Dims:
Dim wf, FilePicker
Dim NOI As Worksheet
Dim myPath As String
Dim PasteRow As Long
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
' This allows you to use excel functions by typing wf.<function name>
Set wf = WorksheetFunction
'Set the name of your output file, I assume its fixed in the Master File
'Please note that I am running this out of the master file and I want it all in the Noi tab
Set NOI = ThisWorkbook.Worksheets("NOI")
'Retrieve Target File Path From User
' Set FilePicker = Application.FileDialog(msoFileDialogFolderPicker)
'This only selects a folder, however I would like it to select a SPECIFIC FILE
' With FilePicker
' .Title = "Select A Target Folder"
' .AllowMultiSelect = False
' If .Show <> -1 Then GoTo NextCode
' myPath = .SelectedItems(1) & "\"
' End With
Dim WorkbookName As Variant
' This runs the "Open" dialog box for user to choose a file
WorkbookName = Application.GetOpenFilename( _
FileFilter:="Excel Workbooks, *.xl*", Title:="Open Workbook")
Set wb = Workbooks.Open(WorkbookName)
' initialize the starting cell for the output file
PasteRow = 4
'I need this to be referring to the file that I choose
For Each ws In wb.Worksheets
If ws.Name <> "Funds" And ws.Name <> "Investments" Then
' **** Leave this out: Next ws
ws.Range("F9").Copy '<--- You mean this, not wb.Worksheets.Range.("F9").Copy
NOI.Range("C" & PasteRow).PasteSpecial xlPasteValues, Transpose:=False
'Get find String
strFind = NOI.Range("C2").Value
'Find string in Row 16 of each row of current ACTIVE worksheet
Set foundCell = ws.Range("A16:IT16").Find(strFind, LookIn:=xlValues)
'If match cell is found
If Not foundCell Is Nothing Then
'Get row and column
fRow = foundCell.Row
fCol = foundCell.Column
'Copy data from active data worksheet “data” and copy over 300 columns (15 years).
' This is needed to find what specific date to start at. This portion works, I just need it to loop through each worksheet.
ws.Range(Cells(fRow + 1, fCol).Address & ":" & Cells(fRow + 1, fCol + 299).Address).Copy
'Paste in NOI tab of mater portfolio
NOI.Range("E" & PasteRow).PasteSpecial xlPasteValues, Transpose:=False
'*** Move PasteRow down by one
PasteRow = PasteRow + 1
wb.Application.CutCopyMode = False
Else
Call MsgBox("Try Again!", vbExclamation, "Finding String")
End If
End If
Next ws
wb.Close SaveChanges:=False
End Function

Excel - Open Workbooks given names

I have the below code.
Very simply it asks the user to select multiple excel workbooks and then will copy and paste data from those workbooks to the current work book.
1.
I would like to add the functionality, whereby instead of the user selecting the excel workbooks. The excel workbooks will be selected in that their names are listed on the current excel sheet.
For example - Select excel workbooks in specified folder whose names are listed in A1:A5.
I would like to perform automatic processing on the data before it is copied into the current work book.
For example if workbook name = 100.xlsx then multiply selection by 15.
See my current code
Sub SUM_BalanceSheet()
Application.ScreenUpdating = False
'FileNames is array of file names, file is for loop, wb is for the open file within loop
'PasteSheet is the sheet where we'll paste all this information
'lastCol will find the last column of PasteSheet, where we want to paste our values
Dim FileNames
Dim file
Dim wb As Workbook
Dim PasteSheet As Worksheet
Dim lastCol As Long
Set PasteSheet = ActiveSheet
lastCol = PasteSheet.Cells(1, Columns.Count).End(xlToLeft).Column
'Build the array of FileNames to pull data from
FileNames = Application.GetOpenFilename(filefilter:="Excel Files (*.xlsx), *.xlsx", MultiSelect:=True)
'If user clicks cancel, exit sub rather than throw an error
If Not IsArray(FileNames) Then Exit Sub
'Loop through selected files, put file name in row 1, paste P18:P22 as values
'below each file's filename. Paste in successive columns
For Each file In FileNames
Set wb = Workbooks.Open(file, UpdateLinks:=0)
PasteSheet.Cells(1, lastCol + 1) = wb.Name
wb.Sheets("Page 1").Range("L14:L98").Copy
PasteSheet.Cells(2, lastCol + 1).PasteSpecial Paste:=xlPasteValues
wb.Close SaveChanges:=False
lastCol = lastCol + 1
Next
'If it was a blank sheet then data will start pasting in column B, and we don't
'want a blank column A, so delete it if it's blank
If Cells(1, 1) = "" Then Cells(1, 1).EntireColumn.Delete shift:=xlLeft
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
This is a frame that needs fine-tuning, but you can get the idea:
Dim i&, wbName$
Dim rng As Excel.Range
Dim wb, wb1 As Excel.Workbook
Set wb = Application.ThisWorkbook
Set rng = wb.Sheets("Sheet1").Range("A1")
For i = 0 To 14
wbName = CStr(rng.Offset(i, 0).Value)
On Error Resume Next 'Disable error handling. We will check whether wb is nothing later
wb1 = Application.Workbooks.Open(wbName, False)
On Error GoTo ErrorHandler
If Not IsNothing(wb1) Then
'Copy-paste here
If wb1.Name = "100" Then 'any condition(s)
'Multiply, divide, or whatever
End If
End If
Next
ErrorHandler:
MsgBox "Error " & Err.Description
'Add additional error handling
Try not to use ActiveSheet and ActiveWorkbook without absolute need. Use ThisWorkbook, dedicated Workbook object, and named sheet Workbook.Sheets("Name") or Workbook.Sheets(index) instead.
Alternatively instead of disabling error checking you can do it and fail if a file is missing.

Merge Multiple Workbooks that have multiple worksheets using VBA

I keep having this issue of VBA either not having an object for the new sheet I want to merge, or having the subscript out of range issue come up. None of the things I tried ended up working.
Private Sub MergeButton_Click()
Dim filename As Variant
Dim wb As Workbook
Dim s As Sheet1
Dim thisSheet As Sheet1
Dim lastUsedRow As Range
Dim j As Integer
On Error GoTo ErrMsg
Application.ScreenUpdating = False
Set thisSheet = ThisWorkbook.ActiveSheet
MsgBox "Reached method"
'j is for the sheet number which needs to be created in 2,3,5,12,16
For Each Sheet In ActiveWorkbook.Sheets
For i = 0 To FilesListBox.ListCount - 1
filename = FilesListBox.List(i, 0)
'Open the spreadsheet in ReadOnly mode
Set wb = Application.Workbooks.Open(filename, ReadOnly:=True)
'Copy the used range (i.e. cells with data) from the opened spreadsheet
If FirstRowHeadersCheckBox.Value And i > 0 Then 'Only include headers from the first spreadsheet
Dim mr As Integer
mr = wb.ActiveSheet.UsedRange.Rows.Count
wb.ActiveSheet.UsedRange.Offset(3, 0).Resize(mr - 3).Copy
Else
wb.ActiveSheet.UsedRange.Copy
End If
'thisSheet = ThisWorkbook.Worksheets(SheetCurr)
'Paste after the last used cell in the master spreadsheet
If Application.Version < "12.0" Then 'Excel 2007 introduced more rows
Set lastUsedRow = thisSheet.Range("A65536").End(xlUp)
Else
Set lastUsedRow = thisSheet.Range("A1048576").End(xlUp)
End If
'Only offset by 1 if there are current rows with data in them
If thisSheet.UsedRange.Rows.Count > 1 Or Application.CountA(thisSheet.Rows(1)) Then
Set lastUsedRow = lastUsedRow.Offset(1, 0)
End If
lastUsedRow.PasteSpecial
Application.CutCopyMode = False
Next i
This is where I try to add an extra loop that copies the next sheet (which is Sheet12) but it comes up with the Subscript our of range error.
Sheets("Sheet3").Activate
Sheet.Copy After:=ThisWorkbook.Sheets
Next Sheet
It will then move to the next sheet to perform the loop again.
ThisWorkbook.Save
Set wb = Nothing
#If Mac Then
'Do nothing. Closing workbooks fails on Mac for some reason
#Else
'Close the workbooks except this one
Dim file As String
For i = 0 To FilesListBox.ListCount - 1
file = FilesListBox.List(i, 0)
file = Right(file, Len(file) - InStrRev(file, Application.PathSeparator, , 1))
Workbooks(file).Close SaveChanges:=False
Next i
#End If
Application.ScreenUpdating = True
Unload Me
ErrMsg:
If Err.Number <> 0 Then
MsgBox "There was an error. Please try again. [" & Err.Description & "]"
End If
End Sub
Any help an this would be great
Your source code is very confusing and I believe you're stumbling because the ActiveWorkbook and ActiveSheet change each time you open a new workbook. It's also not clear why you're copying/merging the data from each worksheet in every opened workbook and then copying Sheet3. You will help yourself by more clearly defining what and where your data is and how you're moving it around.
As an example (that may not solve your problem, because your problem is not clear), look at the code below to see how you can keep the sources and destinations straight within your loops. Modify this example as much as you need in order to match your exact situation.
Sub Merge()
'--- assumes that each sheet in your destination workbook matches a sheet
' in each of the source workbooks, then copies the data from each source
' sheet and merges/appends that source data to the bottom of each
' destination sheet
Dim destWB As Workbook
Dim srcWB As Workbook
Dim destSH As Worksheet
Dim srcSH As Worksheet
Dim srcRange As Range
Dim i As Long
Application.ScreenUpdating = False
Set destWB = ThisWorkbook
For i = 0 To FileListBox.ListCount - 1
Set srcWB = Workbooks.Open(CStr(FileListBox(i, 0)), ReadOnly:=True)
For Each destSH In destWB.Sheets
Set srcSH = srcWB.Sheets(destSH.Name) 'target the same named worksheet
lastdestrow = destSH.Range("A").End(xlUp)
srcSH.UsedRange.Copy destSH.Range(Cells(lastdestrow, 1))
Next destSH
srcWB.Close
Next i
Application.ScreenUpdating = True
End Sub

Trying to iterate through some workbooks from a list of workbooks, getting out of range errors

I have a problem. I'm guessing its easier to first write the code, and then explain it so here goes:
Sub Test()
Dim myHeadings() As String
Dim i As Long
Dim path As String
Dim pathtwo As String
Dim currentWb As Workbook
Dim openWb As Workbook
Dim openWs As Worksheet
Set currentWb = ActiveWorkbook
path = "C:\pathto\"
pfile = Split("File1,File2,File3", ",")
myHeadings = Split("Januari,Februari,Mars,April,Maj,Juni,Juli,Augusti,September,Oktober,November,December", ",")
For j = 0 To UBound(pfile)
pathtwo = path & pfile(j) & ".xlsx"
i = 0
If IsFile(pathtwo) = True Then
For i = 0 To UBound(myHeadings)
Set openWb = Workbooks.Open(pathtwo)
Set openWs = openWb.Sheets(myHeadings(i))
If openWs.Range("C34") = 0 Then
currentWb.Sheets("Indata").Cells(70, i + 27 + 12*j.Value = ""
Else
currentWb.Sheets("Indata").Cells(70, i + 27 + 12*j).Value = openWs.Range("C34")
End If
Next i
End if
Workbooks(openWb.Name).Close
Next j
End sub
What I want to pick a file from the pfile list, iterate through all its sheets defined in myHeadings and deduct the value at C34 (in reality there are plenty more values deducted, but to keep it short). After this I want to Close the file, go to the next file and do the same thing until all the Three files (again, in reality there are more, which some of them does not exist yet).
The function "IsFile" is
Function IsFile(fName As String) As Boolean
'Returns TRUE if the provided name points to an existing file.
'Returns FALSE if not existing, or if it's a folder
On Error Resume Next
IsFile = ((GetAttr(fName) And vbDirectory) <> vbDirectory)
End Function
written by iDevlop at stackoverflow, in this thread: VBA check if file exists
The reason why I have
currentWb.Sheets("Indata").Cells(70, i + 27 + 12*j).Value = openWs.Range("C34")
is because I want to start to write my data into currentWb at AA70 (Row 70, column 27). j*12 is because it is "periodic" depending on which file it is (the file file1 corresponds to 2015, file2 to 2016 etc), and hence in my summary I have it month and yearwise.
The problem arises though when I run this macro, at the first file at the sheet Mars I get out of range, but Before I added the iteration of files, there was not any subscript out of range at the first file. Is there anyone who can see how this can be?
Please note that indentation and so on may be somewhat off as I copied this from a much larger file with many rows in between with irrelevant code.
This isnt the right answer for your specific question but this is how I have done something similar and might help you to see how i did it. Basically what this is doing is opening up a CSV and copying the entire sheet and pasting it into a workbook. I was consolidating like 20 CSV dumps into 1 workbook to make it easier to dig through the stuff.
Regarding Dir()
You can invoke Dir with 2 arguments or with no arguments. You initialize it with 2 arguments the pathway and the attributes (which is optional). The 2nd time I am calling Dir in this sub it is without any arguments. What this does is fetch the subsequent files.
Sub Add_Sheets()
Dim ws As Worksheet
Dim PasteSheet As Worksheet
Dim wb As Workbook
Set wb = Application.Workbooks.Open("C:\Users\Desktop\CSV\All.xlsx") 'Location of where you want the workbook to be
StrFile = Dir("c:\Users\Desktop\CSV\*.csv") 'Dir of where all the CSVs were.
Do While Len(StrFile) > 0
Debug.Print StrFile
Application.Workbooks.Open ("c:\Users\Desktop\CSV\" & StrFile)
Set ws = ActiveSheet
ws.Range("A1:C" & rows.Count).Select 'Selecting Specific content on the worksheet
Selection.Copy
wb.Activate
wb.Worksheets.add(After:=Worksheets(Worksheets.Count)).name = StrFile 'Setting the sheet name to the name of the CSV file
Range("A1").PasteSpecial Paste:=xlPasteValues
StrFile = Dir
Loop
End Sub

Manipulate/copy .CSV data, without opening the file?

I'm trying to optimize some code that takes some test data stored in CSV files does some analysis and copies their data into an excel sheet. This code is often run on hundreds of tests at a time, and its taking about 4.5 seconds per test so it can take hours to complete at times.
I looked up some optimization techniques and cut it down by about .25 seconds per test but I think the bulk of the time is being taken up by excel having to "open" the individual files before it can do anything with them. Is there a way to do this more efficiently?
I am open to answers that involve using another language to compile the files into one big file if that would make things quicker.
I would open them as text rather than workbooks:
Sub ReadCSV()
Dim MyString As String
Open "C:\path\text.csv" For Input As #1 ' Open file for input.
Do While Not EOF(1) ' Loop until end of file.
Line Input #1, MyString ' Read a line into variable
Debug.Print MyString ' Print data to the Immediate window.
Loop
Close #1 ' Close file.
End Sub
This will be much faster than opening as a workbook
I have this function working greate handling lot of CSV files. You need to indicate in cell "D11" the name of folder containing all the CSV files and will combine them into one single file. I handle over 200 files and make it quick. Hope it helps.
Sub CombineAllFilesInADirectory()
Dim Path As String 'string variable to hold the path to look through
Dim FileName As String 'temporary filename string variable
Dim tWB As Workbook 'temporary workbook (each in directory)
Dim tWS As Worksheet 'temporary worksheet variable
Dim aWS As Worksheet 'active sheet in master workbook
Dim RowCount As Long 'Rows used on master sheet
Dim uRange As Range 'usedrange for each temporary sheet
Dim mWB_comb As Workbook 'master workbook exclusivo de esta funcion
Path = Sheets("CombineFiles").Range("D11").Value
Application.EnableEvents = False 'turn off events
Application.ScreenUpdating = False 'turn off screen updating
Set mWB_comb = Workbooks.Add(1) 'create a new one-worksheet workbook
Set aWS = mWB_comb.ActiveSheet 'set active sheet variable to only sheet in mWB
If Right(Path, 1) <> Application.PathSeparator Then 'if path doesnt end in "\"
Path = Path & Application.PathSeparator 'add "\"
End If
FileName = Dir(Path & "*.csv", vbNormal) 'set first file's name to filename variable
Application.StatusBar = "reading files, please wait."
Do Until FileName = "" 'loop until all files have been parsed
If Path <> ThisWorkbook.Path Or FileName <> ThisWorkbook.Name Then
Set tWB = Workbooks.Open(FileName:=Path & FileName) 'open file, set to tWB variable
For Each tWS In tWB.Worksheets 'loop through each sheet
Set uRange = tWS.Range("A4", tWS.Cells(tWS.UsedRange.Row + tWS.UsedRange.Rows.count - 1, _
tWS.UsedRange.Column + tWS.UsedRange.Columns.count - 1)) 'set used range
If RowCount + uRange.Rows.count > 65536 Then 'if the used range wont fit on the sheet
aWS.Columns.AutoFit 'autofit mostly-used worksheet's columns
Set aWS = mWB_comb.Sheets.Add(After:=aWS) 'add a new sheet that will accommodate data
RowCount = 0 'reset RowCount variable
End If
If RowCount = 0 Then 'if working with a new sheet
aWS.Range("A1", aWS.Cells(3, uRange.Columns.count)).Value = tWS.Range("A1", _
tWS.Cells(3, uRange.Columns.count)).Value 'copy headers from tWS
RowCount = 3 'add one to rowcount
End If
aWS.Range("A" & RowCount + 1).Resize(uRange.Rows.count, _
uRange.Columns.count).Value = uRange.Value 'move data from temp sheet to data sheet
RowCount = RowCount + uRange.Rows.count 'increase rowcount accordingly
Next 'tWS
tWB.Close False 'close temporary workbook without saving
End If
FileName = Dir() 'set next file's name to FileName variable
Loop
Application.StatusBar = "Ready"
mWB_comb.Sheets(1).Select 'select first data sheet on master workbook
Application.EnableEvents = True 're-enable events
Application.ScreenUpdating = True 'turn screen updating back on
'Clear memory of the object variables
Set tWB = Nothing
Set tWS = Nothing
Set mWB_comb = Nothing
Set aWS = Nothing
Set uRange = Nothing
End Sub