I want to code a macro that searches through multiple .xls* files and copies the tables into one big table in my masterfile. Currently the macro is able to access the different files and can copy the information. Now I want it to paste it into one table in my masterfile but i dont know how to make it paste the information from one table at the end of another without knowing how big each table is, so there is no overlapping or empty lines.
Sub New_Data()
Dim wb As Workbook
Dim ws As Worksheet
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
'Deletes all current data in the masterfile
Application.DisplayAlerts = False
For Each ws In Worksheets
If ws.Name = "Overview" Then ws.Range(A2, AT10000).ClearContents
Application.DisplayAlerts = True
'User can pick what folder he wants to get his data from
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Please pick a Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'If invalid path is put in
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'All data ending on .xls* gets picked
myExtension = "*.xls*"
'Declares the files as combination of path and .xsl*
myFile = Dir(myPath & myExtension)
'Loop that actually opens up the files and picks the data from it
Do While myFile <> ""
Set wb = Workbooks.Open(Filename:=myPath & myFile)
DoEvents
'Actual Process of copying, as you can see im totally lost
For Each ws In Worksheets
If ws.Name = "Übersicht" Then ws.Range("B6:BT10000").Copy
Before ThisSheet.Range("A2:AT64").Paste
wb.Close SaveChanges:=False
DoEvents
myFile = Dir
Loop
'Feedback, for the code is done
MsgBox "Done!"
End Sub
The problem is that I need to copy a varying amount of cells and have absolutly no clue how to achive that, any help (preferably explained simple, I'm quite new to VBA) will be appreciated, thanks a lot in advance.
Some things to note:
There are numerous ways to find the last row and last column of a worksheet. Depending on what you are looking for, you will want to use different methods
Dir returns a string representing the name of a file, directory, or archive that matches a specified pattern. When we say fileName = Dir we are setting fileName equal to the next file which meets the pattern we set about
Good Luck!
Option Explicit
Sub Consolidate_Data()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim wb As Workbook
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
Dim sendRow As Long: sendRow = 2
Dim src As Worksheet
' Create a worksheet object to reference the 'master' sheet
Set ws = ThisWorkbook.Worksheets("Overview")
lastRow = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Row ' gets the lowest row where data is found
lastCol = ws.UsedRange.SpecialCells(xlCellTypeLastCell).Column ' gets the rightmost column where data is found
' Clear Contents of ws (excluding header row that im assuming you have)
ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)).ClearContents
' common directory where files are located
Dim commonDirectory As String: commonDirectory = "C:\Desktop\Test_Folder\"
Dim key As String: key = "*.xls" ' As you seemed to already understand the * denotes any length of any characters
Dim fileName As Variant: fileName = Dir(commonDirectory & key)
' iterate through all files which follow the commonDirectory & key pattern
While fileName <> ""
' opening workbooks is very slow, if you have a way to verify which workbooks you want to open based on the workbook name
' you could reduce runtime by quite a bit
Set wb = Workbooks.Open(commonDirectory & fileName, , True) ' open the .xls workbook as read only
' check if the workbook contains "Ubersicht" (my keyboard doesnt like the accent on the U)
For Each src In wb.Worksheets
If src.name = "Ubersicht" Then
' COPY THE DATA
lastRow = src.UsedRange.SpecialCells(xlCellTypeLastCell).Row ' gets the lowest row where data is found (in src -> aka your Ubersicht sheet)
lastCol = src.UsedRange.SpecialCells(xlCellTypeLastCell).Column ' gets the rightmost column where data is found (in src -> aka your Ubersicht sheet)
src.Range(src.Cells(1, 1), src.Cells(lastRow, lastCol)).Copy Destination:=ws.Range(ws.Cells(sendRow, 1), ws.Cells(sendRow, 1))
sendRow = sendRow + lastRow
Exit For
End If
Next
wb.Close savechanges:=False
fileName = Dir
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Related
HiHi,
disclaimer: I have no experience with coding
I have a code which takes values from cells (B2:C2) from multiple worksheets in a folder on my desktop and pasts it into the master workbook. This works great, however, I don't want the copied cells pasted consecutively down cells (F3:G3)- they need to be pasted into specific cells. This sounds complicated, and I'm sure it is. First, here's my base code which I have modified (from this code) to fit my needs:
Sub MergeAllWorkbooks()
Dim SummarySheet As Worksheet
Dim FolderPath As String
Dim FileName As String
Dim WorkBk As Workbook
Dim SourceRange As Range
Dim DestRange As Range
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
' Set summarysheet to activeworkbook/activesheet where the macro runs
Set SummarySheet = ActiveWorkbook.ActiveSheet
' Modify this folder path to point to the files you want to use.
FolderPath = "C:\Users\Me\Desktop\Extracted Data\16.12.2021\"
' Call Dir the first time, pointing it to all Excel files in the folder path.
FileName = Dir(FolderPath & "*.csv*")
' Loop until Dir returns an empty string.
Do While FileName <> ""
' Open a workbook in the folder
Set WorkBk = Workbooks.Open(FolderPath & FileName)
'loop through all Sheets in WorkBk
For Each sh In WorkBk.Worksheets
' Set the source range to be A9 through C9.
Set SourceRange = Sheets(sh.Name).Range("B2:C2")
' Set the destination range to start at column B and
' be the same size as the source range.
Set DestRange = SummarySheet.Range("F" & SummarySheet.Range("F" & Rows.Count).End(xlUp).Row + 1)
Set DestRange = DestRange.Resize(SourceRange.Rows.Count, _
SourceRange.Columns.Count)
' Copy over the values from the source to the destination.
DestRange.Value = SourceRange.Value
Next sh
' Close the source workbook without saving changes.
WorkBk.Close savechanges:=False
' Use Dir to get the next file name.
FileName = Dir()
Loop
' Call AutoFit on the destination sheet so that all
' data is readable.
ActiveSheet.Columns.AutoFit
'Message Box when tasks are completed
MsgBox "Task Complete!"
End Sub
So, this runs and does copy the values from each workbook within the source folder to the master. I want to make it so that:
If it copies from a work book that contains i.e "282579" and "Ch.4" to the cells that correspond to those values. To clarify, I have added a Screenshot of my master workbook.
If it copies a value from a source workbook with a title that contains 282579 and Ch.4, it will paste those 2 values into 282579's Ch.4 cell located at (F10:G10) and so on.
Tried using the If function (like, If (workbook has this in its name) but I have no idea how to specify which cells it needs to be pasted in)
I hope I have made sense and that this is understandable.
edit: if a copy of the data I use is needed, I can supply it
Use a Regular Expression to extract the SN and Ch. numbers from the filename. Use Find to located the SN on the summary sheet then scan the merged rows for the Ch number.
Sub MergeAllWorkbooks()
' Modify this folder path to point to the files you want to use.
Const FolderPath = "C:\Users\Me\Desktop\Extracted Data\16.12.2021\"
Dim wb As Workbook, wbCSV As Workbook
Dim ws As Worksheet, wsCSV As Worksheet
Dim rngCSV As Range, fnd As Range, bFound As Boolean
Dim Filename As String, n As Long, i As Long
' Set summarysheet to activeworkbook/activesheet where the macro runs
Set wb = ActiveWorkbook
Set ws = wb.ActiveSheet
' regular expression to extract numbers
' example VS SAAV_282579 ch 4 Data.csv
Dim Regex As Object, m As Object, SN As Long, CH As Long
Set Regex = CreateObject("vbscript.regexp")
With Regex
.IgnoreCase = True
.Pattern = "(_(\d+) +ch +(\d+) +Data)"
End With
' Call Dir the first time, pointing it to all Excel files in the folder path.
Filename = Dir(FolderPath & "*Data.csv*")
' Loop until Dir returns an empty string.
Application.ScreenUpdating = False
Do While Filename <> ""
' extract SN and Ch from filename
If Regex.test(Filename) Then
Set m = Regex.Execute(Filename)(0).submatches
SN = m(1)
CH = m(2)
Debug.Print Filename, SN, CH
' Find SN
Set fnd = ws.Range("B:B").Find(SN, LookIn:=xlValues, lookat:=xlWhole)
If fnd Is Nothing Then
MsgBox SN & " not found !", vbCritical, Filename
Else
' find ch.
bFound = False
For i = 0 To fnd.MergeArea.Count - 1
If ws.Cells(fnd.Row + i, "D") = CH Then ' Col D
bFound = True
' Open a workbook in the folder
Set wbCSV = Workbooks.Open(FolderPath & Filename, ReadOnly:=True)
ws.Cells(fnd.Row + i, "F").Resize(, 2).Value2 = wbCSV.Sheets(1).Range("B2:C2").Value2
' Close the source workbook without saving changes.
wbCSV.Close savechanges:=False
Exit For
End If
Next
If bFound = False Then
MsgBox "Ch." & CH & " not found for " & SN, vbExclamation, Filename
End If
End If
n = n + 1
Else
Debug.Print Filename & " skipped"
End If
' Use Dir to get the next file name.
Filename = Dir()
Loop
' Call AutoFit on the destination sheet so that all
' data is readable.
ws.Columns.AutoFit
Application.ScreenUpdating = True
'Message Box when tasks are completed
MsgBox n & " csv files found.", vbInformation, "Task Complete!"
End Sub
From your explanation it is not clear if you are able to match the source worksheets with a specific Ch. If you can, I'd advise to define a Ch variable soon after the For each sh loop, then you need to initiate another loop in the master workbook on column D for each row until you get the row number of the Ch variable. You use the row number to define the destination range
Dim SummarySheet As Worksheet
Dim FolderPath As String
Dim FileName As String
Dim WorkBk As Workbook
Dim SourceRange As Range
Dim DestRange As Range
Dim n As Long 'Ch substring position
Dim Ch As String 'Ch variable for source file
Dim LastChRow As Long 'lastrow of Ch in summary sheet
Dim ChSummary As String 'Define the Ch string in summary sheet
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
' Set summarysheet to activeworkbook/activesheet where the macro runs
Set SummarySheet = ActiveWorkbook.ActiveSheet
' Define LastChRow
LastChRow = SummarySheet.Cells(Rows.Count, "D").End(xlUp).Row
' Modify this folder path to point to the files you want to use.
FolderPath = "C:\Users\Me\Desktop\Extracted
Data\16.12.2021\"
' Call Dir the first time, pointing it to all Excel files in the
folder path.
FileName = Dir(FolderPath & "*.csv*")
' Loop until Dir returns an empty string.
Do While FileName <> ""
'define starting charachter of Ch source file for string manipulation
n = InStr(FileName, "Ch")
'define Ch variable
Ch = Trim(Mid(FileName, n, 5))
' Open a workbook in the folder
Set WorkBk = Workbooks.Open(FolderPath & FileName)
'loop through all Sheets in WorkBk
For Each sh In WorkBk.Worksheets
For i = 3 To LastChRow
'Define ChSummary variable in loop
ChSummary = "Ch" & " " & SummarySheet.Range("D" & i)
If ChSummary = Ch Then
' Set the source range to be A9 through C9.
Set SourceRange = Sheets(sh.Name).Range("B2:C2")
' Set the destination range to start at column B and
' be the same size as the source range.
Set DestRange = SummarySheet.Range("F" & i & ":G" & i)
'Set DestRange = DestRange.Resize(SourceRange.Rows.Count, _
' SourceRange.Columns.Count)
' Copy over the values from the source to the destination.
DestRange.Value = SourceRange.Value
End If
Next i
Next sh
' Close the source workbook without saving changes.
WorkBk.Close savechanges:=False
' Use Dir to get the next file name.
FileName = Dir()'
i'm a beginner in VBA and i need to do the following. Starting from a workbook i should create another one without formulas and macro code.
I found some solutions and based on that i modeled my own code:
Sub SaveValuesOnly()
Dim wsCopy As Worksheet, wsPaste As Worksheet
Dim wb As Workbook
Dim sFileName As String, sPath As String
sPath = "C:\Users\"
sFileName = "OVERALL RECAP"
Set wsCopy = ThisWorkbook.Worksheets("INCIDENTS")
Set wb = Workbooks.Add
Set wsPaste = wb.Sheets(1)
wsCopy.Cells.copy
wsPaste.Cells.PasteSpecial xlPasteValues
wsPaste.Cells.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
wsPaste.Name = "Expenses" 'Change if needed
wb.SaveAs Filename:=sPath & sFileName, FileFormat:=xlOpenXMLWorkbook
End Sub
I need to copy more than one sheet and tried to use the official documentation like:
Worksheets(Array("Sheet1", "Sheet2", "Sheet4")).Copy
With ActiveWorkbook
.SaveAs Filename:=Environ("TEMP") & "\New3.xlsx", FileFormat:=xlOpenXMLWorkbook
.Close SaveChanges:=False
End With
But i didn't manage to implement this into the code above, any suggestion? Thanks.
Copy Worksheets to New Workbook
The Flow
Basically, the procedure will:
create a copy of ThisWorkbook (the workbook containing this code) in the destination folder,
open the copy and continue to work with it,
copy values to (remove formulas from) the specified worksheets,
delete the not specified sheets,
rename the specified worksheets,
save the copy to a new workbook in .xlsx format,
delete the copy.
Remarks
If a workbook with the same name (e.g. OVERALL RECAP) is already open, it will crash Excel.
Be careful when determining the worksheet names, because if you try to rename a worksheet using an already existing name, an error will occur.
The Code
Option Explicit
Sub copyWorksheets()
Const dPath As String = "C:\Users"
Const dFileName As String = "OVERALL RECAP"
Const CopyList As String = "INCIDENTS,Sheet2,Sheet3"
Const PasteList As String = "Expenses,Sheet2,Sheet4"
Dim wb As Workbook: Set wb = ThisWorkbook
Dim CopyNames() As String: CopyNames = Split(CopyList, ",")
Dim PasteNames() As String: PasteNames = Split(PasteList, ",")
Dim nUpper As Long: nUpper = UBound(CopyNames)
Dim tFilePath As String: tFilePath = dPath & "\" & "t_" & wb.Name
Application.ScreenUpdating = False
' Save a copy.
wb.SaveCopyAs tFilePath
' Work with the copy.
With Workbooks.Open(tFilePath)
' Copy values (remove formulas).
Dim n As Long
For n = 0 To nUpper
With .Worksheets(CopyNames(n)).UsedRange
.Value = .Value
End With
Next n
' Delete other sheets.
Dim dCount As Long: dCount = .Sheets.Count - nUpper - 1
If dCount > 0 Then
Dim DeleteNames() As String: ReDim DeleteNames(1 To dCount)
Dim sh As Object ' There maybe e.g. charts.
n = 0
For Each sh In .Sheets
If IsError(Application.Match(sh.Name, CopyNames, 0)) Then
n = n + 1
DeleteNames(n) = sh.Name
End If
Next sh
Application.DisplayAlerts = False
.Sheets(DeleteNames).Delete
Application.DisplayAlerts = True
End If
' Rename worksheets.
For n = 0 To nUpper
If CopyNames(n) <> PasteNames(n) Then
.Worksheets(CopyNames(n)).Name = PasteNames(n)
End If
Next n
' Save workbook.
.Worksheets(1).Activate
Application.DisplayAlerts = False
.SaveAs _
Filename:=dPath & "\" & dFileName, _
FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True
'.Close SaveChanges:=False ' Close the new workbook.
End With
' Delete the copy.
Kill tFilePath
Application.ScreenUpdating = True
MsgBox "Workbook created.", vbInformation, "Success"
'wb.Close SaveChanges:=False ' Close ThisWorkbook.
End Sub
The code below takes the opposite approach to the earlier one. It copies the entire workbook to a new name and then modifies it. You can list the sheets you want to keep. Formulas in them will be converted to their values. Sheets not listed will be deleted.
Sub SaveValuesOnly()
' 154
' list the sheets you want to keep by their tab names
Const SheetsToKeep As String = "Sheet1,Sheet3"
Dim sFileName As String
Dim sPath As String
Dim Wb As Workbook ' the new workbook
Dim Ws As Worksheet ' looping object: worksheet
Dim Keep() As String ' array of SheetsToKeep
Dim i As Long ' loop counter: Keep index
sPath = Environ("UserProfile") & "\Desktop\"
sFileName = "OVERALL RECAP"
Keep = Split(SheetsToKeep, ",")
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
' create a copy of the ActiveWorkbook under a new name
ActiveWorkbook.SaveCopyAs sPath & sFileName & ".xlsm"
Set Wb = Workbooks.Open(sPath & sFileName & ".xlsm")
For Each Ws In Wb.Worksheets
' check if the sheet is to be kept
For i = UBound(Keep) To 0 Step -1
If StrComp(Ws.Name, Trim(Keep(i)), vbTextCompare) = 0 _
Then Exit For
Next i
If i = True Then ' True = -1
Ws.Delete
Else
' keep the sheet
With Ws.UsedRange
.Copy
.PasteSpecial xlPasteValuesAndNumberFormats
' you can repeat PasteSpecial here to copy more detail
End With
End If
Next Ws
' change the file format to xlsx (deleting copy of this code in it)
Wb.SaveAs Filename:=sPath & sFileName, FileFormat:=xlOpenXMLWorkbook
Kill sPath & sFileName & ".xlsm"
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
There are a few points you need to be aware of. One, the ActiveWorkbook will be copied. That is presumed to the ThisWorkbook (the one containing the code) but it could be any other. Two, any workbook by the targeted name already existing at the location specified by sPath will be over-written without warning. Three, alerts are turned off while the code runs. If it happens to crash they will remain turned off until you restart Excel or enter Application.DisplayAlerts = True [Enter] in the Immediate window.
Last, but not least, sheets are processed in sequence of their index numbers (left to right). If your formulas in the kept sheets refer to data in sheets that get deleted the sequence is important. You may have to run two loops instead of the one my code has. Use one loop to replace formulas and another just to delete.
I'm looking for a help in a difficult mission.
I have more then 30.000 files in a especific folder (*\backup) in xl?? format and need to read the cell B4. I thought the better idea is use the VBA in Excel to read this specific cell for each file and write on a table A:B.
I believe the following should help you, just remember to amend the declaration for the destination Worksheet name and the full path to the folder where the Workbooks you want to read reside.
The code below will loop through your desired Directory/Folder and read all the files with an .xls* extension, get the value from the first Worksheet in cell B4 and pass this value to the destination worksheet.
Sub LoopAllExcelFilesInFolder()
Dim wb As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim wsDestination As Worksheet: Set wsDestination = ThisWorkbook.Worksheets("Sheet1")
'declare and set the worksheet where you want to aggregate the data.
'Optimize Macro Speed
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.CutCopyMode = False
myPath = "C:\backup\"
'set the full path to the folder you want to utilize, remember to add the last \
Last = wsDestination.Cells(wsDestination.Rows.Count, "A").End(xlUp).Row
If Last >= 2 Then wsDestination.Range("A2:B" & Last).ClearContents
'clear the destination worksheet ready to aggregate again
myExtension = "*.xls*"
'Target File Extension (must include wildcard "*")
myFile = Dir(myPath & myExtension)
'Target Path with Ending Extention
Do While myFile <> ""
'Loop through each Excel file in folder
Set wb = Workbooks.Open(Filename:=myPath & myFile)
DoEvents
'Ensure Workbook has opened before moving on to next line of code
wsDestination.Cells(1, "A").Value = "Filename"
wsDestination.Cells(1, "B").Value = "Value From Cell B4"
NextRow = wsDestination.Cells(wsDestination.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
wsDestination.Cells(NextRow, "A").Value = myFile
wsDestination.Cells(NextRow, "B").Value = wb.Worksheets(1).Range("B4").Value
wb.Close SaveChanges:=False
'Close Workbook without Saving
DoEvents
'Ensure Workbook has closed before moving on to next line of code
myFile = Dir
'Next File
Loop
MsgBox "Transfer of Data Completed!", vbInformation, "Info"
'Message Box when tasks are completed
ResetSettings:
'Reset Macro Optimization Settings
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
I am trying to:
open up spreadsheets from a folder of 50
sort and filter the first sheet on each one (the name will be unknown of this sheet)
filtering needs to find each row that has a certain value in column J - this value is 'No'
All rows that meet the criteria (row J contains 'no') need to be then placed onto a master spreadsheet
Each csv should close each time it's been processed
I have spent hours & hours on forums and have some code which I have been tinkering with, but can't get it running together:
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
'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 = "*.csv*"
'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
Range("A1:AC3100").Select
Selection.AutoFilter
ActiveWindow.LargeScroll ToRight:=1
Range("Y2").Select
ActiveSheet.Range("$A$1:$AC$3110").AutoFilter Field:=25, Criteria1:="No"
Range("A1:AC3100").Select
Range("Y2").Activate
Selection.Copy
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Paste
Application.CutCopyMode = False
Selection.Copy
Windows("Book1").Activate
Rows("1:1").Select
Selection.Insert Shift:=xlDown
'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
The spreadsheet data has variable lengths do I made the selection the maximum:
Range("A1:AC3100")
I would assume there is a better way than this too.
Your criterion is a bit too vague to give a perfect response, but I'll take a crack at it. Some parts of your code seem extraneous or convoluted so I'm doing this based on your end goal (all rows where the value in column J for the first sheet in each workbook that contain 'no' are copied into a master spreadsheet).
If all of your worksheets are always in the same folder you can make the myPath static rather than attempting to use the msoFileDialogFolderPicker. When I attempted to run your code on my machine it gave me an "Out of Memory" error, if you have this issue as well I recommend a static string for myPath.
Option Explicit
Sub PutInMasterFile()
Dim wb As Workbook
Dim masterWB As Workbook
Dim rowNum As Integer
Dim copyRange As Range
Dim pasteRange As Range
Dim myPath As String
Dim myFile As String
Dim FirstAddress As String
Dim x As Variant
Dim c As Variant
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
I would advise against disabling Events until you have confirmed your code is running correctly. Worry about getting working code before thinking about optimization.
x = 1
Set masterWB = Workbooks("NAMEOFWORKBOOK")
Set pasteRange = masterWB.Sheets(1).Range("A" & x)
myPath = "C:\EXAMPLE\MOREEXAMPLE\*.csv"
myFile = Dir(myPath)
myPath can be set to search directly for .csv files in the string.
Do While myFile <> vbNullString
Workbooks.Open (myFile)
With Workbooks(myFile).Sheets(1)
Set c = .Range("J:J").Find("No", LookIn:=xlValues, lookat:=xlWhole)
Using .find in vba is preferential to trying to get a filter and then grabbing everything that the filter displays.
If Not c Is Nothing Then
FirstAddress = c.Address
Do
rowNum = c.Row
Set copyRange = .Range(rowNum & ":" & rowNum)
copyRange.Copy
pasteRange.PasteSpecial
x = x + 1
Set pasteRange = masterWB.Sheets(1).Range("A" & x)
Copies in the row into your master sheet. The x = x + 1 guarantees you paste new data onto a new row to avoid overwriting anything.
Set c = .Range("J:J").FindNext(c)
Loop While Not c Is Nothing And FirstAddress <> c.Address
End If
End With
Workbooks(myFile).Close
myFile = Dir()
Closes your first file and gets the next one set up
Set pasteRange = masterWB.Sheets(1).Range("A" & x)
Sets the paste range in the master wb outside of the inner loop, otherwise it will overwrite the values starting at A1 again with the next file.
Loop
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
I would also recommend you read up on VBA best practices for any future code you work on such as using Option Explicit and avoiding use of GoTo or .Select wherever possible.
Background
First of all I realise all of this is a perfect task for a database but I don't currently have that option available and I think it's a good learning experience to continue doing this in excel.
I have multiple workbooks each containing a list of identifying numbers, through the code below I enter the name of the workbook I require and the list is imported to main my workbook containing multiple columns of data. I then ran my Match and Export sub to break up the main data set into different sheets.
Question
Is there a way to use a for loop for each of the files in the containing folder so that I don't have to identify each workbook in turn?
Sub Export_Specified_Contractor()
Dim listwb As Workbook, mainwb As Workbook
Dim fname As String
Dim sht As Worksheet, oput As Worksheet
Dim LRow As Long, oLRow As Long
Dim cprng As Range, orng As Range
'--> Get the name of the contractor list to be exported
fname = Application.InputBox("Enter Contractor Name", "Name?")
Set mainwb = ThisWorkbook
With Application
'--> Set contractor list file
Set listwb = .Workbooks.Open _
("C:\Documents and Settings\alistairw\My Documents\Disallowed Items\Contractor Lists\" & fname)
End With
Set sht = listwb.Sheets("Sheet1")
'--> Copy contractor list
With sht
LRow = .Range("A" & Rows.Count).End(xlUp).Row
.Range("A1:A" & LRow).Copy
End With
mainwb.Activate
'--> Create contractor list sheet in main workbook and paste values
With mainwb
On Error Resume Next
Sheets("Sheet2").Delete
Sheets.Add.Name = "Sheet2"
Set oput = Sheets("Sheet2")
With oput
.Range("A1").PasteSpecial
End With
End With
Call Match_and_Export
'--> Delete the list workbook and list sheet
Application.DisplayAlerts = False
listwb.Close
oput.Delete
Application.DisplayAlerts = True
End Sub
looping through a folder:
MyPath = "C:\Documents and Settings\alistairw\My Documents\Disallowed Items\Contractor Lists\"
strFilename = Dir(MyPath & "\*.xlsx", vbNormal) 'change to xls if needed
If Len(strFilename) = 0 Then Exit Sub ' exit if no files in folder
Do Until strFilename = ""
'Your code here
strFilename = Dir()
Loop