VBA Macro: Copying worksheets from one Excel file to another - vba

I need help on copying worksheets from one excel workbook to another. Currently, this is my code but it does not run:
Sub Code()
Workbooks.Open Filename:="C:\Users\xxx\Desktop\w1.xlsm"
Sheets (Array("Sheet1", "Sheet2"))
Copy after:=Workbooks("w2.xlsm").Sheets(Sheets.Count)
Workbooks("Client Info Template.xlsm").Close savechanges:=False
End Sub

Instead of Sheets... and Copy ... as two lines, try a single line:
Sheets(Array("Sheet1", "Sheet2")).Copy After:=Workbooks("w2.xlsm").Sheets(Sheets.Count)
This probably still won't work, or at least not reliably, because Sheets.Count may exceed the count of sheets in the destination workbook, so it is better to fully qualify all of your objects:
Sub Code()
Dim w1 as Workbook, w2 as Workbook
Set w1 = Workbooks.Open(Filename:="C:\Users\xxx\Desktop\w1.xlsm")
Set w2 = Workbooks.Open(Filename:="C:\Users\xxx\Desktop\w2.xlsm") '## Modify as needed
w1.Sheets(Array("Sheet1", "Sheet2")).Copy After:=w2.Sheets(w2.Sheets.Count)
End Sub

Related

Excel synchronize workbooks with vba

I'd like to ask if you could help me with copying some worksheet data from workbook A into my active workbook (workbook B)
I have the following code in the main workbook to copy the data from workbook A
Public Sub Worksheet_Activate()
test
End Sub
Sub test()
Dim Wb1 As Workbook
Dim MainBook As Workbook
'Open All workbooks first:
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm")
'Set MainBook = Workbooks.Open(Application.ActiveWorkbook.FullName)
Set MainBook = Application.ActiveWorkbook
'Now, copy what you want from wb1:
Wb1.Sheets("Projekte").Cells.Copy
'Now, paste to Main worksheet:
MainBook.Worksheets("Projekte").Range("A1").PasteSpecial xlPasteAll
Application.CutCopyMode = False
'Close Wb's:
Wb1.Close SaveChanges:=False
End Sub
I know, that it opens worksheet A and that it highlights and copys the data.
The script wont paste it into worksheet B (where the script is executed from)
Anybody know what i did wrong?
Kindest regards, and thanks for any help !
You should set the Mainbook (destination) first before the origin (if you're going to use ActiveWorkbook).
'Set MainBook First
Set MainBook = ThisWorkbook
'Open All workbook:
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm")
Just for clarity, it's just me being OC on this one.
you have to properly reference your workbook and worksheet objects
if you have to paste the whole content of range (including formatting, comments, ...), then you want to code like follows (explanations in comments):
Option Explicit
Sub test()
Dim targetSheet As Worksheet
Set targetSheet = ActiveSheet 'store currently active sheet
Workbooks.Open("Z:\Folder\WorkbookA.xlsm").Sheets("Projekte").UsedRange.Copy Destination:=targetSheet.Range("A1") ' open the wanted workbook and copy its "Projekte" sheet used range to 'targetSheet (i.e.: the sheet in the workbook where it all started) from its cell A1
ActiveWorkbook.Close SaveChanges:=False ' close the currently active workbook (i.e. the just opened one)
End Sub
if you only need to paste values, then this is the way to go (much faster!):
Option Explicit
Sub test()
Dim targetSheet As Worksheet
Set targetSheet = ActiveSheet 'store currently active sheet
With Workbooks.Open("Z:\Folder\WorkbookA.xlsm").Sheets("Projekte").UsedRange ' open the wanted workbook and reference its sheet "Projekte" used range
targetSheet.Range("A1").Resize(.Rows.Count, .Columns.Count).Value = .Value
.Parent.Parent.Close SaveChanges:=False 'close the parent workbook of referenced range (i.e., the newly opened workbook)
End With
End Sub
My recommendation is never to use ActiveWorkbook.
In most cases when people use ActiveWorkbook they actually meant to use ThisWorkbook. The difference is:
ActiveWorkbook is the currently selected one which is "on top of the screen" in exact that moment when your code runs. That can be any workbook the user just clicked on while your code runs. So you never can be 100% sure to get the right workbook.
ThisWorkbook is the actual workbook your code runs at the moment. And this doesn't change ever. So this is a well defined reference and no gamble about which workbook is on top at the moment.
About why your approach did not work
Set Wb1 = Workbooks.Open("Z:\Folder\WorkbookA.xlsm") 'this line makes WorkbookA the active one
Set MainBook = Application.ActiveWorkbook 'this makes MainBook = WorkbookA
Therefore a simple Set MainBook = Application.ThisWorkbook should work here.
Another recommendation
Sheets and Worksheets is not the same. Make sure you never use Sheets when you can use Worksheets.
Sheets contains worksheets and charts
Worksheets contain only worksheets
An example Sheets(1).Range("A1") fails if it is a chart.

Excel VBA: How to activate a workbook without its complete name?

I have multiple excel workbooks open. I want to activate a workbook which has "Final" in its name.
Example: I have three open workbooks called "Workbook1.xlsx", "worKbook2.xlsm" and "workbookFinal.xlsx" open at the same time.
My VBA code is in "Macro.xlsm". Using VBA I want to activate the workbook which has "Final" in it. FYI .. all workbooks are in different paths.
Try the code below, using the Like Operator with the wild-card *.
Option Explicit
Sub FindFinalWorkbook()
Dim wb As Workbook
' loop through all open workbooks
For Each wb In Application.Workbooks
If wb.Name Like "*Final*" Then '< -- check if workbook name is Like *Final*
wb.Activate
Exit For
End If
Next wb
End Sub
loop through Workbooks collection until finding the right named workbook:
Sub wbs()
Dim wb As Workbook
For Each wb In Workbooks
If InStr(wb.Name, "Final") > 0 Then
wb.Activate
Exit For
End If
Next
End Sub

Excel Macro: Setting a variable for a workbooks location?

I need to write a macro script that will copy data from one xml workbook and paste the values to another workbook. I've written the below macro that works fine, but i need to run this every week for several different documents so it means i have to replace the document name for each run.
Here's what i have so far:
Sub copying()
''''''Section 1''''''
Workbooks("Results_2561").Activate 'workbook i'm copying from
Range("B27:B41").Select
Selection.Copy
Workbooks("Overall_Results").Activate 'workbook i'm pasting to
Range("G2").PasteSpecial
''''''Section 2''''''
Workbooks("Results_2561").Activate
Range("C27:C41").Select
Selection.Copy
Workbooks("Overall_Results").Activate
Range("C2").PasteSpecial
''''''Section 3''''''
Workbooks("Results_2561").Activate
Range("I28:I40").Select
Selection.Copy
Workbooks("Overall_Results").Activate
Range("G17").PasteSpecial
''''''Section 4''''''
Workbooks("Results_2561").Activate
Range("J28:J40").Select
Selection.Copy
Workbooks("Overall_Results").Activate
Range("C17").PasteSpecial
End Sub
...
and that's only half the script. Is there a way i can declare a variable at the start and set it as the Workbooks file path so i can call that instead of typing and retyping it over and over again?
Preferably without using something like
Dim book1 as Workbook
Set book1 = Workbooks.Open("C://Results_2561.xlsm")
..as this keeps opening and closing the document when i run the script.
Thanks
since you're only interested in copying values you could use this helper Sub
Sub CopyValues(rngToCopyFrom As Range, rngToCopyTo As Range)
With rngToCopyFrom
rngToCopyTo.Resize(.Rows.COUNT, .Columns.COUNT).Value = .Value
End With
End Sub
to be exploited in your main code like follows:
Sub main()
Dim wsTo As Worksheet
Set wsTo = Workbooks("Overall_Results").ActiveSheet '<--| set the worksheet to paste values to
With Workbooks("Results_2561").ActiveSheet '<--| reference the worksheet to copy values from
CopyValues .Range("B27:B41"), wsTo.Range("G2")
CopyValues .Range("C27:C41"), wsTo.Range("C2")
CopyValues .Range("I28:I40"), wsTo.Range("G17")
CopyValues .Range("J28:J40"), wsTo.Range("C17")
End With
End Sub
should your relevant workbooks have more than one sheet, then just substitute
ActiveSheet
with
Worksheets("myRelevantShetName") '<--|change "myRelevantShetName" to the actual name of the relevant worksheet in each workbook
First of all, you don't have to Activate workbook every time when you want to copy/paste something. Just declare it in Range() property, for example:
''''''Section 1''''''
Workbooks("Results_2561").Sheets(1).Range("B27:B41").Copy
Workbooks("Overall_Results").Sheets(1).Range("G2").PasteSpecial
You can set Workbook as variable like:
Sub copying()
Dim wb1 As Workbook, wb2 As Workbook
Set wb1 = Workbooks("Results_2561")
Set wb2 = Workbooks("Overall_Results")
''''''Section 1''''''
wb1.Sheets(1).Range("B27:B41").Copy
wb2.Sheets(1).Range("G2").PasteSpecial
End Sub
Finally, as #A.S.H suggested, you can add a file dialog where you point which files you want to use. I have put it in some function (don't forget to put it in the same project as your copying macro):
Function strPath() As String
Dim intResult As Integer
Application.FileDialog(msoFileDialogFilePicker).Title = "Select file"
intResult = Application.FileDialog(msoFileDialogFilePicker).Show
If intResult <> 0 Then
strPath = Application.FileDialog(msoFileDialogFilePicker).SelectedItems(1)
End If
End Function
So your final code for Section 1 would look like:
Sub copying()
Dim wb1 As Workbook, wb2 As Workbook
MsgBox "Show file to copy form."
Set wb1 = Workbooks.Open(strPath())
MsgBox "Show file to paste in."
Set wb2 = Workbooks.Open(strPath())
''''''Section 1''''''
wb1.Sheets(1).Range("B27:B41").Copy
wb2.Sheets(1).Range("G2").PasteSpecial
End Sub

Create a Copy of Sheets from existing (unknown named) workbook into a new (unknown named) workbook

I have an existing workbook that will be used by multiple users (who will name the workbook uniquely - I can set one Workbook Codename if needed though, though don't know how to do this?).
I need to create a macro that opens a new workbook (which presumably I won't know the name of? as it could be 'Book1', 'Book2', 'Book3' etc?), then returns to the original workbook where the macro is stored, and copies several (can do one at a time if needed) sheets (that I DO know the names of these sheets) and pastes them as new sheets into the new workbook that I created at the start. The macro does not need to Save the file (in fact it's preferable that it doesn't as I want the user to save the new workbook wherever is most convenient for the user).
I have attempted to show what the macro would do, showing the obvious problem that I do not know the names of the workbooks I am creating/copying from/pasting into.
Any help, much appreciated!
Sub CopySheetintoNewWorkbook()
'Macro opens new / blank workbook (name unknown?)'
Workbooks.Add
'Macro goes back to original workbook where macro is saved (of which the name is unknown to the macro - i.e., users can and will change it)'
Windows("UnknownWorkbookName-1").Activate
'Macro goes to a sheet which can be named and will be known, so this is no problem'
Sheets("KnownSheet").Select
'Macro creates a copy of the sheet and pastes it as a new sheet within the new, unknown named workbook'
Application.CutCopyMode = False
Sheets("KnownSheet").Copy Before:=Workbooks("UnknownWorkbookName-2").Sheets(1)
End Sub
We want to copy Sheet1 and Sheet2.
This relies on a tiny trick:
Sub qwerty()
Dim wb1 As Workbook, wbNEW As Workbook
Set wb1 = ActiveWorkbook
Sheets("Sheet1").Copy
Set wbNEW = ActiveWorkbook
wb1.Sheets("Sheet2").Copy after:=wbNEW.Sheets(1)
End Sub
When the first .Copy is performed, a new workbook is created and it becomes the ActiveWorkbook ........the rest is easy.
EDIT#1:
If we have a group of sheets to be copied, then we can create an array of sheet names and loop through the array, copying one sheet at a time:
Sub qwerty()
Dim wb1 As Workbook, wbNEW As Workbook
Dim ary() As String, s As String, i As Long
s = "Larry,Moe,Curly"
ary = Split(s, ",")
Set wb1 = ActiveWorkbook
i = 1
For Each a In ary
If i = 1 Then
Sheets(a).Copy
Set wbNEW = ActiveWorkbook
Else
wb1.Sheets(a).Copy after:=wbNEW.Sheets(1)
End If
i = 2
Next a
wbNEW.Activate
End Sub

Creating an Archive Macro Excel VBA

In this latest project the desire is to have a button & macro that will do the following:
When clicked the macro will copy all the data from the existing workbook & save it to another location. To create the copy of the workbook I will be using the following code below:
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:="C:\Data.xlsm"
Application.DisplayAlerts = True
This code was sourced from - http://goo.gl/t7qOyB
Once the copy has been archived, the data in the existing workbook must then be removed leaving all the formatting behind. How can removing the data but keeping the formatting be achieved?
Use the .ClearContents() property of Cells Collection
Sub ClearAll()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Cells.ClearContents
Next
End Sub
This code iterates through all sheets in the current workbook and deletes the values from cells keeping the formatting.
Update!
If you wanted to clear only specific range on each sheet then
Sub ClearAll()
Dim ws As Worksheet
For Each ws In Worksheets
ws.Range("A1:B20").ClearContents
Next
End Sub
This will clear only range A1:B20 on each sheet.