I want to retrieve data from multiple Excel workbooks in a folder.
The files are not opened.
The workbooks are called: Business Case (1), Business Case (2)... (incrementally growing until ~50).
I need the data to do business analysis, and evaluate potential ideas.
I got it working until file nr. 11 with the "Indirect" function. It won't retrieve more data after 10+; so I started looking at VBA.
The first problem I ran into with VBA, is that lopping through Excel files, looks like it requires a "fixed" path (e.g.: c:\Users\Bonkers\Desktop\Folder.....). I want the master-data-retrieval-book to work on other PCs, so the path of the folder, needs to be "not limited" to my PC.
Function ChooseFolder(strTitle As String, fDtype) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(fDtype)
With fldr
.Title = strTitle
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
ChooseFolder = sItem
Set fldr = Nothing
End Function
Sub datatransfer()
Dim FolderPath As String
Dim FilePath As String
Dim Filename As String
Dim targetfile As String
Dim wb1 As Workbook, wb2 As Workbook
targetfile = ChooseFolder("Please select the target file", msoFileDialogFilePicker)
FolderPath = ChooseFolder("Please select the Folder path", msoFileDialogFolderPicker)
FilePath = FolderPath & "\Business Case (*.xls*)"
Set wb2 = Workbooks.Open(targetfile) 'only need to open this once and leave open until execution is finished
Filename = Dir(FilePath)
Do While Filename <> "" ' need "<>" to say not equal to nothing
wb2.Worksheets.Add After:=wb2.Worksheets(wb2.Worksheets.Count) 'add new sheet to paste data in target book
Set wb1 = Workbooks.Open(FolderPath & "\" & Filename)
Dim lastrow As Long, lastcolumn As Long
With wb1.Worksheets(1) 'best to qualify all objects and work directly with them
lastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
lastcolumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
'pretty sure you want to add this A1, since it's a new blank sheet
.Range(.Cells(2, 1), .Cells(lastrow, lastcolumn)).Copy _
Destination:=wb2.Worksheets(wb2.Worksheets.Count).Range("A1")
End With
wb1.Close False 'assume no need to save changes to workbook you copied data from
Filename = Dir
Loop
wb2.Close True 'no close and save master file
End Sub
If you need to dynamically set the files folder and the target file you can use the next adapted function:
Function ChooseFolder(strTitle As String, fDtype) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(fDtype)
With fldr
.Title = strTitle
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
ChooseFolder = sItem
Set fldr = Nothing
End Function
Then, in the processing Sub you may call it in the next way:
targetfile = ChooseFolder("Please select the target file", msoFileDialogFilePicker)
FolderPath = ChooseFolder("Please select the Folder path", msoFileDialogFolderPicker)
FilePath = folderPath & "\Business Case (*.xls*"
Edited:
Please, use this updated code. It will copy all the range as it is. Since, I do not know if the content of the all involved workbooks looks the same, I tried designing the code to behave as for the similar structures:
Sub datatransfer()
Dim FolderPath As String, FilePath As String, Filename As String, targetfile As String
Dim wb1 As Workbook, wb2 As Workbook, astrow As Long, lastcolumn As Long
FolderPath = ChooseFolder("Please select the Folder path", msoFileDialogFolderPicker)
targetfile = ChooseFolder("Please select the target file", msoFileDialogFilePicker)
FilePath = FolderPath & "\Business Case (*.xls*" 'you wrongly copied this line...
Set wb2 = Workbooks.Open(targetfile)
Filename = Dir(FilePath)
Do While Filename <> ""
wb2.Worksheets.Add After:=wb2.Worksheets(wb2.Worksheets.Count) 'add new sheet to paste data in target book
Set wb1 = Workbooks.Open(FolderPath & "\" & Filename)
With wb1.Worksheets(1) 'best to qualify all objects and work directly with them
lastrow = .UsedRange.Rows.Count + .UsedRange.Row
lastcolumn = .UsedRange.Columns.Count + .UsedRange.Column
.Range(.Cells(2, 1), .Cells(lastrow, lastcolumn)).Copy _
Destination:=wb2.Worksheets(wb2.Worksheets.Count).Range("A2")
End With
wb1.Close False 'assume no need to save changes to workbook you copied data from
Filename = Dir
Loop
wb2.Close True 'no close and save master file
End Sub
Please, test it and send some feedback.
Related
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
I am trying to read files *.xls from u:\test folder. There is one sheet in every file. I want to copy cell B1 and to paste it into new file to A1. Then I want to copy range B1:B57 and to paste it into the new file/sheet to B1:B57. Then I want to copy range K1:U57 and copy (the values only) to the new file/sheet C1 location. I am doing this in Visual Basic 6 and I have problem to find out how to use the range function... I tried to activated and select the sheet(1). Then I wanted to use the command Set SrchRange = ActiveSheet.Range(Cells(2, 1)). I got error 1004 Application defined or object defined error. Here on this line. If I would successed to select/copy/paste the cell areas to new file/sheet, then I would like to save the current file as txt, given the .txt extenssion. How to correct this code to reach the goal?
Sub FromExcelToNpad()
'export activesheet as txt file
Dim my_files As String
Dim folder_path As String
Dim wb As Workbook, NewWB As Workbook
Dim ws As Worksheet
Dim SrcRange As Range
folder_path = "u:\test"
my_files = Dir(folder_path & "\*.xls", vbDirectory)
Do While my_files <> vbNullString
Set wb = Workbooks.Open(folder_path & "\" & my_files)
Set ws = wb.Sheets(1)
Set NewWB = Workbooks.Add
ws.Activate
ws.Select
Set SrchRange = ActiveSheet.Range(Cells(2, 1))
wb.ActiveSheet.UsedRange.Copy NewWB.Sheets(1).Range("A1")
wb.Close True
Application.DisplayAlerts = True
my_files = Dir()
Loop
End Sub
Update
The range and cells are copied:
Dim my_files As String
Dim folder_path As String
Dim wb As Workbook, NewWB As Workbook
Dim ws As Worksheet
folder_path = "u:\test"
my_files = Dir(folder_path & "\*.xls", vbDirectory)
Do While my_files <> vbNullString
Set wb = Workbooks.Open(folder_path & "\" & my_files)
Set ws = wb.Sheets(1)
Set NewWB = Workbooks.Add
ws.Range("B1").Copy NewWB.Sheets(1).Range("A1")
ws.Range("B3:B57").Copy NewWB.Sheets(1).Range("A3:A57")
ws.Range("K1:U57").Copy
NewWB.Sheets(1).Range("B1:L57").PasteSpecial xlValues
wb.Close True
With NewWB
Application.DisplayAlerts = False
.SaveAs Filename:=folder_path & "\" & my_files, FileFormat:=xlText
.Close True
Application.DisplayAlerts = True
End With
wb.Save
my_files = Dir()
Loop
I am trying to save the file as .txt . I have error Run time error - automation error. Also there is a dialog asking me if I want to save data from a "page". How to turn this off?
I have written some VBA code to handle copying data from multiple workbooks in a single folder to another Master workbook and then graph the results. When running the macro it doesn't copy the data in the correct order. Ie. Curve1 gets copied where Curve8 should go. Below is the code that handles the entire folder selection and copy paste procedure.
Sub CopyDataBetweenWorkbooks()
Dim wbSource As Workbook
Dim shTarget As Worksheet
Dim shSource As Worksheet
Dim strFilePath As String
Dim strPath As String
' Initialize some variables and
' get the folder path that has the files
Set shTarget = ThisWorkbook.Sheets("5")
strPath = GetPath
' Make sure a folder was picked.
If Not strPath = vbNullString Then
' Get all the files from the folder
strfile = Dir$(strPath & "*.xlsx", vbNormal)
Do While Not strfile = vbNullString
' Open the file and get the source sheet
Set wbSource = Workbooks.Open(strPath & strfile)
Set shSource = wbSource.Sheets("Points")
'Copy the data
Call CopyData(shSource, shTarget)
'Close the workbook and move to the next file.
wbSource.Close False
strfile = Dir$()
Loop
End If
End Sub
' Procedure to copy the data.
Sub CopyData(ByRef shSource As Worksheet, shTarget As Worksheet)
Const strRANGE_ADDRESS As String = "B1:C26000"
Dim lCol As Long
'Determine the last column.
lCol = shTarget.Cells(21, shTarget.Columns.Count).End(xlToLeft).Column + 2
'Copy the data.
shSource.Range(strRANGE_ADDRESS).Copy
shTarget.Cells(21, lCol).PasteSpecial xlPasteValuesAndNumberFormats
' Reset the clipboard.
Application.CutCopyMode = xlCopy
End Sub
' Fucntion to get the folder path
Function GetPath() As String
With Application.FileDialog(msoFileDialogFolderPicker)
.ButtonName = "Select a folder"
.Title = "Folder Picker"
.AllowMultiSelect = False
'Get the folder if the user does not hot cancel
If .Show Then GetPath = .SelectedItems(1) & "\"
End With
End Function
If there is a way for me to implement a change without using an array that would be the best option.
Found it folks! I just needed to step through the files in order by calling them one by one and stepping through the numbers (The naming convention can even be anything followed by a number using this method) Sweet Giblets, I did it!
Sub CopyDataBetweenWorkbooks()
Dim wbSource As Workbook
Dim shTarget As Worksheet
Dim shSource As Worksheet
Dim strFilePath As String
Dim strPath As String
' Initialize some variables and
' get the folder path that has the files
Set shTarget = ThisWorkbook.Sheets("6")
strPath = GetPath
Filename = InputBox("What is the name of this File")
FileCount = InputBox("How many file are you looking for")
' Make sure a folder was picked.
If Not strPath = vbNullString Then
' Get all the files from the folder
'strfile = Dir$(strPath & "*.xlsx", vbNormal)
'Do While Not strfile = vbNullString
For FileNumber = 1 To FileCount Step 1
strfile = Filename & FileNumber & ".xlsx"
' Open the file and get the source sheet
Set wbSource = Workbooks.Open(strPath & strfile)
Set shSource = wbSource.Sheets("Points")
'Copy the data
Call CopyData(shSource, shTarget)
'Close the workbook and move to the next file.
wbSource.Close False
'strfile = Dir$()
Next 'FileNumber
'Loop
End If
End Sub
I am doing a cleanup project at work for reports of applications that are being used.
Here is the first part of the project where I need the new workbook to pick up the extracted excel reports from a folder, copy a particular worksheet (via input message box) change the worksheet name to reflect the application report and paste it in the new workbook.
As this macro workbook will be shared with my other colleagues, I would like it to have a "select path directory" box for them to pick and choose the path directory.
I have done the basics of point the macro directly to a specific location to pick the files. My manager wants it to be able to choose the path directory if another colleague uses this same template.
We have team Google drive which is where the files are stored, so if the code is able to extract the files from the team drive instead of the user downloading onto their system will be great.
Sub CopySheets()
Dim path As String
Dim FileName As String
Dim whichSheet As String
path = "/Users/timothy.wong/Downloads/Project Clean Up/2019/"
FileName = Dir(path & "*.xlsx")
whichSheet = InputBox("Which month would you like to copy? Enter month (eg. Jan, Feb, Mar)")
Do While FileName <> ""
Workbooks.Open FileName:=path & FileName, ReadOnly:=True
Sheets(whichSheet).Select
ActiveWorkbook.ActiveSheet.Copy after:=ThisWorkbook.Sheets(1)
Workbooks(FileName).Close
ActiveSheet.Name = Left(FileName, Application.WorksheetFunction.Search(" ", FileName) - 1)
FileName = Dir()
Loop
End Sub
The basic code works well, I need to make it a little more advanced.
You might try this:
Option Explicit
Sub CopySheets()
Dim path As String
Dim FileName As String
Dim whichSheet As String
Dim SheetNames As String
Dim wb As Workbook
path = GetFolder
If path = vbNullString Then
MsgBox "No folder was selected. Ending the procedure."
End
End If
FileName = Dir(path & "*.xlsx")
whichSheet = InputBox("Which month would you like to copy? Enter month (eg. Jan, Feb, Mar)")
Do While FileName <> ""
Set wb = Workbooks.Open(FileName:=path & FileName, ReadOnly:=True)
On Error Resume Next
If Len(wb.Sheets(whichSheet).Name) = 0 Then 'Here we handle an error on the inputname for the sheet.
On Error GoTo 0
SheetNames = GetSheetNames(wb)
MsgBox "The input sheet does not exist in this workbook. The current worksheet names are: " & SheetNames
whichSheet = InputBox("Which month would you like to copy? Enter month (eg. Jan, Feb, Mar)")
End If
With wb.Sheets(whichSheet)
.Copy after:=ThisWorkbook.Sheets(1)
.Close
End With
ThisWorkbook.Sheets(2).Name = Left(FileName, Application.WorksheetFunction.Search(" ", FileName) - 1)
FileName = Dir()
Loop
End Sub
Function GetFolder() As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Selecciona una carpeta"
.AllowMultiSelect = False
.InitialFileName = Application.DefaultFilePath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Function GetSheetNames(wb As Workbook) As String
Dim ws As Worksheet
For Each ws In wb.Worksheets
GetSheetNames = GetSheetNames & ", " & ws.Name
Next ws
End Function
I am trying to get a VBA macro to loop through all xls files in a specific folder. The below code works for the most part. However i have 42 files in this folder and the code only loops through about 26 of them. They are all the same file extension.
My thoughts are it either isn't looping through all the files. Or it is looping through all the files however there is an issue with the last row variable and data is being pasted over.
Sub CopyDataBetweenWorkbooks()
Dim wbSource As Workbook
Dim shTarget As Worksheet
Dim shSource As Worksheet
Dim strFilePath As String
Dim strPath As String
Application.ScreenUpdating = False
' Initialize some variables and
' get the folder path that has the files
Set shTarget = ThisWorkbook.Sheets(1)
strPath = GetPath
' Make sure a folder was picked.
If Not strPath = vbNullString Then
' Get all the files from the folder
strfile = Dir$(strPath & "*.xls", vbNormal)
Do While Not strfile = vbNullString
' Open the file and get the source sheet
Set wbSource = Workbooks.Open(strPath & strfile)
Set shSource = wbSource.Sheets("Trend Report")
'Copy the data
Call CopyData(shSource, shTarget)
'Close the workbook and move to the next file.
wbSource.Close False
strfile = Dir$()
Loop
End If
End Sub
' Procedure to copy the data.
Sub CopyData(ByRef shSource As Worksheet, shTarget As Worksheet)
LastRowSource = shSource.Cells(Rows.Count, "B").End(xlUp).Row
Dim strRANGE_ADDRESS As String
Dim lastrow As String
strRANGE_ADDRESS = "B15:H" & LastRowSource - 1
'insert file name
StrFileFullname = ActiveWorkbook.FullName
shSource.Range("H15:H" & LastRowSource).Value = StrFileFullname
'Copy the data.
shSource.Range(strRANGE_ADDRESS).Copy
'Set last row and paste
lastrow = shTarget.Cells(Rows.Count, "B").End(xlUp).Row + 1
shTarget.Range("B" & lastrow).PasteSpecial xlPasteValuesAndNumberFormats
' Reset the clipboard.
Application.CutCopyMode = xlCopy
End Sub
' Function to get the folder path
Function GetPath() As String
With Application.FileDialog(msoFileDialogFolderPicker)
.ButtonName = "Select a folder"
.Title = "Folder Picker"
.AllowMultiSelect = False
'Get the folder if the user does not hot cancel
If .Show Then GetPath = .SelectedItems(1) & "\"
End With
End Function