Copy and paste data from different workbooks to several cells - excel

I am new to VBA and I am trying to copy data from one workbook to another. In my "copying workbook", wb1 (.dbf format) I have 3 sets of data I want to copy to my "pasting workbook", wb2 (.xlsm format).
I need to copy three "chunks" (which I call bands) of data from one WB to the other. Band1 ranges from "C2:M5", Band2 from "N2:X5" and Band3 from "Y2:AI5".
I want the user to be able to choose where he is pasting each band, ideally by asking him to select only the first cell of the range for each band.
So far, I have the code showed below. It only copies and pastes one band at a time, which means I have to run it three times. My goal is to have a routine which copies and pastes the data all at once (running the code once) and that pastes the bands/"chuncks" whenever the user wants them to.
I hope this was clear enough. Thank you in advance for all your help!
Sub CopyData()
' Keyboard shortcut: Ctrl+d
Dim band As Integer
Dim wb1 As Workbook
Dim wb2 As Workbook
Set band = InputBox("Choose bands 1, 2 or 3:")
Set wb1 = Workbooks.Open("C:\Users\mmm\CopyFile.dbf") ' File I want to copy the data from
Set wb2 = Workbooks.Open("C:\Users\mmm\PasteFile.xlsm") ' File I want to paste my data to
If band = 1 Then
wb1.Worksheets(dbf_name).Range("C2:M5").Copy 'Range of Band1 to copy
wb1.Close savechanges:=False
Application.DisplayAlerts = True
Application.DisplayAlerts = False
ActiveSheet.Paste
Application.CutCopyMode = False
Range("A1").Select
ElseIf band = 2 Then
wb1.Worksheets(dbf_name).Range("N2:X5").Copy 'Range of Band2 to copy
wb1.Close savechanges:=False
Application.DisplayAlerts = True
Application.DisplayAlerts = False
ActiveSheet.Paste
Application.CutCopyMode = False
Range("A1").Select
ElseIf band = 3 Then
wb1.Worksheets(dbf_name).Range("Y2:AI5").Copy 'Range of Band3 to copy
wb1.Close savechanges:=False
Application.DisplayAlerts = True
Application.DisplayAlerts = False
ActiveSheet.Paste
Application.CutCopyMode = False
Range("A1").Select
End If
End Sub
[UPDATE WITH FINAL CODE]
Sub CopyData()
' Keyboard shortcut: Ctrl+d
Dim dbf_path As String
Dim dbf_name As String
Dim rCopy As Range
Dim i As Long
Dim rPaste As Range
Dim wb1 As Workbook
dbf_path = "C:\Users\mmm\CopyFile.dbf"
dbf_name = "filename_dbf"
Set wb1 = Workbooks.Open(dbf_path)
ThisWorkbook.Activate
Set rCopy = wb1.Worksheets(dbf_name).Range("C2:M5,N2:X5,Y2:AI5")
For i = 1 To rCopy.Areas.Count 'loop through each distinct block or area
Set rPaste = Application.InputBox("Enter starting cell for range " & i, Type:=8) 'invite paste cell, specifying range input
If rPaste.Count > 1 Then Set rPaste = rPaste(1) 'if more than one cell selected use the first one
rCopy.Areas(i).Copy rPaste 'paste
Next i
wb1.Close savechanges:=False
End Sub

Here's a simple exampleto show how you might set the paste destination for each block via an input box. Hopefully you can adapt it to your precise set up.
Sub x()
Dim rCopy As Range, i As Long, rPaste As Range
Set rCopy = Range("C2:M5,N2:X5,Y2:AI5") 'define ranges to copy
For i = 1 To rCopy.Areas.Count 'loop through each distinct block or area
Set rPaste = Application.InputBox("Enter starting cell for range " & i, Type:=8) 'invite paste cell, specifying range input
If rPaste.Count > 1 Then Set rPaste = rPaste(1) 'if more than one cell selected use the first one
rCopy.Areas(i).Copy rPaste 'paste
Next i
End Sub

Related

VBA Code to copy data from four source workbooks to master workbook based on last row that was not previously copied

I have a challenge on achieving the below project, kindly please assist:
I have four source workbooks with names(GK,SK,RJ and TB).
Each workbook(GK,SK,RJ and TB) have three worksheets with the same names(products, channels, and sales).
I have destination workbook called consolidated workbook with the same worksheets names(products, channels, and sales) like those of the four source workbooks.
All workbooks(source + destinations) are in the same folder.
Iam requesting VBA code that will copy data from each worksheet of all the four source workbooks and transfer/paste the data to worksheets in consolidated workbook based on the rows that were not previously copied from the last copy event.
Currently I have the below code but whenever I ran it copies everything from worksheets on the source workbooks and paste to worksheets in consolidated workbook which result to duplicated data.
All the source workbook have worksheets with the "DATE" as a first column in each worksheet table column.
Destination workbook also have the same worksheet names and the same columns structure on each worksheet are the same as of those source worksheet.
Kindly advise what should I amend so that the code will that will copy data from each worksheet of all the four source workbooks and transfer/paste the data to worksheets in consolidated workbook based on the rows that were not previously copied from the last copy event.
Sub Copy_From_All_Workbooks()
Dim wb As String, i As Long, sh As Worksheet
Application.ScreenUpdating = False
wb = Dir(ThisWorkbook.Path & "\*")
Do Until wb = ""
If wb <> ThisWorkbook.Name Then
Workbooks.Open ThisWorkbook.Path & "\" & wb
For Each sh In Workbooks(wb).Worksheets
sh.UsedRange.Offset(1).Copy '<---- Assumes 1 header row
ThisWorkbook.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Next sh
Workbooks(wb).Close False
End If
wb = Dir
Loop
Application.ScreenUpdating = True
End Sub
Kindly please see the amended code:
Sub Copy_From_All_Workbooks()
Dim wb As String, i As Long, sh As Worksheet, fndRng As Range,
start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As
Range
Application.ScreenUpdating = False
wb = Dir(ThisWorkbook.Path & "\*")
Do Until wb = ""
If wb <> ThisWorkbook.Name Then
Workbooks.Open ThisWorkbook.Path & "\" & wb
For Each sh In Workbooks(wb).Worksheets
On Error Resume Next
sh.UsedRange.Offset(1).Copy '<---- Assumes 1 header row
Set fndRng = sh.Range("A:A").Find(date_to_find,LookIn:=xlValues,
searchdirection:=xlPrevious)
If Not fndRng Is Nothing Then
start_of_copy_row = fndRng.Row + 1
Else
start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
End If
end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
Set range_to_copy = Range(start_of_copy_row & ":" & end_of_copy_row)
latest_date_loaded = Application.WorksheetFunction.Max(ThisWorkbook.Sheets(sh.Name).Range("A:A"))
ThisWorkbook.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
On Error GoTo 0
Application.CutCopyMode = False
Next sh
Workbooks(wb).Close False
End If
wb = Dir
Loop
Application.ScreenUpdating = True
End Sub
Kindly please see how consolidated workbook appear(the sheet names and column format are exactly the same as of the source workbooks.)
CONSOLIDATED WORKBOOK
The following line can be used to find the latest date loaded on your consolidated sheet:
latest_date_loaded = Application.WorksheetFunction.Max(ThisWorkbook.Sheets(sh.Name).Range("A:A"))
The following lines can be used on a worksheet (sh) to create a range (for copying) that starts after the latest_date_loaded down to the bottom of the table. You'll therefore need to ensure this is in date order.
Dim fndRng As Range, start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As Range
date_to_find = latest_date_loaded
Set fndRng = sh.Range("A:A").Find(date_to_find, LookIn:=xlValues, searchdirection:=xlPrevious)
If Not fndRng Is Nothing Then
start_of_copy_row = fndRng.Row + 1
Else
start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
End If
end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
Set range_to_copy = Range(start_of_copy_row & ":" & end_of_copy_row)
EDIT
Here is a rework of your code, using some of the lines/ideas I've mentioned above.
Sub Copy_From_All_Workbooks()
'declarations
Dim wb As String, i As Long, sh As Worksheet, fndRng As Range, _
start_of_copy_row As Long, end_of_copy_row As Long, range_to_copy As _
Range, latest_date_loaded As Date, consolidated_wb As Workbook
'turn off screen updating for user experience
'Application.ScreenUpdating = False
'set a reference to the consolidated workbook
Set consolidated_wb = ThisWorkbook
'read parent folder of consolidated workbook
wb = Dir(consolidated_wb.Path & "\*")
'perform this loop until no more files
Do Until wb = ""
'make sure it doesn't try to open consolidated workbook (again)
If wb <> consolidated_wb.Name Then
'open found source workbook
Workbooks.Open consolidated_wb.Path & "\" & wb
'cycle through each sheet (sh)
For Each sh In Workbooks(wb).Worksheets
'on that sheet, find the latest date already existing
latest_date_loaded = Application.WorksheetFunction.Max(consolidated_wb.Sheets(sh.Name).Range("A:A"))
'find the last occurence of that date in column A
Set fndRng = sh.Range("A:A").Find(latest_date_loaded, LookIn:=xlValues, _
searchdirection:=xlPrevious)
'if you find that date already then..
If Not fndRng Is Nothing Then
'set the top row to where you found it, plus one
start_of_copy_row = fndRng.Row + 1
Else
'otherwise, it's a new sheet, start on row two
start_of_copy_row = 2 ' assuming row 1 has a header you want to ignore
End If
'find the end of the table, using column A's contents
end_of_copy_row = sh.Cells(sh.Rows.Count, "A").End(xlUp).Row
'make sure there's something to copy
If end_of_copy_row >= start_of_copy_row Then
'create a reference to the block of cells to copy
Set range_to_copy = sh.Range(start_of_copy_row & ":" & end_of_copy_row)
'copy that range
range_to_copy.Copy
'paste them, values only
consolidated_wb.Sheets(sh.Name).Cells(Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial xlPasteValues
'clear copy markings from screen
Application.CutCopyMode = False
Else
'otherwise, do nothing here
End If
Next sh
'close the source workbook
Workbooks(wb).Close False
End If
'get next potential filename
wb = Dir
Loop
'turn back on screen updating
Application.ScreenUpdating = True
End Sub

VBA copy and past loop

I am trying to write a macro that goes into an infinite amount of sheets and copies and pastes a data range from A10:E10, A11:E11 and so on until it hits a blank cell until pastes it into a new tab until it has gone through each sheet and grabbed the data. I have tried to use the code below, but it will only let me paste one cell and if I change the range to more than one it pastes over and leaves out data. Any Help would be greatly appreciated.
Dim sh As Worksheet
Dim wb As Workbook
Dim DestSh As Worksheet
Dim i As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb = ThisWorkbook
Set DestSh = wb.Sheets("Combined")
' Loop through worksheets that start with the name "20"
i = 4
For Each sh In ActiveWorkbook.Worksheets
If sh.Name = "Data" Then Exit Sub
sh.Range("E10").Copy
With DestSh.Range("AF" & i)
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
i = i + 1
Next

Loop Through Ranges in Another Workbook Based on Cell Value

I use the code below to loop through a range.
I need to change the sourceRange to a range in the Analysis v1 workbook.
In the Summary sheet of that workbook in cells B2 and B3 there are names of column headers in another sheet in that workbook called Data. The headers in the Data sheet are in row 2.
I would like to find the B2 and B3 column headers then loop through each column.
Option Explicit
Public Sub Process()
Dim targetWorkbook As Workbook
Dim summarySheet As Worksheet
Dim sourceRange As Range
Dim cell As Range
' Customize this settings
Set targetWorkbook = Workbooks("Analysis v1.xlsm")
Set summarySheet = ThisWorkbook.Worksheets("Summary")
Set sourceRange = summarySheet.Range("Q3:Q5")
Application.ScreenUpdating = False
' Loop through each cell in source range
For Each cell In sourceRange.Cells
' Validate that cell has a value
If cell.Value <> vbNullString Then
summarySheet.Range("F3").Value = cell.Value
' Execute procedure to create new sheet
CreateNewSheet
End If
Next cell
Application.ScreenUpdating = True
End Sub
Hi please check the following codes for your ref. Just show method of how to add / save a workbook.
Sub aa()
Dim targetWorkbook As Workbook
Dim summarySheet As Worksheet
Dim sourceRange As Range
Dim cell As Range
' Customize this settings
'Set targetWorkbook = Workbooks("Analysis v1.xlsm")
Set summarySheet = ThisWorkbook.Worksheets("Summary")
Set sourceRange = summarySheet.Range("Q3:Q5")
Application.ScreenUpdating = False
'not very clear for your logic ******
'Loop through each cell in source range
For Each cell In sourceRange.Cells
' Validate that cell has a value
If cell.Value <> vbNullString Then
summarySheet.Range("F3").Value = cell.Value
' Execute procedure to create new sheet
End If
Next cell
' *************************
'Here is the demo of how to copy and save to a new workbook.
Set targetWorkbook = Workbooks.Add
Dim fName As String
fName = "Analysis v1.xlsm"
targetWorkbook.Sheets(1).Range("A1") = summarySheet.Range("F3").Value
Application.DisplayAlerts = False
On Error Resume Next
targetWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & fName, FileFormat:=52
targetWorkbook.Close SaveChanges:=True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

sheets stored in an array and paste them as values to new workbook, maintaining sheets' names and order

I'm trying to write this little macro to copy several sheets stored in an array and paste them as values to new workbook, maintaining sheets' names and order. I've found some solutions but not exactly matching my situation.
This is for excel macro where we try sending dashboard thru mail along with attachment but need to added sheet only paste values with same formatting
Option Explicit
Sub Send_Email_With_snapshot()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Summary")
ActiveWorkbook.RefreshAll
Worksheets(Array("Calculation", "Retailer Wise_Data", "TM Wise", "Channel_Base")).Copy
Worksheets("Calculation").Range("a1:Ax54").Copy
Worksheets("Calculation").Range("a1:Ax54").PasteSpecial _
Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
With ActiveWorkbook
.SaveAs Filename:="E:\Automation\New folder\" & "RAEO_Dashboard_MTD.xlsx", FileFormat:=51
.Close savechanges:=True
Application.DisplayAlerts = False
Dim lr As Integer
lr = sh.Range("A" & Application.Rows.Count).End(xlUp).Row
sh.Range("A1:T120").Select
With Selection.Parent.MailEnvelope.Item
.to = "xyz.com"
.cc = ""
.Subject = sh.Range("AN14").Value
.attachments.Add "D:\RAEO_Dashboard_MTD.xlsx"
.send
End With
Application.DisplayAlerts = False
ThisWorkbook.Save
Application.DisplayAlerts = True
End With
End Sub
I wasn't sure if you meant when you wrote "with same formatting". If by that you mean cells formatting (eg. color, size, borders, visible/hidden propertie, etc.) then I added another section at the end of this answer to address that. However, if you only need number formats to stay the same, here is how you could do it.
Paste values and number formats
The 2 key elements here are:
To use .PasteSpecial Paste:=xlPasteValuesAndNumberFormats to paste values and number formats at the same time.
Use a For loop to go over your array of sheets.
Implemented this would look like this:
Sub CopySheetsValuesAndNumberFormats()
ActiveWorkbook.RefreshAll 'In case you have Pivot Tables to refresh
Dim ListOfSheets() As Variant
ListOfSheets = Array("Calculation", "Retailer Wise_Data", "TM Wise", "Channel_Base") 'Example list based on the question
Dim SourceWorkbook As Workbook
Set SourceWorkbook = ThisWorkbook 'Or Workbooks("Workbook Name")
Dim DestinationWorkbook As Workbook
Set DestinationWorkbook = Workbooks.Add
Dim i As Long
For i = LBound(ListOfSheets) To UBound(ListOfSheets)
Dim SourceSheet As Worksheet
Set SourceSheet = SourceWorkbook.Worksheets(ListOfSheets(i))
Dim DestinationSheet As Worksheet
Set DestinationSheet = DestinationWorkbook.Worksheets.Add(After:=DestinationWorkbook.Worksheets(DestinationWorkbook.Worksheets.Count)) 'Insert in last position
DestinationSheet.Name = SourceSheet.Name
Dim SourceRange As Range
Set SourceRange = SourceSheet.UsedRange
Dim DestinationRange As Range
Set DestinationRange = DestinationSheet.Range(SourceRange.Address)
'Paste values and number formats
SourceRange.Copy
DestinationRange.PasteSpecial Paste:=xlPasteValuesAndNumberFormats
Application.CutCopyMode = False
Next i
'Delete initial sheets
For i = 1 To 3
On Error Resume Next
Application.DisplayAlerts = False
DestinationWorkbook.Worksheets("Sheet" & i).Delete
Application.DisplayAlerts = True
On Error GoTo 0
Next i
End Sub
Paste values and cells formatting
In order to copy the formatting, you are going to have to copy from all Cells as opposed to from the UsedRange in the first section of this answer. The reason is that some columns might have some formatting that apply to all the cells inside a column, but not all these cells will be part of the UsedRange.
The only part of the code that you need to replace from the code above is the one starting with "Paste values and number formats". You would need to replace this part with the following:
'Paste values and cells formatting
SourceSheet.Cells.Copy
DestinationSheet.Cells.PasteSpecial Paste:=xlPasteAll
SourceRange.Copy
DestinationRange.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False

How to copy mutiple sheets from one workbook to another; without copying VBA

I am trying to copy all sheets (7 sheets) from workbook1(wb1) to wb2. wb1 contains command buttons but I don't want them in my new workbook. I am using loop to copy individual sheets from one workbook to another. but error comes while copying to 2nd sheet. I am using the code as below :-
Public Sub CommandButton1_Click()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim i As Integer
i = 1
Set wb1 = ActiveWorkbook
Set ws1 = ActiveSheet
Set wb2 = Workbooks.Add
With wb2
.Title = "My Sales"
.Subject = "Sales"
.SaveAs Filename:="mysales.xls"
End With
For i = 1 To 7
Dim row As Long
Dim column As Long
wb1.Activate
wb1.Sheets(i).Activate
column = ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).column
row = ActiveSheet.Range("A" & Rows.Count).End(xlUp).row
Application.CutCopyMode = False
ActiveSheet.Range(Cells(1, 1), Cells(row, column)).Select
Selection.Copy
wb2.Sheets(i).Range("A1").PasteSpecial
Application.CutCopyMode = False
next i
End Sub
Loop is running succesfully for the first time but for i=2, code gives error
Sub M_snb()
thisworkbook.sheets(array("one","two","three","four","five","six","seven")).copy
do until activeworkbook.sheets("one").oleobjects.count=0
activeworkbook.sheets("one").oleobjects(1).delete
loop
activeworkbook.saveas "G:\OF\new.xlsx",51
End Sub

Resources