VBA Excel - copy object to last active sheet - excel

I have an object located on a different sheet, which I would like to copy to the last active sheet. Unfortunately, the code I have throws an error:
Object doesn't support this property or method
Sub AddCabinet()
Dim MooSheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Shapes.Range(Array("VHPOPA")).Select
Selection.Copy
CurrentSheet.Range("A1").Paste
End Sub
How can I copy an object to my previous current sheet? I have a few sheets with the same buttons.

.paste is a worksheet method, not a range method, that is where the error is coming from.
We can remove all the Selects to make this a bit cleaner.
Dim MooSheet As Worksheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Shapes("VHPOPA").Copy
CurrentSheet.Paste

Copy Shapes
Can you even get rid of Select and Activate when copying multiple shapes? I couldn't.
My idea was to copy the shape(s) and restore the worksheets initial selections.
The array is useful to copy multiple shapes. Note that if you don't explicitly use the array function as the parameter for the Shape.Range property, you need to evaluate the array by putting it into parentheses, if its variable is declared as a variant without parentheses i.e.:
Dim shpArr() As Variant... sws.Shapes.Range(shpArr).Select
' or:
Dim shpArr As Variant ... sws.Shapes.Range((shpArr)).Select
The Flow
Exit if the workbook containing this code (ThisWorkbook) is not the active workbook (ActiveWorkbook). Exit if the active sheet (ActiveSheet) is not a worksheet. Reference the active sheet i.e. the destination worksheet.
Reference the source worksheet. Exit if it's the destination worksheet.
Reference the destination Selection to restore after the job is done. Reference the destination cell. Activate it, if it's not active.
Select the source worksheet. Reference its Selection to restore it after the job is done. Select all shapes whose names are in the array and copy them using Selection.
Activate the destination worksheet and paste. Restore its initial selection using Select.
Select the source workbook to restore its initial selection using Select.
Select the destination worksheet.
Sub AddCabinet()
' Define constants.
Const sName As String = "Cab Templates"
Const dFirstCellAddress As String = "A1"
Dim shpArr() As Variant: shpArr = Array("VHPOPA")
'Dim shpArr() As Variant: shpArr = Array("Oval 1", "Oval 2")
' Reference ThisWorkbook's active sheet, the destination worksheet ('dws').
Dim wb As Workbook: Set wb = ThisWorkbook
If Not wb Is ActiveWorkbook Then Exit Sub ' another workbook is active
If Not TypeOf ActiveSheet Is Worksheet Then Exit Sub ' not a worksheet
Dim dws As Worksheet: Set dws = wb.ActiveSheet ' or 'ActiveSheet'
' Reference the source worksheet ('sws')
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
If sws Is dws Then Exit Sub ' source and destination are the same
'Application.ScreenUpdating = False
' Reference the destination cell ('dCell') and activate if not active.
Dim dSel As Object: Set dSel = Selection ' store
Dim dCell As Range: Set dCell = dws.Range(dFirstCellAddress)
If Not dCell Is ActiveCell Then dCell.Activate ' ensure it's active
' Copy.
sws.Select
Dim sSel As Object: Set sSel = Selection ' store
sws.Shapes.Range(shpArr).Select
Selection.Copy
' Paste.
With dws
.Activate
.Paste
End With
If Not dSel Is Nothing Then dSel.Select ' restore
sws.Select
If Not sSel Is Nothing Then sSel.Select ' restore
dws.Select
'Application.ScreenUpdating = True
End Sub

Before copying the object need to be there in that sheet, solve the problem...
try this...
Sub AddCabinet()
Dim MooSheet, CurrentSheet As Worksheet
Set CurrentSheet = ThisWorkbook.ActiveSheet
Set MooSheet = ThisWorkbook.Sheets("Cab Templates")
MooSheet.Select
MooSheet.Shapes.Range(Array("VHPOPA")).Select
Selection.Copy
CurrentSheet.Select
Range("A1").Select
ActiveSheet.Paste
End Sub
Hope it Helps...

Related

Copying a worksheet from one workbook to another into an existing worksheet

I have the following code:
Sub CopySheet()
Dim wb1 As Workbook
Dim wb2 As Workbook
Set wb1 = Workbooks("TestData.xlsm")
Set wb2 = Workbooks("AutoBE.xlsm")
wb1.Sheets("Sheet1").Copy After:=wb2.Sheets("Sheet1")
End Sub
This manages to copy Sheet1 from TestData into the AutoBE workbook. However, it creates a new sheet due to the Copy After
Is there a way to insert the data into an existing worksheet in AutoBE such as Sheet1 itself, assuming for simplicity that it is empty? I have looked everywhere online and forums and no luck. Is this even possible? With experience with python I fell as though it must be.
Alternatively is there a way to create this new sheet in AutoBE as this code does but then deleting all other sheets in AutoBE apart from the newly created one?
'Replace' Worksheet
Here is a simple example of how you could proceed.
If this doesn't work for you, share what's wrong with it so we can improve.
A Quick Fix
Sub CopyWorksheet()
' Source
Dim swb As Workbook: Set swb = Workbooks("TestData.xlsm")
Dim sws As Worksheet: Set sws = swb.Worksheets("Sheet1")
' Destination
Dim dwb As Workbook: Set dwb = Workbooks("AutoBE.xlsm")
' Reference the old worksheet...
Dim dwsOld As Worksheet: Set dwsOld = dwb.Worksheets("Sheet1")
' and store its name and its code name in variables.
Dim dName As String: dName = dwsOld.Name
Dim dCodeName As String: dCodeName = dwsOld.CodeName
' Copy.
sws.Copy After:=dwsOld
' Reference the new (copied) worksheet.
Dim dwsNew As Worksheet: Set dwsNew = dwsOld.Next
' Delete the old worksheet.
Application.DisplayAlerts = False ' delete without confirmation
dwsOld.Delete
Application.DisplayAlerts = True
' Rename the new worksheet and restore the old code name.
dwsNew.Name = dName
dwb.VBProject.VBComponents(dwsNew.CodeName).Name = dCodeName
End Sub

dynamic worksheet(s) data manipulation before copy to new workbook

I am trying to copy multiple worksheets to a new workbook. The worksheet names are defined in an array named sWorkSheetNames, which are then copied to a new workbook via swb.Worksheets(sWorkSheetNames).Copy.
The challenge I am facing is that the data on those worksheets is captured via complex indirect() formulas, which in turn pull data from a 100k+ long "DATA" worksheet. Now, via the above copy command, the indirect formulas break and throw a #REF error, which I can only circumvent by also copying the massive DATA sheet to the new workbook, then replace the formulas with values, and only then delete the DATA sheet, which is what I do not want to do.
My question now is this: how can I most effectively copy x number of sheets from the source workbook, replace the used range data to values, and then copy it to a new workbook, without knowing the worksheet name of the copied worksheets (copies in the same workbook are named "SomeName (x)" where x could be 1,2,3,4,etc depending on the number of copies)?
Thank you very much
Dim sWorkSheetNames() As Variant
sWorkSheetNames = Array("Daily Summary", "Monthly Summary")
' Reference the source workbook ('swb').
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
' Copy the worksheets to a new workbook.
swb.Worksheets(sWorkSheetNames).Copy
' Destination
' Reference this new workbook, the destination workbook ('dwb').
Dim dwb As Workbook: Set dwb = Workbooks(Workbooks.Count)
Dim dws As Worksheet
Dim drg As Range
' Convert formulas to values
' breaks the formulas since the indirect DATA sheet is not present in the new workbook
' copy paste to value needs to happen in the swb before copy
For Each dws In dwb.Worksheets
Set drg = dws.UsedRange
drg.Value = drg.Value
Next dws
Copy Worksheets From a List
A Quick Fix
Replace
drg.Value = drg.Value
with
drg.Value = swb.Worksheets(dws.Name).Range(drg.Address).Value
Optionally
To get the worksheets in the order they appear in the array, copy each worksheet separately.
Sub ExportWorksheets()
' Write the worksheet names to a variant array.
Dim sWorkSheetNames() As Variant
sWorkSheetNames = VBA.Array("Daily Summary", "Daily Report")
' 'VBA.' ensures a zero-based array ('Option Base' related).
' Reference the source workbook ('swb').
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
' Declare additional variables.
Dim sws As Worksheet, srg As Range
Dim dwb As Workbook, dws As Worksheet, drg As Range
Dim n As Long
For n = 0 To UBound(sWorkSheetNames)
' Reference the source worksheet ('sws').
Set sws = swb.Worksheets(sWorkSheetNames(n))
' Check if it's the first worksheet to be copied and copy accordingly.
If n = 0 Then ' is the first worksheet
' Copy the source worksheet to a new single-worksheet workbook.
sws.Copy
' Reference this new workbook, the destination workbook ('dwb').
Set dwb = Workbooks(Workbooks.Count)
Else ' is not the first worksheet
' Copy the source worksheet to the end of the destination workbook.
sws.Copy After:=dwb.Sheets(dwb.Sheets.Count)
End If
' Reference the destination worksheet ('dws').
Set dws = dwb.Worksheets(dwb.Worksheets.Count)
' Reference the destination (used) range ('drg').
Set drg = dws.UsedRange
' Reference the source (used) range ('srg').
Set srg = sws.Range(drg.Address)
' Copy values (by assignment).
drg.Value = srg.Value
Next n
' Continue to save the destination workbook...
dwb.Saved = True ' just for easy closing while testing this code
End Sub
If you copy cells formulas, it is not possible anymore to transform their resulted value (error, or not) in the before copying ones.
That's why the copying must be done for the cells value from the source sheet. Automatically creating a workbook containing the two sheets, cannot handle the formulas aspect. It is necessary to do it sheet by sheet, but not using clipboard, the code should be fast enough:
Sub copySheets()
Dim sWorkSheetNames() As Variant
sWorkSheetNames = Array("Sheet151", "Sheet152") ' Array("Daily Summary", "Monthly Summary")
' Reference the source workbook ('swb').
Dim swb As Workbook: Set swb = ThisWorkbook ' workbook containing this code
' Reference this new workbook, the destination workbook ('dwb').
Dim dwb As Workbook, shNo As Long, i As Long, sh As Worksheet
Set dwb = Workbooks.Add 'create a new workbook
shNo = dwb.Worksheets.count 'extract its (default) number of sheets
For i = 0 To UBound(sWorkSheetNames) 'iterate between the sheet names array:
If i + 1 <= shNo Then
Set sh = dwb.Worksheets(i + 1) 'use an existing sheet
Else
Set sh = dwb.Worksheets.Add(After:=dwb.Worksheets(dwb.Worksheets.count)) 'insert a new sheet
End If
sh.name = sWorkSheetNames(i) 'name the sheet to be used for copying
With swb.Worksheets(sWorkSheetNames(i)).UsedRange
sh.Range("A1").Resize(.rows.count, .Columns.count).Value = .Value 'copy the cells value
With sh.Range("A1").Resize(.rows.count, .Columns.count)
.EntireColumn.AutoFit 'a little format. Other features can be added here, if necessary
End With
End With
Next
End Sub
If you always need copying only two sheets, the copying itself can be simplified. I designed the code to also accept more than existing number of sheets in the new workbook (inserting new ones).

How can I design the code in VBA in order to refer to a previously already newly created workbook in Excel?

How can I refer in VBA to a previously newly created workbook within the same macro? For example, I copy something from A2 in the active workbook, then I create a new workbook, paste there in cell B3, return to the first workbook, copy cell A3, return again to the newly created workbook and paste in in cell B4.
So, what I need is the code for this part of the sentence: "return again to the newly created workbook"
My code till now is this:
`Selection.Copy`
`Workbooks.Add`
`Range("B3").Paste`
`Windows("First_WorkBook.xlsm").Activate`
`Range("A3").Select`
`Selection.Copy`
The last two lines are missing: returning to the new workbook and pasting there.
Can you please help me with this issue?
Please, try the next code. You should also declare the sheets where the ranges will be copied:
Sub testNewWBCopy()
Dim actWb As Workbook, newWb As Workbook, shAct As Worksheet, shNew As Worksheet
Set actWb = ActiveWorkbook
Set shAct = actWb.Sheets(1)
Set newWb = Workbooks.Add
Set shNew = newWb.Sheets(1)
shAct.Range("A2").Copy Destination:=shNew.Range("B3")
shAct.Range("A3").Copy Destination:=shNew.Range("B4")
End Sub
And it is good to avoid selecting, activating, if possible... They only consume Excel resources and make the code slower.
Copy from One Worksheet to Another (in a Different Workbook)
Using variables will do the trick.
Option Explicit
Sub CopyCells()
' Destination
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets("Sheet1")
' Source
Dim swb As Workbook: Set swb = Workbooks("First_Workbook.xlsm")
' To avoid an error occuring if the workbook is not open, you could
' replace the previous line with the following code block:
' On Error Resume Next
' Dim swb As Workbook: Set swb = Workbooks("First_Workbook.xlsm")
' On Error GoTo 0
' If swb Is Nothing Then
' MsgBox "The workbook is not open.", vbCritical, "CopyCells"
' Exit Sub
' End If
Dim sws As Worksheet: Set sws = swb.Worksheets("Sheet1")
' Copy
sws.Range("A2").Copy
dws.Range("B2").PasteSpecial
sws.Range("A3").Copy
dws.Range("B3").PasteSpecial
Application.CutCopyMode = False
' In this particular case you would rather do:
' sws.Range("A2:A3").Copy
' dws.Range("B2:B3").PasteSpecial
' Application.CutCopyMode = False
' Or:
'sws.Range("A2:A3").Copy dws.Range("B2:B3")
' Or (for copying values only):
'dws.Range("B2:B3").Value = sws.Range("A2:A3").Value
End Sub

VBA Copy and Paste Formatting for all Worksheet

I try to write really simple script to copy original worksheet (ORIGINAL_NOCHANGE) and paste the formatting only other sheet.
In the ORIGINAL_NOCHANGE, there are some column merged together, and some column having the conditional formatting.
This is the original structure of ORIGINAL_NOCHANGE :
COPY1 and COPY2 are the copy of ORIGINAL_NOCHANGE, but has no format like the original one (my Python script cannot copy the Excel formatting).
After I run my VBA script :
Sub TrySecond()
Dim ws As Worksheet
'Worksheets("ORIGINAL_NOCHANGE").Activate
Worksheets("ORIGINAL_NOCHANGE").Range("A1:AA71").Copy
For Each ws In Worksheets
If ws.Name <> "ORIGINAL_NOCHANGE" Then
'ws.Range("AC1") = "Are You Kidding Me"
Range("A1:P17").Select
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End If
Next
End Sub
the ORIGINAL_NOCHANGE has been changed into this structure, which I really don't want :
but nothing happend in COPY1 and COPY2!
Note that my python script will copy hundreds of ORIGINAL_NOCHANGE worksheet but due to the limitation of package inside, it couldn't copy the formatting.
Putting here as somebody might be suggesting me to copy the original manually.
I'm not sure what's the mistake in my script. Can you please help?
Thanks a lot!
Formats to New Worksheets
Adjust the values in the constants section (and the workbook).
Option Explicit
Sub FormatsToNewWorksheets()
' Define constants.
Const sName As String = "ORIGINAL_NOCHANGE"
Const dNamesList As String = "COPY1,COPY2"
' Create a reference to the workbook containing this code.
Dim wb As Workbook: Set wb = ThisWorkbook
' Create a reference to the Source Worksheet.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
' Write the names from the list to the Destination Names Array.
Dim dNames() As String: dNames = Split(dNamesList, ",")
' Declare additional variables.
Dim dws As Worksheet ' (Current) Destination Worksheet
Dim n As Long ' Destination Names Counter
' Loop through the elements (names) of the Destination Names Array.
For n = 0 To UBound(dNames)
' Attempt to create a reference to the (current) Destination Worksheet.
On Error Resume Next
Set dws = wb.Worksheets(dNames(n))
On Error GoTo 0
' Delete the (current) Destination Worksheet if it exists.
If Not dws Is Nothing Then ' exists
Application.DisplayAlerts = False
dws.Delete
Application.DisplayAlerts = True
'Else ' doesn't exist
End If
' Create the (current) Destination Worksheet
' (a copy of the Source Worksheet)
' after all existing sheets (at the last position).
sws.Copy After:=wb.Sheets(wb.Sheets.Count)
' Modify the (current) Destination Worksheet.
With ActiveSheet
.Name = dNames(n)
.UsedRange.ClearContents ' or not?
End With
Next n
End Sub
Right click on your worksheet, and select Move or Copy then tick create a copy, then you can create as many sheets as you want with the same format without VBA ....and you can create this worksheet to other workbook also....
If you still prefer VBA code, here is the function you can use, same as what i am doing just now:
Sub Macro1()
Sheets("Sheet1").Select
Sheets("Sheet1").Copy After:=Sheets(1)
End Sub

Copy from multiple sheets But not all into one master from last row

Still new to VBA. I’m trying to copy entire rows from multiple sheets (excluding a few). All sheets are set up the same with headers. I’ve tried using case as you can see below and copy to last row.
I’m not sure how or why I’ve gone wrong.
Any help is appreciated.
Sub copyall()
Dim wb As Workbook 'Workbook object - Always good to work with object variables
Dim sht As Worksheet 'Object for handling worksheets in loop
Dim trg As Worksheet 'Master Worksheet
Dim rng As Range 'Range object
Set wb = ActiveWorkbook 'Working in active workbook
Set trg = wb.Worksheets("all_rs_tenancies")
Application.ScreenUpdating = False
'We can start loop
Select Case Name
Case "data_supply", "Options", "all_rs_tenancies"
Case Else
'Data range in worksheet - starts from second row as first rows are the header rows in all worksheets
sht.Range(sht.Range("A2:AA2"), sht.Range("A2:AA2").End(xlDown)).Copy
'Put data into the Master worksheet
trg.Range("A", Rows.Count).End(xlDown).Offset(1, 0).PasteSpecial xlPasteValuesAndNumberFormats
End Select
Application.ScreenUpdating = True
End Sub
You're missing the code to loop through all worksheet; using For Each will set sht. Name needs a reference to the object (i.e. sht). I wouldn't use the Select Case statement to exclude the three sheets (and If would do) ... but have left it assuming you're going to do something else in that code. This at least will compile. You can debug from here if needed.
Option Explicit
Sub copyall()
Dim wb As Workbook 'Workbook object - Always good to work with object variables
Dim sht As Worksheet 'Object for handling worksheets in loop
Dim trg As Worksheet 'Master Worksheet
Dim rng As Range 'Range object
Set wb = ActiveWorkbook 'Working in active workbook
Set trg = wb.Worksheets("all_rs_tenancies")
Application.ScreenUpdating = False
'We can start loop
For Each sht In wb.Worksheets
Select Case sht.Name
Case "data_supply", "Options", "all_rs_tenancies"
Case Else
'Data range in worksheet - starts from second row as first rows are the header rows in all worksheets
sht.Range(sht.Range("A2:AA2"), sht.Range("A2:AA2").End(xlDown)).Copy
'Put data into the Master worksheet
trg.Range("A", Rows.Count).End(xlDown).Offset(1, 0).PasteSpecial xlPasteValuesAndNumberFormats
End Select
Next
Application.ScreenUpdating = True
End Sub

Resources