Loop through multiple workbooks not working - excel

I have a code that loops through all the workbooks in a user selected folder and fetch the column names from all the sheets. Note that there may be multiple column names in a single sheet tab. So, the code searches in first column that contains "Product" in it and copies the entire row until last non empty column and pastes them in ThisWorkbook.Sheets("Column Names").
This code opens the workbook, searches for the text "Product" in each sheet tab, copies the column names and closes the workbook without saving.
I am using the below code to fetch the column names. It works completely fine for only 1 workbook and when the code opens the second workbook, it throws error in the line highlighted.
Anybody please help me to identify where I have done wrong.
Option Explicit
Dim i, ShtCnt As Integer
Dim ws, CurSht As Excel.Worksheet
Dim cell As Range
Dim EmpCell As Integer
Dim NonEmpCell As Integer
Dim lRow As Long
Dim ThiswblRow, ThiswblRow2 As Long
Dim lCol As Long
Dim FldrPicker As FileDialog
Dim wb As Workbook
Dim myExtension, filepath, filepathSrc, filepathDest, fileSaveName, filename, Template, TempLocPath, ShtNameRaw, ShtNameTemp, SlrName As String
'Step 1
Public Sub LoopAllExcelFilesInAFolder()
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
filepath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
filepath = filepath
If filepath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls*"
'Target Path with Ending Extention
TempLocPath = Dir(filepath & myExtension)
'Loop through each Excel file in folder
Do While TempLocPath <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(filename:=filepath & TempLocPath)
filename = ActiveWorkbook.Name
Workbooks(filename).Activate
'Call Find_Product_in_each_sheet_loop
For ShtCnt = 1 To ActiveWorkbook.Worksheets.Count
'On Error Resume Next
Set ws = ActiveWorkbook.Worksheets(ShtCnt)
lRow = ws.Range("A100000").End(xlUp).Row --> Getting error in this line
'Call Find_Product(ws)
For i = 1 To lRow
lRow = ws.Range("A100000").End(xlUp).Row
If InStr(ws.Cells(i, 1), "Product") <> 0 Or InStr(ws.Cells(i, 1), "Model") <> 0 Then
ThiswblRow = ThisWorkbook.Sheets("Column Names").Range("B100000").End(xlUp).Row + 1
'Workbook Name
ThisWorkbook.Sheets("Column names").Range("B" & ThiswblRow) = ActiveWorkbook.Name
ws.Activate
'Sheet Name
ThisWorkbook.Sheets("Column names").Range("C" & ThiswblRow) = ActiveSheet.Name
lCol = ws.Cells(i, Columns.Count).End(xlToLeft).Column
ws.Range(Cells(i, 1), Cells(i, lCol)).Select
'Column Names
ws.Range(Cells(i, 1), Cells(i, lCol)).Copy ThisWorkbook.Sheets("Column Names").Range("D" & ThiswblRow)
End If
Next i
ThiswblRow = Empty
lRow = Empty
'Next j
Next ShtCnt
ThiswblRow = ThisWorkbook.Sheets("Column Names").Range("A100000").End(xlUp).Row + 1
ThiswblRow2 = ThisWorkbook.Sheets("Column Names").Range("B100000").End(xlUp).Row
'Partner Name
Workbooks(filename).Sheets("Request Form").Activate
Workbooks(filename).Sheets("Request Form").Columns(1).Select
With Selection
.Find(What:="Partner Name", After:=ActiveCell, LookIn:= _
xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:= _
xlNext, MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Offset(0, 1).Copy ThisWorkbook.Sheets("Column Names").Range("A" & ThiswblRow & ":A" & ThiswblRow2)
End With
lRow = Empty
ThiswblRow = Empty
ThiswblRow2 = Empty
'Close Workbook without saving
wb.Close SaveChanges:=False
'Get next file name
TempLocPath = Dir
Loop
ThisWorkbook.Sheets("Column Names").UsedRange.WrapText = False
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
MsgBox ("Done")
End Sub

Most likely you have an Excel file in the old format (*.xls). In the old format, sheets had only 64k rows, so using something like A100000 fails because there is simply no such cell.
Don't use such magic numbers. The total number of rows in a sheet is ws.rows.count, and
that works no matter how many rows a sheet has. Change the line to
lRow = ws.Cells(ws.rows.count, 1).End(xlUp).Row
or, if you prefer
lRow = ws.Range('A' & ws.rows.count).End(xlUp).Row
P.S.: You should indent your code, the way you presented it is nearly unreadable. I was about to give because it is nearly impossible to tell where loops start and end.

Related

Continue pasting data in successive worksheets when the current workhseet's row limit exceeds 1,048,576

The macro I wrote copies some data from several .dat files to a specific worksheet. It works fine as long as the number of records don't exceed the maximum 1,048,576 rows in my worksheet(excel 2016). How to modify the code to continue pasting data from the source file to the successive worksheets when the max row of 1,048,576 is exceeded?
I first tried to paste data from each source file in individual worksheets in my workbook. But that would create so many sheets in the workbook which I don't want. I want my data to be in minimum number of worksheets as possible.
Sub KLT()
Dim StartTime As Double
Dim MinutesElapsed As String
Dim wbA As Workbook, wbB As Workbook
Dim button_click As VbMsgBoxResult
Dim myPath As String, myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim count As Integer
Dim LIST As Integer
Dim xWs As Worksheet
Dim sh As Worksheet
Dim xcount As Integer
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.DisplayAlerts = False
On Error Resume Next
'Remember time when macro starts
StartTime = Timer
'Deleting the "Start" sheet from previous macro run
For Each xWs In Application.Worksheets
If xWs.Name = "Start" Then
xWs.Delete
End If
Next
'Adding a new Sheet called "Start"
Worksheets.Add(After:=Worksheets(Worksheets.count)).Name = "Start"
Set wbA = ThisWorkbook
Set sh = wbA.Sheets("Start")
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.DAT*" 'my data is in .dat files
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension) 'Storing the actual raw file name
'Loop through each Excel file in folder
Execute:
Do While myFile <> ""
'Set variable equal to opened workbook
Set wbB = Workbooks.Open(Filename:=myPath & myFile)
'The source file range might be a continuation of a previous file, so ensuring the correct range is identified always
If wbB.ActiveSheet.Range("A1").Value = "Continuation of previous file." Then Range("A1").EntireRow.Delete
'Filtering data set and choosing data below headers
With wbB.ActiveSheet
.AutoFilterMode = False
With Range("A1", Range("A" & Rows.count).End(xlUp)) 'I am only interested in the data below the header
.AutoFilter 1, "*Cycle*"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
.AutoFilter 1, "*Profile*"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
.AutoFilterMode = False
End With
'Choosing the desired range to be copied
Set Rng = Union _
(Range("A2", Range("A2").End(xlDown)), _
Range("D2", Range("D2").End(xlDown)), _
Range("E2", Range("E2").End(xlDown)), _
Range("AX2", Range("AX2").End(xlDown)))
'Rng.Select
'''Copying relevant information from the source file & pasting in the Start worksheet'''
lr = sh.Range("A" & Rows.count).End(xlUp).Row + 1
Rng.Copy sh.Range("A" & lr)
'Keeping the count of how many files have been worked on
If InStr(1, ActiveSheet.Name, "LifeCyc") > 0 Then xcount = xcount + 1
'Debug.Print xcount
''''''''***********''''''''
'Close Workbook
wbB.Close 'SaveChanges:=True
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Creating the headers in my report sheet
With sh
.Range("A1").Value = "Date"
.Range("B1").Value = "CumSec"
.Range("C1").Value = "LifeCycleNo"
.Range("D1").Value = "dT"
End With
'Formatting the headers
With sh.Range("A1:D1")
.Interior.Color = rgbBlue
.LineStyle = xlContinuous
.Borders.Color = rgbBlack
.HorizontalAlignment = xlCenter
.Font.Bold = True
.Font.Color = rgbWhite
End With
'Formatting the actual dataset
With sh.Range("A2:D2", Range("A2:D2").End(xlDown))
.LineStyle = xlContinuous
.Borders.Color = rgbBlack
End With
Columns("A:D").AutoFit
'Determine how long the code took to run
MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss")
'Displaying a message on the screen after completion of the task
MsgBox "This code ran successfully in " & MinutesElapsed & " minutes " & "Total Raw Files Processed: " & CStr(xcount), vbInformation
'Reset Macro Optimization Settings
ResetSettings:
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = False
Application.AutomationSecurity = lSecurity
End Sub
Expected outcome is to continue pasting data in successive sheets whenever the current worksheet's row number exceeds the max limit
I am not convinced that it is a good idea to let Excel handle such an amount of data, and I am not sure how you want to deal with more than one sheet having data...
Remove On Error Resume Next. It will hide all errors and you will never recognize that your code had a problem.
Set your wbA-variable at the beginning and work with that, not with then Application.Worksheets object.
Introduce a sheet-counter variable.
Before copying the Range, check if you have enough space left, else create the next sheet.
Do the formatting for all sheets.
Code could look like this (untested, may contain syntax errors)
const SHEETNAME = "Start"
Set wbA = ThisWorkbook
For Each xWs In wbA.Worksheets
If xWs.Name like SHEETNAME & "*" Then
xWs.Delete
End If
Next xWs
dim sheetCount as Long
sheetCount = 1
set sh = wbA.Worksheets.Add(After:=wbA.Worksheets(wbA.Worksheets.count))
sh.Name = SHEETNAME & sheetCount
(...)
lr = sh.Range("A" & Rows.count).End(xlUp).row + 1
If lr + rng.rows.count > sh.Rows.count then
' Not enough space left, add new sheet.
sheetCount = sheetCount + 1
set sh = wbA.Worksheets.Add(After:=sh)
sh.Name = SHEETNAME & sheetCount
lr = 1
End if
rng.Copy sh.Range("A" & lr)
(...)
' Format all data sheets.
For Each xWs In wbA.Worksheets
with xWs
If .Name like SHEETNAME & "*" Then
.Range("A1").Value = "Date"
(...)
' Create a table
lr = .Range("A" & Rows.count).End(xlUp).row
.ListObjects.Add(xlSrcRange, .Range("$A$1:$D$" & lr), , xlYes).Name = "Table_" & .Name
End If
End With
Next xWs

Macro to run through folder, returns subscript out of range error

Setup - I have a macro that's in an excel file, when I click a button it will 1) go to a folder 2) Run the code for all xlsx files.
Problem - I tested parts of the code and it works but when I do the entire thing it doesnt. Debugging highlights a section which I will show shortly.
Sub CommandButton1_Click()
'PURPOSE: To loop through all Excel files in a user specified folder and perform a set task on them
'SOURCE: www.TheSpreadsheetGuru.com
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xlsx*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Ensure Workbook has opened before moving on to next line of code
DoEvents
'Change First Worksheet's Background Fill Blue
'This code below gave us the first column but if clicked twice we have a problem'
ActiveSheet.Columns("A").Insert Shift:=xlToRight
ActiveSheet.Columns("A").Insert Shift:=xlToLeft
'Added the title Source 2 to A1'
Range("A1").Value = "XX"
Range("B1").Value = "XX"
'Perform the Find/Replace All'
Columns("I").Replace What:="XX", _
Replacement:="XX", _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
MatchCase:=False, _
SearchFormat:=False, _
ReplaceFormat:=False
'Solution to the columns A and B
**Dim arrData As Variant, LastRow As Long, i As Long, ws As Worksheet
Set ws = ThisWorkbook.Sheets("newreport") 'change the name of the sheet to the one you are doing the code**
With ws
LastRow = .Cells(.Rows.Count, 3).End(xlUp).Row
arrData = .Range("A2", .Cells(LastRow, "C")).Value
For i = 1 To UBound(arrData)
'Save and Close Workbook
wb.Close SaveChanges:=True
'Ensure Workbook has closed before moving on to next line of code
DoEvents
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
There's one line of code that is the problem,
**Dim arrData As Variant, LastRow As Long, i As Long, ws As Worksheet
Set ws = ThisWorkbook.Sheets("newreport")
How can I get through this problem?
I think I need to rewrite this code
Dim arrData As Variant, LastRow As Long, i As Long, ws As Worksheet
Set ws = ThisWorkbook.Sheets("report1538393886588") 'change the name of the sheet to the one you are doing the code
With ws
LastRow = .Cells(.Rows.Count, 3).End(xlUp).Row
arrData = .Range("A2", .Cells(LastRow, "C")).Value
For i = 1 To UBound(arrData)
If arrData(i, 3) Like "XXX*" Then
arrData(i, 1) = "XX XXX"
Else
arrData(i, 1) = "XXX XXX"
End If
If arrData(i, 3) Like "CSI*" Or arrData(i, 3) = vbNullString Then
arrData(i, 2) = vbNullString
Else
arrData(i, 2) = Right(arrData(i, 3), Len(arrData(i, 3)) - 12)
End If
Next i
.Range("A2", .Cells(LastRow, "C")).Value = arrData
End With
For Each cell In Range("B2", Range("B605536").End(xlUp))
If Not IsEmpty(cell) Then
cell.Value = Right(cell, Len(cell) - 2)
End If
Next cell

Copy and paste data from multiple workbooks last row to a worksheet in another Workbook

The code I've tweaked from another similar post, copies Row 3 to the last row which contains data from 'Sheet1' from all the workbooks in a folder into the 'SH Dealing yyyy.xlsx' 'DealSlips' sheet (adding to the rows here as it sweeps down through the workbooks in the folder). However, it only copies the last row which has data in Column A. In the last row there may be data just in Column J or Column Z for example and it doesn't see these and they are not copied? I'm new to coding and have been pretty much guessing for a couple of hours what needs changing in the code!
Sub LoopAllExcelFilesInFolder()
'PURPOSE: To loop through all Excel files in a user specified folder and perform a set task on them
'SOURCE: www.TheSpreadsheetGuru.com
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim lRow As Long
Dim ws2 As Worksheet
Dim y As Workbook
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Z:\2016\Deal slips ordered mmddyy\"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
Set y = Workbooks.Open("Z:\2016\Report\SH Dealing yyyy.xlsx")
Set ws2 = y.Sheets("DealSlips")
'Loop through each Excel file in folder
Do While myFile <> ""
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Copy data on "Sheet1" sheet to "DealSlips" Sheet in other workbook
With wb.Sheets("Sheet1")
lRow = .Range("A" & Rows.Count).End(xlUp).Row
' lastRow = Sheets("Sheet1").Range("J" & Rows.Count).End(xlUp).Row
.Range("A3:Z" & lRow).Copy ws2.Range("A" & Rows.Count).End(xlUp)(2)
End With
wb.Close SaveChanges:=True
'Get next file name
myFile = Dir
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
You can get your desired result by changing the following line:
lRow = .Range("A" & Rows.Count).End(xlUp).Row
With:
lRow = .UsedRange.Rows.Count
Your original code will count the number of rows on a specific column, in your case Column A, whereas the one using UsedRange will look at the last row on your Sheet including cells that contain formatting only.
UPDATE:
Another way to find the last row without counting the cells with formatting would be as below:
Dim lRow As Long, lRow2 As Long
lRow = wb.Sheets("Sheet1").Cells.Find(What:="*", _
After:=wb.Sheets("Sheet1").Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
wb.Sheets("Sheet1").Range("A3:Z" & lRow).Copy
lRow2 = ws2.Cells.Find(What:="*", _
After:=ws2.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
ws2.Range("A" & lRow2).PasteSpecial xlPasteAll
UPDATE 2:
After looking at your code a little close I realized that the lRow2 was throwing an error because the Sheet was actually blank, so I've added a line of code to add a "Header" to cell A1, so that it can calculate the last row appropriately, also I don't understand how you get the "Correct" result manually when I did it I got many more rows than you, but please check the code below, it worked for me (I think), I also moved the workbook with code (i.e. Book1.xlsm) outside the folder you are looping through and added an If statement to exclude the "SH Dealing yyyy.xlsx" workbook from the loop :
Sub LoopAllExcelFilesInFolder()
Dim wb As Workbook, y As Workbook
Dim myPath As String, myFile As String, myExtension As String
Dim FldrPicker As FileDialog
Dim lRow As Long, lRow2 As Long
Dim ws2 As Worksheet
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
'Retrieve Target Folder Path From User
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Z:\2016\Deal slips ordered mmddyy\"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xls*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
Set y = Workbooks.Open("Z:\2016\Report\SH Dealing yyyy.xlsx")
'amen
Set ws2 = y.Sheets("DealSlips")
'Loop through each Excel file in folder
Do While myFile <> ""
If Left(myFile, 2) <> "SH" Then
'Set variable equal to opened workbook
Set wb = Workbooks.Open(Filename:=myPath & myFile)
'Copy data on "Sheet1" sheet to "DealSlips" Sheet in other workbook
lRow = wb.Sheets("Sheet1").Cells.Find(What:="*", _
After:=wb.Sheets("Sheet1").Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row ' + 1
y.Sheets("DealSlips").Range("A1").Value = "Header"
lRow2 = y.Sheets("DealSlips").Cells.Find(What:="*", _
After:=y.Sheets("DealSlips").Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row + 1
wb.Sheets("Sheet1").Range("A3:Z" & lRow).Copy ws2.Range("A" & lRow2)
wb.Close SaveChanges:=True
'Get next file name
myFile = Dir
Else
myFile = ""
End If
Loop
'Message Box when tasks are completed
MsgBox "Task Complete!"
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

What other ways can I reduce the memory usage in VBA? 32 bit Excel

I was really hoping I could figure this out but haven't had any luck. The following VBA allows users to import data from a separate file and determine unique variables to be analyzed, initiated by a single command button. The issue occurs as the final sub is called (filtering for unique variables). I have set .ScreenUpdating = false and set variables back to null after use. As for the sheets in the workbook, they currently do not contain data or formulas but will need to in order to analyze the data further.
Any help in identifying heavy memory usage would be appreciated.
64 bit is unfortunately not an option either
Located in Module1:
Global PathAndFile As String
Global FileName As String
Sub SelectFile()
Application.ScreenUpdating = False
Dim fd As FileDialog
Dim InDir As String
Dim wb As Workbook
InDir = CurDir() 'Save current directory
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.InitialFileName = CurDir & "\" 'Startup folder
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "All Excel Files", "*.csv" 'Display csv files only
If .Show = False Then
MsgBox "User canceled without selecting."
ChDir (InDir) 'Change back to Initial directory if user cancels
Exit Sub
End If
'contains the path and filename of selected file
PathAndFile = .SelectedItems(1)
End With
'contains the filename (without the path)
FileName = Right(PathAndFile, Len(PathAndFile) - _
InStrRev(PathAndFile, "\"))
'Clear storage sheet
ThisWorkbook.Worksheets("DataTransferred").Cells.Clear
Call rData
End Sub
Sub rData()
'Retrieve Data
Dim lRow As Long
Dim lCol As Long
Dim Datawb As Workbook
'Open Selected workbook
Set Datawb = Workbooks.Open(PathAndFile)
With Datawb
'Find the last non-blank cell in column A(1)
lRow = Cells(Rows.Count, 1).End(xlUp).Row
'Find the last non-blank cell in row 1
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
'Copy data and paste in new this workbook
Range(Cells(1, 1), Cells(lRow, lCol)).Copy _
Destination:=ThisWorkbook.Worksheets("DataTransferred").Cells(1, 1)
End With
Workbooks(FileName).Close
'Clear Memory
lRow = 0
lCol = 0
strPathAndFile = vbNullString
strFileName = vbNullString
'Sort data
Call Worksheets("DataTransferred").VariableSelect '<<<Run-Time Error 7
Application.ScreenUpdating = True
End Sub
Located in Sheets("DataTransffered"):
Sub VariableSelect()
'Determine unique variables out of assortment
Dim rngDest As Range
If ThisWorkbook.Worksheets("DataTransferred").Cells = Empty Then Exit Sub
'Determine destination for varilables
Set rngDest = ThisWorkbook.Sheets("Analysis").Range("A1")
rngDest.ClearContents
'Select cells with in column (B) and apply filter
Me.Range(Me.Range("B1"), Me.Cells(Rows.Count, 2).End(xlUp)).AdvancedFilter _
Action:=xlFilterCopy, CopyToRange:=rngDest, Unique:=True
End Sub

Copying worksheets from multiple workbooks into current workbook

Copying worksheets from multiple workbooks into current workbook
Hi I was wondering if anybody if you guys could help me out?
Im trying to copy multiple workbooks and just save it into only one worksheet.
I have 2000 diffrent workbooks with the diffrent amount of rows, The ammount of cells is the same and it dosent change and they are all at the first sheet in every workbook.
Im new with this kind of stuff so i'm thankfull for all help u can offer, I cant make it work. I'm using excel 2010
This is what I got atm:
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow
Dim Filepath As String
Filepath = “C:\test\”
MyFile = Dir("test\")
Do While Len(MyFile) > 0
If MyFile = "master.xlsm" Then
Exit Sub
End If
Range(Range("a1"), ActiveCell.SpecialCells(xlLastCell)).Select
Selection.Name = "PivotData"
Workbooks.Open (Filepath & MyFile)
Range("A2:AD20").Copy
ActiveWorkbook.Close
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("sheet1").Range(Cells(erow, 1), Cells(erow, 1))
MyFile = Dir
Loop End
Sub
I've re-written your code by applying what I posted in the comment.
Try this out: (I stick with your logic using the DIR function)
Sub test()
Dim MyFile As String, MyFiles As String, FilePath As String
Dim erow As Long
'~~> Put additional variable declaration
Dim wbMaster As Workbook, wbTemp As Workbook
Dim wsMaster As Worksheet, wsTemp As Worksheet
FilePath = "C:\test\"
MyFiles = "C:\test\*.xlsx"
MyFile = Dir(MyFiles)
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
'~~> Set your declared variables
Set wbMaster = ThisWorkbook 'if you want to consolidate files in this workbook
Set wsMaster = wbMaster.Sheets("Sheet1") 'replace Sheet1 to suit
Do While Len(MyFile) > 0
'Debug.Print MyFile
If MyFile <> "master.xlsm" Then
'~~> Open the file and at the same time, set your variable
Set wbTemp = Workbooks.Open(Filename:=FilePath & MyFile, ReadOnly:=True)
Set wsTemp = wbTemp.Sheets(1) 'I used index, you said there is only 1 sheet
'~~> Now directly work on your object
With wsMaster
erow = .Range("A" & .Rows.Count).End(xlUp).Row 'get the last row
'~~> Copy from the file you opened
wsTemp.Range("A2:AD20").Copy 'you said this is fixed as well
'~~> Paste on your master sheet
.Range("A" & erow).Offset(1, 0).PasteSpecial xlPasteValues
End With
'~~> Close the opened file
wbTemp.Close False 'set to false, because we opened it as read-only
Set wsTemp = Nothing
Set wbTemp = Nothing
End If
'~~> Load the new file
MyFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
I've commented the code to help you modify it to suit your needs.
I you got stuck again, then just go back here and clearly state your problem.
Try this out:
Option Explicit
Sub CombineDataFiles()
Dim DataBook As Workbook, OutBook As Workbook
Dim DataSheet As Worksheet, OutSheet As Worksheet
Dim TargetFiles As FileDialog
Dim MaxNumberFiles As Long, FileIdx As Long, _
LastDataRow As Long, LastDataCol As Long, _
HeaderRow As Long, LastOutRow As Long
Dim DataRng As Range, OutRng As Range
'initialize constants
MaxNumberFiles = 2001
HeaderRow = 1 'assume headers are always in row 1
LastOutRow = 1
'prompt user to select files
Set TargetFiles = Application.FileDialog(msoFileDialogOpen)
With TargetFiles
.AllowMultiSelect = True
.Title = "Multi-select target data files:"
.ButtonName = ""
.Filters.Clear
.Filters.Add ".xlsx files", "*.xlsx"
.Show
End With
'error trap - don't allow user to pick more than 2000 files
If TargetFiles.SelectedItems.Count > MaxNumberFiles Then
MsgBox ("Too many files selected, please pick more than " & MaxNumberFiles & ". Exiting sub...")
Exit Sub
End If
'set up the output workbook
Set OutBook = Workbooks.Add
Set OutSheet = OutBook.Sheets(1)
'loop through all files
For FileIdx = 1 To TargetFiles.SelectedItems.Count
'open the file and assign the workbook/worksheet
Set DataBook = Workbooks.Open(TargetFiles.SelectedItems(FileIdx))
Set DataSheet = DataBook.ActiveSheet
'identify row/column boundaries
LastDataRow = DataSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
LastDataCol = DataSheet.Cells.Find("*", SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column
'if this is the first go-round, include the header
If FileIdx = 1 Then
Set DataRng = Range(DataSheet.Cells(HeaderRow, 1), DataSheet.Cells(LastDataRow, LastDataCol))
Set OutRng = Range(OutSheet.Cells(HeaderRow, 1), OutSheet.Cells(LastDataRow, LastDataCol))
'if this is NOT the first go-round, then skip the header
Else
Set DataRng = Range(DataSheet.Cells(HeaderRow + 1, 1), DataSheet.Cells(LastDataRow, LastDataCol))
Set OutRng = Range(OutSheet.Cells(LastOutRow + 1, 1), OutSheet.Cells(LastOutRow + 1 + LastDataRow, LastDataCol))
End If
'copy the data to the outbook
DataRng.Copy OutRng
'close the data book without saving
DataBook.Close False
'update the last outbook row
LastOutRow = OutSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Next FileIdx
'let the user know we're done!
MsgBox ("Combined " & TargetFiles.SelectedItems.Count & " files!")
End Sub

Resources