copy and paste error causing workbook to crash - excel

I'm having an issue with copy and pasting from one spreadsheet to another.
I am using the following code:
Sub LoadnH()
Dim NF As Workbook
Dim shtMain As Worksheet
Set shtMain = Worksheets("Main")
Dim filePath As String
Dim strFileName As Variant
strFileName = Application.GetOpenFilename("All Files (*.*), *.*", , "Select File to Import", , False)
shtMain.Range("filePath").Value = strFileName
If strFileName <> False Then
Set NF = Application.Workbooks.Open(strFileName)
Application.CutCopyMode = False
NF.Sheets("Summary").Copy
Application.DisplayAlerts = False
NF.Close False
Dim nH As Worksheet
Set nH = Worksheets("Hedge Data")
nH.Activate
With nH
.Cells.Clear
.Pictures.Delete
.Range("A1").Select
.PasteSpecial xlPasteValues
End With
End If
End Sub
The code errors out at the following point
.PasteSpecial xlPasteValues
The code show a runtime error '1004':
Method 'PasteSpecial' of object'_Worksheet' failed
how can I fix this so this error? Many times when it hits this error excel will crash and shutdown as well.

To Avoid Select and other similar methods you can assign your value of the destination range with the value from your source range.
You are using the Worksheet.Copy method which copies an entire Worksheet not the data in a Range of the worksheet. This will be creating a new copy of your source worksheet each time you run the code but not copying the data of the worksheet to the clipboard. (NB: below demonstrates using the Before parameter which dictates where the Worksheet will be copied to).
The Range.Copy method will copy the defined range's data to the clipboard (unless you specify the destination parameter).
Rather than using Copy/Paste etc. you can assign the value of the destination range with the value from your source range.
These examples below are all for demonstration of the above points and are tested using 2 new workbooks with default names for the workbooks and worksheets.
E.g 1
Sub WorksheetCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Copy DestinationWorksheet
End Sub
The result of this test creates a copy of Sheet1 from Book1 before Sheet1 on Book2.
E.g 2
Sub RangeCopyMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
SourceWorksheet.Range("A1").Copy
DestinationWorksheet.Range("A1").PasteSpecial xlPasteValues
End Sub
This example copies cell A1 from Book1 - Sheet1 and pastes it to cell A1 in Book2 - Sheet1.
E.g 3
Sub AvoidSelectMethod()
Dim SourceWorksheet As Worksheet
Dim DestinationwWorksheet As Worksheet
Set SourceWorksheet = Workbooks("Book1").Sheets("Sheet1")
Set DestinationWorksheet = Workbooks("Book2").Sheets("Sheet1")
DestinationWorksheet.Range("A1").Value = SourceWorksheet.Range("A1").Value
End Sub
This example assigns the Value property of A1 from Book1 - Sheet1 to cell A1 in Book2 - Sheet1. It's the same outcome as E.g 2 but avoids using Select, Copy & Paste etc. This method is much faster and generally less error prone than the 2nd example.
Depending on your environment, the first example may be the easiest and quickest method.

Related

Copy Data from Sheet to another based on drop-down value

I have several sheets in one workbook. I want to copy-paste the data (entire content) from different sheets to sheet 1 (let's say from B6) based on the drop-down value in 'A2' in Sheet 1. Drop-down consists of names of all the other sheets. So, if I select Sheet 2 in drop-down, it should copy entire content from Sheet 2 to Sheet 1, starting from B6.
Here is the macro, I created for it. But it's not working. Can you help me figure out what's wrong with my code?
Sub Button21_Click()
Dim wb As Workbook
Dim criteria As String
Application.ScreenUpdating = False
'Set values for your variables.
Set wb = ThisWorkbook
criteria = wb.Sheets("Sheet1").Range("A2")
Dim TT As ListObject
For i = 1 To Sheets.Count
With Sheets(i)
For Each TT In Sheets(i).ListObjects
If TT.Name = criteria Then TT.Range.Copy Sheets("Sheet1").Range("B6:Q22").PasteSpecial: Exit Sub
Next
End With
Next
Application.ScreenUpdating = True
End Sub
Here's code that does work.
Sub Button21_Click()
Dim Wb As Workbook
Dim Criteria As String
Dim i As Integer ' loop counter: Sheets
Dim Tbl As ListObject ' loop object
'Set values for your variables.
Set Wb = ThisWorkbook
Criteria = Wb.Sheets("Sheet1").Range("A2")
Application.ScreenUpdating = False
For i = 1 To Wb.Sheets.Count ' { "Shees(1)" is in the ActiveWorkbook
' { which may be different from Wb
For Each Tbl In Wb.Sheets(i).ListObjects
If Tbl.Name = Criteria Then
Tbl.Range.Copy
Wb.Worksheets("Sheet1").Range("B6").PasteSpecial
Exit Sub
End If
Next Tbl
Next i
Application.ScreenUpdating = True
End Sub
You should declare all variables, not only objects. And it's better to prepare your tools before starting on the job, i.e. declare variables before writing code that uses them.
What's the point of declaring Set Wb = ThisWorkbook if you use the default workbook (= ActiveWorkbook) thereafter?
PasteSpecial needs its own line. The construct you used would deliver the argument for the Copy object's Destination property. The latter is an address and can't include the PasteSpecial method.
It's enough to specify the first cell to paste to.
Note that the ListObject's Range comprises of the entire table. Use the DataBodyRange to specify only data (without headers and totals).

Why am I getting a Subscript Out of Range Error 9 when referencing another Workbook/Worksheet in VBA?

I have a Macro (within a Master Workbook) that is getting data from another Workbook/Worksheet using .value2.
I've tried different changes, within the code. I double checked that both workbooks are open. However, I keep getting the Subscript out of range (Error 9).
Sub NielsenScorecard_DataPaste()
Dim WbNielsenScorecard As Workbook
Set WbNielsenScorecard = Workbooks("Nielsen Scorecard_Template.xlsm")
TotalUS_DataPaste
End Sub
Sub TotalUS_DataPaste()
**Subscript out of range (Error 9)**
With Workbooks("Power Query - Meijer_Walmart_Total US xAOC.xlsm").Worksheets("PQTotalUS")
Dim Data(0) As Variant
'Copy Data Range
Data(0) = .Range(.Cells(.Rows.Count, "A").End(xlUp), "AA2").Value2
End With
'Worksheet Code Name within this Workbook
With wsTotalUS
Debug.Print wsTotalUS.Name
.AutoFilter.ShowAllData
.Range("A2:AA" & .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Row).ClearContents
With .Cells(.Rows.Count, "A").End(xlUp).Offset(1).Resize(UBound(Data(0)))
.Resize(ColumnSize:=UBound(Data(0), 2)).Value2 = Data(0)
End With
End With
End Sub
You can reference a sheet by its codename, however it is a different format and must be in ThisWorkbook. A drawback is that you cannot reference a sheet in another workbook by its codename. Worksheets("PQ Total US").Activate versus PQTotalUS.Activate. If your goal is to shorten the code and not have to repeat a long name, then another option is to do the following:
Dim wb1 as Workbook
Dim ws1 as Worksheet
Set wb1 = Workbooks("Power Query Meijer_Walmart_Total US xAOC.xlsm")
Set ws1 = wb1.Worksheets("PQ Total US")
With ws1
'Do something
End with

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

Dynamically Copy Range of Cells from Closed Workbook?

I would like to copy a range of cells in a closed notebook that does not have a static set of rows. I would like to copy it into an active workbook.
I am trying to dynamically copy all entries under the column of F from file 'test.xlsx' from the 'exception' worksheet. The macro runs without issue if there I use static referencing instead. Here is the code that I am running, it gives me a runtime error for the line that copies the data.
Sub GetClassID()
Dim App As New Excel.Application
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.ActiveSheet
Dim wbImport As Workbook
Set wbImport = App.Workbooks.Open(Filename:="C:\Test.xlsx",
UpdateLinks:=True, ReadOnly:=True)
wbImport.Worksheets("Exception").Range("F2",Range("F2").end(xldown)).Copy
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub
Error I get is runtime erorr '1004': Interface not registered
Assuming you run this in an Excel VBA? You don't need to open the other workbook as an Excel.Application, just remove the app out of it and open the workbook normally:
Sub GetClassID()
Dim wsActive As Worksheet
Set wsActive = ThisWorkbook.Sheets("Another Sheet Name")
Dim wbImport As Workbook
Set wbImport = Workbooks.Open(Filename:="C:\Test.xlsx", UpdateLinks:=True, ReadOnly:=True)
With wbImport.Worksheets("Exception")
.Range("F2", .Range("F2").End(xlDown)).Copy
End With
wsActive.Range("A2").PasteSpecial Paste:=xlPasteFormats
wsActive.Range("A2").PasteSpecial Paste:=xlPasteValues
App.CutCopyMode = False
wbImport.Close SaveChanges:=False
App.Quit
End Sub
In my experience, the most effective way to copy a dynamic range is to create a variable as an integer and assign the row of the last cell to be copied (or column if needing to select a row of data across to a certain point. I usually accomplish it with something like this:
Dim R as Integer
With ThisWorkbook.Worksheets
R = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
Then you can plug in 'R' for the row number in a range to make it dynamic each time the macro is ran. For instance: .Range("A1:A" & R).Copy would copy the used range in Column A. It also makes it really easy to reference the last row for loops and such continuously throughout your code. Hope this helps!

Excel vba code for updating workbook from external worksheet

Yet another worksheet copying problem! This is a simple problem that has got me stumped. I want the click of a command button (in action.xlsm) to repopulate the values in a range ("stock" - 2 cols & maybe 100 rows - this is the master inventory records) in a separate excel file (inventory.xlsx), from a named range ("newInventory" - same size as other named range) in the active worksheet (in action.xlsm) that has had the original "stock" values reduced by the values of items taken out of stock. The calculations are OK I just can't get the master inventory file to update. I have checked heaps of forums and tried two approaches to no avail. I have tried:
Private Sub CommandButton1_Click()
Dim InventoryFileName As String
InventoryFileName = "C:\Users\david\Documents\inventory.xlsx"
Workbooks(InventoryFileName).Worksheets("Sheet1").Range("stock") = ThisWorkbook.Worksheets("inventory").Range("newInventory").Value
Workbooks(InventoryFileName).Save
End Sub
Throws a "Run-time error '9': Subscript out of range" on line 4. I have also tried:
Private Sub CommandButton1_Click()
Dim wbTarget As Workbook 'workbook where the data is to be pasted
Dim wsTarget As Worksheet
Dim wbThis As Workbook 'workbook from where the data is to copied
Dim wsThis As Worksheet
Dim strName As String 'name of the source sheet/ target workbook
'set to the current active workbook (the source book)
Set wbThis = ActiveWorkbook
Set wsThis = ActiveSheet
'get the active sheetname of the book
strName = wsThis.Name
'open a workbook that has same name as the sheet name
Set wbTarget = Workbooks.Open("C:\Users\david\Documents\" & strName & ".xlsx")
Set wsTarget = wbTarget.Worksheets("Sheet1")
'select cell A1 on the target book
wbTarget.wsTarget.Range("A1").Select
'clear existing values form target book
wbTarget.wsTarget.Range("A1:B10").ClearContents
'activate the source book
wbThis.Activate
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'copy the range from source book
wbThis.wsThis.Range("A1:B10").Copy
'paste the data on the target book
wbTarget.wsTarget.Range("A1").PasteSpecial Paste:=xlPasteValues
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'save the target book
wbTarget.Save
'close the workbook
wbTarget.Close
'activate the source book again
wbThis.Activate
'clear memory
Set wbTarget = Nothing
Set wbThis = Nothing
End Sub
This throws a "Run-time error '438': Object doesn't support this property or method" on line wbTarget.wsTarget.Range("A1").Select
What have I got wrong? Any suggestions?
Replace
wbTarget.wsTarget.Range("A1").Select
with just
wsTarget.Range("A1").Select
The workbook is already implied from the way you defined wsTarget. I suspect that will do it. If you run the code in the debugger, then when you do a "watch" on the variable you can see exactly what does and doesn't work..
Firstly you have 2 commandbutton1. Secondly you must have a reference for a Range like:
Workbooks(InventoryFileName).Worksheets("Sheet1").Range("A3:B21") = ThisWorkbook.Worksheets("inventory").Range("A10:B12").Value
or
stock="A3:B21"
newInventory="A10:B12"

Resources