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"
Related
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.
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
I have a small app containing about 20 subs which runs perfectly... Every other time.
It fails, in the sub ImportData, the first time I add a code name to a newly created sheet. on the following line:
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Customers"
The code below contains three subs which which can recreate the issue. Important note: I can run the sub ImportData as many times in a row without any issues but if I call the sub "Sync()" twice in a row it will fail on the second attempt but works fine on the third attempt and so on (Maybe it doesn't like odd numbers..)
Any ideas as to why this is happening would be greatly appreciated.
FYT: I am running this code in Excel for Mac
Public LastRow As Long
Private wks As Worksheet
Sub Sync()
Call ImportData
Call SyncBoth
End Sub
Public Sub ImportData()
'++++++++++++++++++++++++++++++++++++++++++++++++++++++
'+++++ 1. ImportData will allow user to select file to import data from
'+++++ 2. Copy both the Customers and Vendors data to their respective sheets
'++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim LastRow As Long
Dim MaxDate As Date
Dim ShCount As Integer
Dim SourceFile As String
SourceFile = "/Users/phild/Documents/RTPro/Customer and Vendor Raw Sync.xlsm"
Dim SourceWb As Workbook
Set SourceWb = Workbooks.Open(SourceFile)
Dim TargetWb As Workbook
Set TargetWb = ThisWorkbook
Dim sheet As Worksheet
For ShCount = 1 To 2
Select Case ShCount
Case 1
Set wsSource = SourceWb.Worksheets("Sheet1") 'Set Worksheet to copy data from
ThisWorkbook.Sheets("Customers").Delete 'Delete old Customer worksheet in this worksheet
Set sheet = ThisWorkbook.Sheets.Add 'Create New Customer woeksheet in this woekbook
sheet.Name = "Customers" 'Name new Customer worksheet
Set wsTarget = ThisWorkbook.Worksheets("Customers") 'Set Customers ws as the target ws
Debug.Assert ThisWorkbook.VBProject.Name <> vbNullString '<--Force the VBE to exist. Don't pollute the Immediate window
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Customers" 'Give Customers a Code name
'THE LINE OF CODE ABOVE RESULTS IN A Runtime error '32813"
' Method 'Name' of object '+VBComponent' failed
' EVERY OTHER TIME I RUN THE SUB Sync()
Case 2
Set wsSource = SourceWb.Worksheets("Sheet3") 'Set Worksheet to copy data from
ThisWorkbook.Sheets("Vendors").Delete 'Delete old Vendors worksheet in this worksheet
Set sheet = ThisWorkbook.Sheets.Add 'Create New Vendor worksheet in this woekbook
sheet.Name = "Vendors" 'Name new Vendor worksheet
Set wsTarget = ThisWorkbook.Worksheets("Vendors") 'Set Customers ws as the target ws
Debug.Assert ThisWorkbook.VBProject.Name <> vbNullString '<--Force the VBE to exist. Don't pollute the Immediate window '
ThisWorkbook.VBProject.VBComponents(wsTarget.CodeName).Name = "Vendors" 'Give Vendors a Code name
End Select
Call CleanTarget(wsTarget)
LastRow = Find_LastRow(wsSource)
wsSource.Range("A1:Z" & LastRow).Copy Destination:=wsTarget.Range("A1")
Next ShCount
SourceWb.Close
End Sub
Sub SyncBoth()
Dim ShCount As Integer
For ShCount = 1 To 2
Select Case ShCount
Case 1
Set wks = Customers 'Work in sheet("Customers")
LastRow = Find_LastRow(wks) 'Last row of "Customers"
Case 2
Set wks = Vendors 'Work in sheet("Vendors")
LastRow = Find_LastRow(wks) 'Last row of "Vendors"
End Select
Debug.Print wks.Name
Next ShCount
'Normally I have about 10 subs here that are called sequentially. But this is enough the cause the errorw
End Sub```
You're modifying the host VBA project at run-time - the code name identifier for Sheet1 is a compile-time, project-global scope object: even if it's not used anywhere, there's a legitimate chance that changing it requires recompiling the project.
So the code runs fine, up until it shoots its own foot off by renaming a global object; the next run now runs fine because now the compiled code matches the actual VBComponent in the project.
Consider having the macro in a separate VBA project, that prompts for which macro-enabled workbook to rename components in: because that VBA project won't be the VBA code that's compiled & running, it should "just work" then.
I'm having an issue with the above: I am using the answer provided, but still hitting an object error. Can you see what i'm missing? I hit the errror at "Cash_Sheet.Range("C8").PasteSpecial xlPasteValues"
`Sub Refresh_Cash()
Dim Morning_Export As Workbook
Dim Cash_Sheet As Worksheet
'Open MorningExport cash workbook
Set Morning_Export = Workbooks.Open(Range("varMornExpPath"))
'Copy cash from Morning_Export_Settlement_Cas tab:
Morning_Export.Sheets("Morning_Export_Settlement Cas").Range("A1:AR5000").Copy
'Set the sheet in this file to paste to:
Set Cash_Sheet = ThisWorkbook.Worksheets("Cash")
'Clear prior data from EOD_Check
Cash_Sheet.Range("rngRefreshPFMExp").ClearContents
'EVERYTHING WORKS UP UNTIL THIS POINT BUT THEN FAILS HERE
Cash_Sheet.Range("C8").PasteSpecial xlPasteValues
'Close MorningExport book:
Morning_Export.Close
End Sub
Sub Refresh_Cash()
Dim wb As Workbook: Set wb = Workbooks.Open(Range("varMornExpPath"))
Dim cs As Worksheet: Set cs = ThisWorkbook.Sheets("Cash")
cs.Range("rngRefreshPFMExp").ClearContents
wb.Sheets("Morning_Export_Settlement Cas").Range("A1:AR5000").Copy
cs.Range("C8").PasteSpecial xlPasteValues
wb.Close
End Sub
Instead of using copy\paste you can directly write the values from one range in to another. This works much faster on large data sets because it doesn't have to copy twice. It also results in cleaner code.
Public Sub Refresh_Cash()
Dim Morning_Export As Workbook
Dim Cash_Sheet As Worksheet
'Open MorningExport cash workbook
Set Morning_Export = Workbooks.Open(ActiveSheet.Range("varMornExpPath"))
'Set the sheet in this file to paste to:
Set Cash_Sheet = ThisWorkbook.Worksheets("Cash")
' Set the values directly
Cash_Sheet.Range("C8") = Morning_Export.Sheets("Morning_Export_Settlement Cas").Range("A1:AR5000")
'Close MorningExport book:
Morning_Export.Close
End Sub
SEE: Copy/PasteSpecial vs Range.Value = Range.Value
When I run this code, i get the following error"Run-time error'438' : Object doesn't support this property or method" on this line of the code:
'copy the range from source book
wbFrom.Range("A:A").Copy
Sub CopyOpenItems()
'
' CopyOpenItems Macro
' Copy open items to sheet.
'
' Keyboard Shortcut: Ctrl+Shift+O
'
Dim wbTarget As Workbook 'workbook where the data is to be pasted
Dim wbFrom As Workbook 'workbook from where the data is to be copied
Dim wsFrom As Worksheet
Dim wsTarget As Worksheet
'set to the current active workbook (the source book)
Set wbTarget = ActiveWorkbook
Set wsTarget = wbTarget.Worksheets(1)
'open a workbook that has same name as the sheet name
Set wbFrom = Workbooks.Open("......")
Set wsFrom = wbFrom.Worksheets(1)
'activate the source book
wbFrom.Activate
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'copy the range from source book
wbFrom.Range("A:A").Copy
'paste the data on the target book
wbTarget.Range("A:A").PasteSpecial
wbFrom.Range("C:C").Copy
wbTarget.Range("C:C").PasteSpecial
wbFrom.Range("D:D").Copy
wbTarget.Range("D:D").PasteSpecial
wbFrom.Range("F:F").Copy
wbTarget.Range("F:F").PasteSpecial
wbFrom.Range("J:J").Copy
wbTarget.Range("J:J").PasteSpecial
wbFrom.Range("K:K").Copy
wbTarget.Range("K:K").PasteSpecial
'clear any thing on clipboard to maximize available memory
Application.CutCopyMode = False
'save the target book
wbTarget.Save
wbFrom.Save
'close the workbook
wbFrom.Close
'activate the source book again
wbFrom.Activate
'clear memory
Set wbTarget = Nothing
Set wbFrom = Nothing
End Sub
I can't figure out what's wrong with it. The point of the code i guess is pretty straightforward, copy selected columns from one workbook and paste it into another.
Also, this code is a slightly modified version of the one that could be find on this link
https://ccm.net/faq/24666-copy-data-to-another-workbook-in-excel