Copy multiple worksheets into a different workbook - excel

I want to have the VBA from workbook1 go into a specified folder, open the three workbooks that are within it, and copy the data from each one (each workbook within the folder only has one sheet with data) into workbook1.
I've looked around and alot of info for copying sheets; I can go in to the folder and copy the data if I have the workbook name and tab name, but these will change every time a new workbook is loaded (monthly).
Sub OpenWorkbook1()
'Open workbook
Workbooks.Open "P:\FSD\SUPPORT SERVICES\File Load\190731_CO.xls"
'Copy
Workbooks("190731_CO.xls").Worksheets("190731_CO").Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
'Paste
Workbooks("Dual Sub.xlsm").Worksheets("CO").Range("A2").PasteSpecial
Paste:=xlPasteValues
Application.CutCopyMode = False
Workbooks("190731_CO.xls").Close SaveChanges:=False
End Sub
The code above is ok, but I want to be able to open the workbooks each month, and the number (190731 in this case) will change monthly to a random number. There are 3 total workbooks I need to extract data from, the above only shows me collecting the data from one.

Based on what I gather from the description, the problem is the following.
The aim is to copy the content of the first sheet of three workbooks in a specified folder only containing these three workbooks into known workbook to sheets named after the letters following the last underscore.
This is actually not one problem, but three problems: find the workbooks, derive the correct sheet from the name and copy the content.
You have already dealt with the last problem, but in a not very generic way. The answers linked in the comments can help you with this further. However, since you are only concerned with the values, I would recommend to copy via an array.
Private Sub CopyValues(ByVal sourceRange As Excel.Range, ByVal targetRange As Excel.Range)
Dim copyArray as Variant
copyArray = sourceRange.Value
targetRange.Value = copyArray
End Sub
To get the name for the target sheet, you can use the VBA atring functions; in particular InstrRev Right and Split could be usefult. I will leave it to you to figure out a way to define a function Private Function TargetSheetName(ByVal sourceWorkbookName As String).
Using this information, you do the following.
Private Sub CopyFirstSheet(ByVal sourceWorkbook As Excel.Workbook, ByVal targetWorkbook As Excel.Workbook)
Dim sourceRange As Excel.Range
Set sourceRange = CopyRange(sourceWorkbook.Worksheets(1)
Dim targetSheetName As String
targetSheetName = TargetSheetName(targetWorkbook.Name)
Dim targetRange As Excel.Range
Set targetRange = targetWorkbook.Worksheets(targetSheetName).Range("A2")
End Sub
Here Private Function CopyRange(ByVal sourceWorksheet As Excle.WorkSheet) As Excel.Range is a function describing how you determine the copy range given the source worksheet.
Finally, there is the problem of finding the source workbooks. In the comments, it was suggested to use Dir. However, I would like to suggest a more readable approach. Unless you work on a Mac, you can refernce the library _Microsoft Scripting Runtime` under Tools->Refreences. This gives you access to the Scripting.FileSystemObject. You can use it as follows.
Private Sub CopyFromFolder(ByVal sourcePath As String, ByVal targetWorkbook As Excel.Workbook)
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
Dim file As Scripting.File
For Each file in fso.GetFolder(path).Files
Dim sourceWorkbook As Excel.Workbook
Set sourceWorkbook = Application.Workbooks.Open path & file.Name
CopyFirstSheet sourceWorkbook, targetWorkbook
sourceWorkbook.Close SaveChanges:=False
Next
End Sub
This assumes that only the three workbooks are in the folder. Otherwise, some more logic will be required.
I hope this is of help regarding the specific problem and in general on how to split such a problem into smaller problem that can be dealt with in separate procedures or functions.

Related

Copy a range from a closed workbook to a specific sheet

I am currently working on a VBA script to automate a excel sheet. The goal is to have the code open a file from using a file path in cell A2 on a sheet called Reports (the file path is dynamic and is formed using information from the sheet) , copy the data from the file for range A1:E200 and to paste the data into the original workbook on a sheet called HOURS starting at A1. At the moment i have gotten to the point where the file is opened but there is a "Mismatch" error when trying to copy the information across. Below I've attached the code used. I was hoping that someone would be able to help to make sense of the error! I am having the same problem with the close section as well. Note: I am a rookie on VBA so if you could be as clear as possible
Sub Button1_Click()
Call Test
Call Copy_Method
Call CloseWorkbook
End Sub
Sub Test()
Dim strFName As String
strFName = Sheet4.Range("A2").Value
Workbooks.Open Filename:=strFName
End Sub
Sub Copy_Method()
'Copy range to another workbook using Range.Copy Method
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set wb2 = ThisWorkbook
Set ws2 = wb2.Sheets("HOURS")
Set wb1 = ThisWorkbook.Worksheets("Reports").Range("A2")
Set ws1 = wb1.Sheets("Sheet")
ws2.Range("A1:E200") = ws1.Range("A1:E200").Value
End Sub
Sub CloseWorkbook()
Workbooks("venues_theeway_hours_August2020.XLS").Close SaveChanges:=True
End Sub
Have you tried this ?
ws2.Range("A1:E200").Value = ws1.Range("A1:E200").Value
You're making life quite difficult for yourself there, splitting the code out across 3 subs. Better to
rename the references to make them easier to differentiate source/destination.
keep it all together so the workbooks/worksheets can still be referenced as they're created:
Apologies if I've misread your requirements, my code does the following:
Reads the original workbook, sheet "Reports", range A2 for a filename.
Opens that filename as a 'source' workbook
Copies data from..
that 'source' workbook, sheet "Sheet", range A1:E200
..to original workbook, sheet "HOURS", range A1:E200
and then closes the 'source' workbook, unsaved as you've not made any changes.
Dim wbSource As Workbook
Dim wbDest As Workbook
Dim wsSource As Worksheet
Dim wsDest As Worksheet
Dim strFName As String
Set wbDest = ThisWorkbook
Set wsDest = wbDest.Sheets("HOURS")
strFName = wbDest.Worksheets("Reports").Range("A2").Value
Set wbSource = Workbooks.Open(strFName)
Set wsSource = wbSource.Worksheets("Sheet")
wsDest.Range("A1:E200").Value = wsSource.Range("A1:E200").Value
wbSource.Close SaveChanges:=False
I'm a little puzzled about your workbook close with save? Perhaps you actually want to close the source sheet unsaved and maybe save the destination sheet you're adding data to? In that case you'll need to add this line to the end of the above code.
wbDest.Close SaveChanges:=True

Extract specific cells from multiple closed workbooks

I have 500+ spreadsheets that I need to extract 5 rows from each one. They're all saved in the same folder. I just need to be able to create a code that runs through each file in the specified directory, extracts the first 5 rows of each file (only one worksheet per file), and paste the results all in one summarized worksheet.
This is the code I have so far (doesn't work as intended):
Public Sub CommandButton1_Click()
Dim mainBook As Workbook
Set mainBook = ActiveWorkbook
Dim fso As New Scripting.FileSystemObject
Dim fle As Scripting.File
Dim book As Workbook
For Each fle In fso.GetFolder("C:\dir").Files
Set book = Workbooks.Open(fle.Path)
Dim wks As Worksheet
For Each wks In book.Worksheets
wks.Range("A5:A10").Copy mainBook.Worksheets(1) 'copies to the start of the main workbook
Next
book.Close
Next
End Sub
Thank you.
wks.Range("A5:A10").Copy mainBook.Worksheets(1), you need to actually paste to a range, try
wks.Range("A5:A10").Copy mainBook.Worksheets(1).cells(mainBook.Worksheets(1).rows.count,"A").end(xlup).offset(1)

How to copy a range of cells

I am trying to copy data from a closed Excel file to the workbook I am currently in. I would like to browse for the file and then have the macro do the rest.
I am getting an error in the target workbook that says
"Application-defined or object defined error."
Below is what I have so far. Target is the workbook I am opening and y is the current one, or should be at least!
Option Explicit
Sub getfilename()
Dim myFilePath As String
Dim target As Workbook, y As Workbook
myFilePath = Application.GetOpenFilename()
'copying
Set target = Workbooks.Open(myFilePath)
target.Sheets("Sheet1").Range("R9C2:R20C2").Copy
'pasting
Set y = ActiveWorkbook
y.Sheets("Adjustment").Cells("R57C4").PasteSpecial
'close
target.Close
End Sub
The RANGE object expects A1 notation rather than R1C1 notation. The CELLS object can use row number and column number (though you don't need the R..C.. structure there, either.
Sub getfilename()
Dim myFilePath As String
Dim target As Workbook, y As Workbook
myFilePath = Application.GetOpenFilename()
Set y = ActiveWorkbook
'copying
Set target = Workbooks.Open(myFilePath)
'Here we're using the A1 notation
target.Sheets("Sheet1").Range("B2","B9").Copy
'Here we're using the Row & Column numbers notation
y.Sheets("Adjustment").Cells(57, 4).PasteSpecial
'close
target.Close
End Sub
In addition, you don't actually need to use the Copy and PasteSpecial methods to duplicate values. It's not too big a deal in a small macro like this, but in a larger process you'd find it more efficient to duplicate the values directly using something like:
target.Range("A1","A10").value = source.Range("A1","A10").value

Copy one worksheet to multiple identical workbooks using VBA

I have a workbook containing one worksheet ("DB Output" or Sheet 34) which I would like to copy to several (around 45) files in within the same folder.
None of the target files have an existing sheet named "DB Output" - the objective is to find a way to insert a copy of this sheet, forumlas and all, into each one.
The range of cells on that sheet that needs to be copied to a sheet of the same name in each book is A1:PE5
The sheet contains references to cells in the book it is currently in, however as the files which I am seeking to copy the worksheet to all share the same template, I want the references to be to the local file, not the original one.
I've tried looking at RDBMerge, however it seems that is for merging sheets, and while I do want to do that, it will not help me do it multiple times quickly.
Likewise I have looked on SO for similar situations, this is the closest, however my attempts to adapt that code have failed as I only have a single workskeet. Never the less, as it is always useful to inlcude what you have already tried, here is my existing attempt:
Option Explicit
Public Sub splitsheets()
Dim srcwb As Workbook, trgwb As Workbook
Dim ws As Worksheet, t1ws As Worksheet
Dim rng1 As Range
Dim trgnm As String
Dim fpath As String
Application.ScreenUpdating = False
'--> Set this to the location of the target workbooks
fpath = "C:/file/path/"
Set srcwb = ThisWorkbook
For Each ws In srcwb.Worksheets
trgnm = ws.Name
'--> Change A1:B3 to the range to be copied to inside page
Set rng1 = srcwb.Sheets(trgnm).Range("A1:PE5")
Set trgwb = Workbooks.Open(fpath & trgnm & ".xlsm")
With trgwb
Set t1ws = .Sheets("DB Output")
End With
'--> Change A1:B3 to the range where you want to paste
rng1.Copy t1ws.Range("A1:PE5")
trgwb.Close True
Next
Application.ScreenUpdating = True
End Sub
However this starts with the first sheet in the workbook that contains DB Output (the sheet to be copied) and gives an error that "NameOfSheet1.xlsm" does not exist in that directory (which it does not).
Any help is much appreciated.
This should copy from the active workbook to all files in a directory. If you need help modifying it to fit your specific use let me know!
Edit: fixed code to only copy A1:PE5 and save each workbook.
Sub Example()
Dim path As String
Dim file As String
Dim wkbk As Workbook
path = "C:\Test\"
file = Dir(path)
Application.DisplayAlerts = False
Do While Not file = ""
Workbooks.Open (path & file)
Set wkbk = ActiveWorkbook
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "DB Output"
ThisWorkbook.Sheets("DB Output").Range("A1:PE5").Copy Destination:=wkbk.Sheets("DB Output").Range("A1")
wkbk.Save
wkbk.Close
file = Dir
Loop
Application.DisplayAlerts = True
End Sub
Please note that I did not add error handling so this could break if the active workbook is included in the directory you are trying to copy or if a sheet with the same name already exists in the workbook. If this is an issue let me know and I will add error handling.

Importing data from many excel workbooks and sheets into a single workbook/table

I have 54 excel files with three sheets each, each sheet has a different amount of data entries but they are set out in a identical format, and I need to import the data from those sheets into a single workbook using VBA.
Is there any way I can program it so I can build the loops to import the data, but without having to write in each workbook name for each loop/sheet? I think I can use the call function, but I don't know how to make the loop codes independent of the workbook name they apply to.
Thank you so much in advance,
Millie
Sure just loop over the workbooks in a folder open them and then loop over their sheets. Depending on slight differences in format you might need to do some extra work when importing.
Sub ImportWorkbooks(destination as workbook, importFolderPath As String)
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get the folder object associated with the directory
Set objFolder = objFSO.GetFolder(importFolderPath)
'Loop through the Files collection and import each workbook
For Each objFile In objFolder.Files
Dim source As Workbook
Set source = Application.Workbooks.Open(objFile.Path, ReadOnly:=True)
ImportWorkbook source, destination
wb.Close
Set wb = Nothing
Next
Set objFolder = Nothing
Set objFile = Nothing
Set objFSO = Nothing
End Sub
Sub ImportWorkbook(source As Workbook, destination as Workbook)
Dim sheet As Worksheet
'Import each worksheet
For Each sheet In source.Sheets
ImportWorksheet sheet, destination
Next sheet
End Sub
Sub ImportWorksheet(sheet As Worksheet, destination as Workbook)
'Perform your import logic for each sheet here (i.e. Copy from sheet and paste into a
'sheet into the provided workbook)
End Sub
Basic usage would be something like the following to import into the current workbook:
ImportWorkbooks ThisWorkbook, "c:\path\to\folder\containing\workbooks\to\import"
It only takes two things:
An array with the workbook file names in it, e.g.
dim books
books = array("book1.xls","book2.xls",....)
Then your loop code looks something like
dim myBk as Workbook
dim bkFile as string
For Each bkFile in books
myBk = Workbooks.Open(bkFile, ReadOnly)
myBk.Activate
'Transfer cells from myBk to target workbook
target.cells(--).Value = myBk.Sheets("myStuff").Cells(--)
...
Next
I can't help you with the detail. You'll need to change the target.cells argument for each pass through the loop to shift the data destination.

Resources