I want to combine the first sheet of multiple workbooks into one master workbook. The data is always structured in the same manner. In addition to this, I want an extra sheet in my master workbook where all the data is summarized (to add up all the numbers of each sheet,eg 1+1+1=3).
So far I started with this code. Yet, I have no idea how to summarize in VBA with different workbooks (that is why it not included in the code)
thanks in advance folks!
'Defining
Dim wb As Workbook
Dim ws As Worksheet
Dim directory As String
Dim myFiles As String
Dim targetwb As Workbook
Set targetwb = ThisWorkbook
Application.ScreenUpdating = False
directory = "C:\Dokumente\"
myFiles = Dir(directory & "*.xlsx")
'Loop through all files in a folder until DIR cannot find anymore
Do While myFiles <> ""
'Open Workbooks one by one 'Do i really have to use the "set command"???
Set wb = Workbooks.Open(Filename:=directory & myFiles)
'The actual action
'Countries:
'Brazil:
If wb.Name = "Brazil*" Then
Worksheets("Status Overview").Copy ThisWorkbook.Worksheets("Brazil")
End If
'Kosovo:
If wb.Name = "Kosovo*" Then
Worksheets("Status Overview").Copy ThisWorkbook.Worksheets("Kosovo")
End If
'United States:
If wb.Name = "United States*" Then
Worksheets("Status Overview").Copy ThisWorkbook.Worksheets("United States")
End If
Workbooks(myFiles).Close
myFiles = Dir
Loop
Application.ScreenUpdating = True```
Run this in a Workbook with one sheet name Summary.
Option Explicit
Sub Summarize()
Const FOLDER = "C:\Dokumente\"
Const WS_NAME = "Status Overview"
'Defining
Dim wbIn As Workbook, wb As Workbook, ws As Worksheet, ar, s
Dim filename As String, msg As String
Dim copied As Collection
Set copied = New Collection
ar = Array("Brazil", "Kosovo", "United States")
Set wb = ThisWorkbook
'Application.ScreenUpdating = False
filename = Dir(FOLDER & "*.xlsx")
Do While filename <> ""
For Each s In ar
If LCase(filename) Like LCase(s) & "*" Then
Set wbIn = Workbooks.Open(FOLDER & filename, True, True) ' update links, read only
wbIn.Sheets(WS_NAME).Copy after:=wb.Sheets(wb.Sheets.Count)
wbIn.Close False
wb.Sheets(wb.Sheets.Count).Name = s
copied.Add s
msg = msg & vbCrLf & s
End If
Next
filename = Dir
Loop
' build =SUM() formula
Dim f As String, sep As String, rng As Range
f = "=SUM("
For Each s In copied
f = f & sep & "'" & s & "'!RC"
sep = ","
Next
f = f & ")"
' range to summate on summary sheet
Set rng = wb.Sheets("Summary").Range("A10:E20")
' apply sum formula to range
rng.FormulaR1C1 = f
'Application.ScreenUpdating = True
MsgBox "Imported :" & msg, vbInformation
End Sub
Related
I have multiple workbooks in a single folder. All the workbooks share the same format and I wish to copy from the same range on the first worksheet in all workbooks and add this to a single worksheet of a newly created workbook.
The code so far:
Sub OpenAllCompletedFilesDirectory()
Dim Folder As String, FileName As String
Folder = "pathway..."
FileName = Dir(Folder & "\*.xlsx")
Do
Dim currentWB As Workbook
Set currentWB = Workbooks.Open(Folder & "\" & FileName)
CopyDataToTotalsWorkbook currentWB
FileName = Dir
Loop Until FileName = ""
End Sub
Sub AddWorkbook()
Dim TotalsWorkbook As Workbook
Set TotalsWorkbook = Workbooks.Add
outWorkbook.Sheets("Sheet1").Name = "Totals"
outWorkbook.SaveAs FileName:="pathway..."
End Sub
Sub CopyDataToTotalsWorkbook(argWB As Workbook)
Dim wsDest As Worksheet
Dim lDestLastRow As Long
Dim TotalsBook As Workbook
Set TotalsBook = Workbooks.Open("pathway...")
Set wsDest = TotalsBook.Worksheets("Totals")
Application.DisplayAlerts = False
lDestLastRow = wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1).Row
argWB.Worksheets("Weekly Totals").Range("A2:M6").Copy
wsDest.Range("A" & lDestLastRow).PasteSpecial
Application.DisplayAlerts = True
TotalsBook.Save
End Sub
This works - to a point. It does copy the correct ranges across and place the results one below another on the "Totals" worksheet of the "Totals" workbook, but it raises a 'Subscript out of range' error on:
argWB.Worksheets("Weekly Totals").Range("A2:M6").Copy
after data from the last workbook has been pasted.
How can I tidy this code so that it works without error?
I imagine there is scope to improve the code too.
I'd maybe do something like this.
Note you can just open the summary workbook once before looping over the files.
Sub SummarizeFiles()
'Use `Const` for fixed values
Const FPATH As String = "C:\Test\" 'for example
Const TOT_WB As String = "Totals.xlsx"
Const TOT_WS As String = "Totals"
Dim FileName As String, wbTot As Workbook, wsDest As Worksheet
'does the "totals" workbook exist?
'if not then create it, else open it
If Dir(FPATH & TOT_WB) = "" Then
Set wbTot = Workbooks.Add
wbTot.Sheets(1).Name = TOT_WS
wbTot.SaveAs FPATH & TOT_WB
Else
Set wbTot = Workbooks.Open(FPATH & TOT_WB)
End If
Set wsDest = wbTot.Worksheets(TOT_WS)
FileName = Dir(FPATH & "*.xlsx")
Do While Len(FileName) > 0
If FileName <> TOT_WB Then 'don't try to re-open the totals wb
With Workbooks.Open(FPATH & FileName)
.Worksheets("Weekly Totals").Range("A2:M6").Copy _
wsDest.Cells(wsDest.Rows.Count, "A").End(xlUp).Offset(1)
.Close False 'no changes
End With
End If
wbTot.Save
FileName = Dir 'next file
Loop
End Sub
Loop in folder is work, but don't work loop cells, don't work copy and paste selected data from 50 Excel workbooks to a single destination Excel workbook. I work in Windows Operating System. I have folder with 50 Excel files. I have single destiny Excel file. Data go from folder to 1 single Excel file.
Help, please.
Sub Combine()
Dim s As String, MyFiles As String
Dim endd As Integer, startt As Integer
Dim NewWb As Workbook
Dim newS As Worksheet
Dim i As Long
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set NewWb = Workbooks.Add
With NewWb
Set newS = NewWb.Worksheets("Лист1")
End With
endd = i * 10 + 1
startt = endd - 10
MyFiles = "C:\Users\User\Desktop\Nezavisimai\Papka2\"
s = Dir(MyFiles & "*.xlsx")
Do While s <> ""
[a1] = 0
If Dir = "" Then Exit Sub Else i = 1
Do
If Dir = "" Then Exit Do Else i = i + 1
Loop Until False
[a1] = i
With Workbooks.Open(MyFiles & s)
.Worksheets("Данные").Range("A1:C10").Copy
.Close SaveChanges:=False
End With
newS.Select
With newS
.Range("B" & startt & ":D" & endd).Paste
End With
s = Dir
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Option Explicit
Sub Combine()
Const FOLDER = "C:\Users\User\Desktop\Nezavisimai\Papka2\"
Dim wb As Workbook, wbNew As Workbook, wsNew As Worksheet
Dim filename As String, i As Long, n As Integer, rng As Range
Set wbNew = Workbooks.Add(xlWBATWorksheet) '1 sheet
Set wsNew = wbNew.Sheets(1)
Application.ScreenUpdating = False
i = 1
filename = Dir(FOLDER & "*.xlsx")
Do While filename <> ""
' open book and copy range
Set wb = Workbooks.Open(FOLDER & filename, False, True) ' no link update, read only
Set rng = wb.Sheets(1).Range("A1:C10")
rng.Copy wsNew.Range("B" & i)
i = i + rng.Rows.Count
' close book goto next
wb.Close False
n = n + 1
filename = Dir
Loop
' save combined
wbNew.SaveAs ThisWorkbook.Path & "\Combined.xlsx"
wbNew.Close False
Application.ScreenUpdating = True
MsgBox n & " files copied", vbInformation
End Sub
I'm trying to run macro from file "A: that include Sheet named "Filter_Criteria" on multiple Worksheets from specific folder.
In each "B%" Worksheet from selected folder data from Sheet "Data" shall be filtered by range Sheet "Filter_Criteria" from file A and send back to Sheet "Output" file "B%".
Issue is that non of files from folder is being filtered and I got to results in any "B%" Worksheet.
Macro goes from the beginning to the end with no issues.
Inside-macro code works fine while running it on each file with:
Set Data_sh = ActiveWorkbook.Sheets("Data")
Set Output_sh = ActiveWorkbook.Sheets("Output")
But I cannot understand what is wrong with current changes.
Sub RunOnAllFilesInFolder()
Dim folderName As String, eApp As Excel.Application, fileName As String
Dim wb As Workbook, ws As Worksheet, currWs As Worksheet, currWb As Workbook
Dim fDialog As Object: Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
Dim Filter_Criteria_Sh As Worksheet
Set currWb = ActiveWorkbook: Set currWs = ActiveSheet
Set Filter_Criteria_Sh = ThisWorkbook.Sheets("Filter_Criteria")
'Folder with Worksheets
fDialog.Title = "Select a folder"
fDialog.InitialFileName = currWb.Path
If fDialog.Show = -1 Then
folderName = fDialog.SelectedItems(1)
End If
'New Excel Process
Set eApp = New Excel.Application: eApp.Visible = False
fileName = Dir(folderName & "\*.*")
Do While fileName <> ""
'Update status bar to indicate progress
Application.StatusBar = "Processing " & folderName & "\" & fileName
Set wb = eApp.Workbooks.Open(folderName & "\" & fileName)
'Filter Data Macro
Dim Data_sh As Worksheet
Dim Output_sh As Worksheet
Set Data_sh = wb.Sheets("Data")
Set Output_sh = wb.Sheets("Output")
Output_sh.UsedRange.Clear
Data_sh.AutoFilterMode = False
Dim Emp_list() As String
Dim n As Integer
n = Application.WorksheetFunction.CountA(Filter_Criteria_Sh.Range("A:A")) - 2
ReDim Emp_list(n) As String
Dim i As Integer
For i = 0 To n
Emp_list(i) = Filter_Criteria_Sh.Range("A" & i + 2)
Next i
Data_sh.UsedRange.AutoFilter 2, Emp_list(), xlFilterValues
Data_sh.UsedRange.Copy Output_sh.Range("A1")
Data_sh.AutoFilterMode = False
MsgBox ("Data has been Copied")
wb.Close SaveChanges:=False
Debug.Print "Processed " & folderName & "\" & fileName
fileName = Dir()
Loop
eApp.Quit
Set eApp = Nothing
'Clear statusbar and notify of macro completion
Application.StatusBar = ""
MsgBox "Completed executing macro on all workbooks"
End Sub
I expect that 'Filter Data Macro will filter data in each file with filter criteria stored in Worksheet "A"
wb.Close SaveChanges:=False
You're not saving any changes you make to the workbooks.
I am currently using a piece of code to loop through all files in a folder and copy certain cells from each file into a master list. Currently there are a number of files being added into the folder every week. The code is then re-ran and all files are looped through again. One of the columns in the master list includes the filenames of previously looped files.
I would like to modify this code to ONLY loop through files that have not previously been looped through (i.e files with filenames that are not already included in the list created by previously running the code) and add data into the already existing list. Here is the code that I am currently using:
Sub CopyFromFolderExample()
' updated 2018-11-13 by OPE
' copies values from the first worksheet from all workbooks in a given folder
Dim strFolder As String, strFile As String, r As Long, wb As Workbook
Dim varTemp(1 To 6) As Variant ' variable to hold the values you want to copy
Application.ScreenUpdating = False
strFolder = "D:\Other\Barbara's Bakery Ltd\Inv\" ' include last path separator
' prepare the target worksheet
With ThisWorkbook.Worksheets(1)
.Range("A4:E" & .Rows.Count).ClearContents ' clear any existing content below the header row
r = .Range("A" & .Rows.Count).End(xlUp).Row ' last non-empty row in column A
End With
strFile = Dir(strFolder & "*.xl*") ' the first workbook found in the folder
Do While Len(strFile) > 0 ' repeat for each *.xl* file in the folder
Application.StatusBar = "Reading data from " & strFile & "..."
Set wb = Workbooks.Add(strFolder & strFile) 'open a copy of the workbook, just in case it is already open
With wb.Worksheets(1) ' specify source worksheet
' read input values
varTemp(1) = .Range("A13").Value
varTemp(2) = .Range("H8").Value
varTemp(3) = .Range("H9").Value
varTemp(4) = .Range("H36").Value
varTemp(5) = .Range("H37").Value
varTemp(6) = strFile
End With
wb.Close False ' close the workbook copy, not necessary to save any changes
' write the values from the source workbook to the target worksheet
With ThisWorkbook.Worksheets(1)
r = r + 1
.Range("A" & r & ":F" & r).Formula = varTemp
End With
strFile = Dir ' next source workbook
Loop
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub
Given that you appear to be storing your previously looped book names in Column F, you can just look for your current books name there. If the book name is there, we will skip the file. If the book name is not there, we will proceed with your code.
You can use a function Looped to check for your value which will return either
TRUE: The book has already been looped
FALSE: The book has not been looped
You then need to build your action statements around the result of this function. If Not Looped(strFile, ws) Then which translates to If Looped = FALSE Then proceed.
I also declared a worksheet variable ws to get rid of two of your with blocks and to be able to pass this variable into the below function.
Option Explicit
Sub CopyFromFolderExample()
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets(1)
Dim strFolder As String, strFile As String, r As Long, wb As Workbook
Dim varTemp(1 To 6) As Variant
Application.ScreenUpdating = False
strFolder = "D:\Other\Barbara's Bakery Ltd\Inv\"
ws.Range("A4:E" & ws.Rows.Count).ClearContents
r = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
strFile = Dir(strFolder & "*.xl*")
Do While Len(strFile) > 0
If Not Looped(strFile, ws) Then
Application.StatusBar = "Reading data from " & strFile & "..."
Set wb = Workbooks.Add(strFolder & strFile)
With wb.Worksheets(1)
varTemp(1) = .Range("A13").Value
varTemp(2) = .Range("H8").Value
varTemp(3) = .Range("H9").Value
varTemp(4) = .Range("H36").Value
varTemp(5) = .Range("H37").Value
varTemp(6) = strFile
End With
wb.Close False
r = r + 1
ws.Range(ws.Cells(r, 1), ws.Cells(r, 6)).Formula = varTemp
End If
strFile = Dir
Loop
Application.StatusBar = False
Application.ScreenUpdating = True
End Sub
Private Function Looped(strFile As String, ws As Worksheet) As Boolean
Dim Found As Range
Set Found = ws.Range("F:F").Find(strFile)
If Found Is Nothing Then
Looped = False
Else
Looped = True
End If
End Function
I would like to combine sheets with the same name & format from multiple files into a single summary sheet. I used this code to do it but I found it won't copy any filtered data or link cells. I also tried a couple codes to remove the filter, and the copied data becomes uncontinuous. Could someone look into this and help me? Thanks!
Sub Multiple_to_One()
Dim MyPath, MyName, AWbName
Dim Wb As Workbook, WbN As String
Dim G As Long
Dim Num As Long
Dim BOX As String
Dim lo As ListObject
Application.ScreenUpdating = False
MyPath = ActiveWorkbook.Path
MyName = Dir(MyPath & "\" & "*.xlsm")
AWbName = ActiveWorkbook.Name
Do While MyName <> ""
If MyName <> AWbName Then
Set Wb = Workbooks.Open(MyPath & "\" & MyName)
With Workbooks(1).ActiveSheet
Wb.Sheets(13).UsedRange.Copy .Cells(.Range("B65536").End(xlUp).Row + 1, 1)
Wb.Close False
End With
End If
MyName = Dir
Loop
MsgBox "All done.", vbInformation, "bingo"
End Sub
This is a bit of a brute force method, but seems to work:
Sub Summarize()
Dim sourcePath As String
Dim sourceName As String
Dim sourceWorkbook as Workbook ' Workbook to be copied
Dim sourceSheet as Worksheet
Dim thisWorkbookName as String
Dim copyCell as Range
Dim sourceBase as Range ' Summary starts here
Application.ScreenUpdating = False
sourcePath = ActiveWorkbook.Path
thisWorkbookName = ActiveWorkbook.Name
sourceName = Dir(MyPath & "\" & "*.xlsm")
Set sourceBase = Workbooks(1).ActiveSheet.Range("A1") ' Set to what you want
Do While sourceName <> ""
If sourceName <> thisWorkbookName Then
Set sourceWorkbook = Workbooks.Open(sourcePath & "\" & sourceName)
Set sourceSheet = sourceWorkbook.Sheets(13)
For Each copyCell In sourceSheet.UsedRange
copyCell.Copy sourceBase.Offset(copyCell.Row - 1, copyCell.Column - 1)
Next
Set sourceBase = sourceBase.Offset(sourceSheet.UsedRange.Rows.Count)
Set copyCell = Nothing
Set sourceSheet = Nothing
sourceWorkbook.Close False
End If
sourceName = Dir
Loop
Application.ScreenUpdating = True
MsgBox "All done.", vbInformation, "bingo"
End Sub
I'm just manually copying every cell in the used range into the target sheet. The base cell gets reset after each sheet, so it should just keep appending to the target sheet.
Caveat
I've only tested the inner code in my own sheet. I made adjustments on the fly to fit everything into your original logic. The entire function above should replace your original function. If you have errors, it's because I mistyped something. My apologies.
I set the autofiltermode to False. This worked in my case.
Wb.Sheets(13).AutoFilterMode = False
Here is the modified code.
Sub Multiple_to_One()
Dim MyPath, MyName, AWbName
Dim Wb As Workbook, WbN As String
Dim G As Long
Dim Num As Long
Dim BOX As String
Dim lo As ListObject
Application.ScreenUpdating = False
MyPath = ActiveWorkbook.Path
MyName = Dir(MyPath & "\" & "*.xlsm")
AWbName = ActiveWorkbook.Name
Do While MyName <> ""
If MyName <> AWbName Then
Set Wb = Workbooks.Open(MyPath & "\" & MyName)
Wb.Sheets(13).AutoFilterMode = False
ThisWorkbook.Activate
With Workbooks(1).ActiveSheet
Wb.Sheets(13).UsedRange.Copy .Cells(.Range("B65536").End(xlUp).Row + 1, 1)
Wb.Close False
End With
End If
MyName = Dir
Loop
Application.ScreenUpdating = True
MsgBox "All done.", vbInformation, "bingo"
End Sub