I have some VBA code that gives me "Runtime Error 1004: PasteSpecial method of Range class failed."
This is my code:
Sub CurrentToOld()
rownumber = ThisWorkbook.Sheets("As-Built Emergency").Range("A1", Worksheets("As-Built Emergency").Range("A2").End(xlDown)).Rows.Count
ThisWorkbook.Sheets("As-Built Emergency").Activate
ThisWorkbook.ActiveSheet.Rows("2:" & rownumber).Select
Selection.Cut
ThisWorkbook.Sheets("OLD AB EMERGENCY").Activate
ThisWorkbook.ActiveSheet.Range("A2").Select
ThisWorkbook.ActiveSheet.Range("A2").PasteSpecial Paste:=xlPasteSpecial, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
The error is in the 2nd to last line, and I can't seem to figure out why. I'm copying around 150 rows, and there are no merged cells within any of the copied ones.
I've tried removing the .Select statements and I change what I copied from Rows("2:" & rownumber) to Range("A1:D4") [something small which exists] but I still get the error.
EDIT: I put this line:
ThisWorkbook.ActiveSheet.Range("A2").Select
Because I wanted to test if it was a problem with the way I wrote the PasteSpecial code or if I actually needed to declare anything.
But the statement above works when I tested it in the debugger, so I'm at a standstill here.
Try just activating that range.
ThisWorkbook.ActiveSheet.Range("A2").Activate
or try declaring the worksheet
Sub CurrentToOld()
Dim wb As Workbook
Set WorkBk = ActiveWorkbook
rownumber = WorkBk.Sheets("As-Built Emergency").Range("A1", Worksheets("As-Built Emergency").Range("A2").End(xlDown)).Rows.Count
WorkBk.Sheets("As-Built Emergency").Activate
WorkBk.ActiveSheet.Rows("2:" & rownumber).Select
Selection.Cut
WorkBk.Sheets("OLD AB EMERGENCY").Activate
WorkBk.ActiveSheet.Range("A2").Select
WorkBk.ActiveSheet.Range("A2").PasteSpecial Paste:=xlPasteSpecial, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
Or declare the sheet as well
Sub CurrentToOld()
Dim wb As Workbook
Set WorkBk = ActiveWorkbook
Dim ws As Excel.Worksheet
Set ws = Application.ActiveSheet
rownumber = WorkBk.Sheets("As-Built Emergency").Range("A1", Worksheets("As-Built Emergency").Range("A2").End(xlDown)).Rows.Count
WorkBk.Sheets("As-Built Emergency").Activate
ws.Rows("2:" & rownumber).Select
Selection.Cut
WorkBk.Sheets("OLD AB EMERGENCY").Activate
ws.Range("A2").Select
ws.Range("A2").PasteSpecial Paste:=xlPasteSpecial, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End Sub
Sub CurrentToOld()
Dim rownumber As Long
rownumber = ThisWorkbook.Sheets("As-Built Emergency").Range("A1", Worksheets("As-Built Emergency").Range("A2").End(xlDown).Address).Rows.Count
ThisWorkbook.Sheets("As-Built Emergency").Activate
ThisWorkbook.ActiveSheet.Rows("2:" & rownumber).Select
Selection.Cut
ThisWorkbook.Sheets("OLD AB EMERGENCY").Select
ThisWorkbook.Sheets("OLD AB EMERGENCY").Range("A1").Select
ActiveSheet.Paste
End Sub
Apparently the problem was that the sheet I was posting to had data, and I needed to clear out the used cells first.
Related
Sub Copy_Cell2()
'Declare Variables
Dim Wr As Worksheet
'Define the excel sheet
Set Wr = ThisWorkbook.Sheets("Sheet2")
'Code to stop screen updating and flickering ON
Application.ScreenUpdating = False
'Select Sheet1 to get the random value
Sheets("Sheet1").Select
Cells.Select
Range("F1").Select
Range("F1").Copy
'Selects Sheet2 to paste the random value in the next blank cell in column A
Sheets("Sheet2").Select
Range("A2").Select
nrlife = Wr.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select
'Establish what row has been selected
With ActiveCell
vRow = .Row
End With
vRange = "A" & vRow & ""
Range(vRange).Select
'Code to paste value and format from Sheet1 to first empty row on sheet2
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks_:=False, Transpose:=False
'Code to stop screen updating and flickering OFF
Application.ScreenUpdating = True
End Sub
I am getting error in Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks_:=False, Transpose:=False
Error code is Run-time error '1004' Aplication-defined or
object-defined error
Can anyone help me what am i missing?
Your code reduces to:
Dim wb As Workbook
Set wb = ThisWorkbook
wb.Sheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1).Value = _
wb.Sheets("Sheet1").Range("F1").Value
You can assign values directly - no need for copy/paste in this case.
I have a problem with the autofill function. I want to use the macro to fill in the date until there is nothing left in B. The problem is that there are some gaps there. Can I change the code so that it fills up to the last line in B. I tried it with the code below. However, it does not work.
Sub fill()
Sheets("Table1").Select
Columns("C:C").Select
Selection.Insert Shift:=xlToRight
Range("C2").Select
ActiveCell.FormulaR1C1 = "=IF(RC[-1]="""",R[-1]C,RC[-1])"
ActiveCell.Select
Dim last As Long
Range("C2").Select
Range(Selection, Selection.End(xlToRight)).AutoFill Destination:=Range("C2:C" & last)
Selection.End(xlDown).Select
Selection.ClearContents
ActiveCell.Offset(-1, 0).Range("A1").Select
Range(Selection, Selection.End(xlUp)).Select
Selection.Copy
Range("B2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Columns("C:C").Select
Application.CutCopyMode = False
Selection.Delete Shift:=xlToLeft
Range("A1").Select
End Sub
You do not need such a lengthy process. You can do it in just couple of lines. For example
rng.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
Here is an example. Assuming that your range is from C2 onwards as shown below.
Try this code
Option Explicit
Sub Sample()
Dim ws As Worksheet
Set ws = Sheets("Table")
Dim lRow As Long
With ws
lRow = .Range("C" & .Rows.Count).End(xlUp).Row
Dim rng As Range
Set rng = .Range("C3:C" & lRow)
Dim visibleCells As Range
On Error Resume Next
Set visibleCells = rng.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If Not visibleCells Is Nothing Then
visibleCells.FormulaR1C1 = "=R[-1]C"
End If
End With
End Sub
In Action
Worth a Mention
Also avoid using Select/Selection/Activecell etc. You may want to read up on How to avoid using Select in Excel VBA
You do not need VBA to achieve what you want. You can achieve the same using few clicks.
NON VBA Method
Select your range. In this case C3:C13
Press CTRL + G to bring up the Go To dialog box
Click Special button
Select the Blanks radio button and click OK.
In the Formula bar type =C2 and press CTRL + ENTER key and you are done
In Action
To be short and sweet with my requirement, I need a code to do the conditions below.
Select from range A2:G5
Then check if a sheet named with current date i:e 29-02-2016
If yes,
then copy paste the range in A1 leave 3 rows below for the next data to be pasted below that.
If no,
create a new sheet and name it with current date and then copy paste the range in A1 leave 3 rows below for the next data to be pasted below that.
I tried the below code but it give me error once the current date sheet is created.
Sub Macro1()
Sheets("Sheet1").Select
Range("D3:G12").Select
Selection.Copy
sheets = "todaysdate".select
Dim todaysdate As String
todaysdate = Format(Date, "dd-mm-yyyy")
AddNew:
Sheets.Add , Worksheets(Worksheets.Count)
ActiveSheet.Name = todaysdate
On Error GoTo AddNew
Sheets(todaysdate).Select
Range("A1048576").Select
Selection.End(xlUp).Select
ActiveCell.Offset(3, 0).Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End Sub
Try these modifications.
Sub Macro1()
Dim todaysdate As String
With Worksheets("Sheet1")
.Range("D3:G12").Copy
End With
todaysdate = Format(Date, "dd-mm-yyyy")
On Error GoTo AddNew
With Worksheets(todaysdate)
On Error GoTo 0
With .Cells(Rows.Count, "A").End(xlUp).Offset(3, 0)
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
End With
End With
Exit Sub
AddNew:
With Worksheets.Add(after:=Sheets(Sheets.Count))
.Name = todaysdate
With .Cells(Rows.Count, "A").End(xlUp)
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
End With
End With
End Sub
Step through the modified procedure with the [F8] key to watch how it handles the thrown error and continues on to exit or processes the paste with a three row offset.
Why this call of sub is not working properly?
I get an error that there are undefined objects.
I believe this can be a little problem but cannot find a solution.
I am trying to make new sheetnames but the code is too long for VBA , so I have to split the code, and continue in a second Sub. (apparently it is limited to 15 of 16 handlings)
Thanks in advance.
below my startcode
Sub Macro1()
' Macro1 Macro
Dim wbNew As Workbook
'sheet 1----------------------------------------------------------------
Application.ScreenUpdating = False
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
Set wbNew = Workbooks.Add
wbNew.Sheets(1).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
wbNew.Sheets(1).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
Range("A15").Select
Call vanaf_17
ActiveWorkbook.SaveAs Filename:= _
"C:\Path\" & "per 1-15" & " " & Format(Range("C13"), "mmmm") & " " & Format(Range("C13"), "YYYY") & ".xlsx"
FileFormat = xlOpenXMLWorkbook
ActiveWindow.Close
End Sub
code to call
Sub vanaf_17()
Dim wbNew As Workbook
Application.ScreenUpdating = False
'sheet 17----------------------------------------------------------------
'here starts a new sheet!!!!!!!!!!!!!
Sheets.Add After:=ActiveSheet
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
'change here sheet nr!!!!!!!
wbNew.Sheets(17).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'change here sheet nr!!!!!!!
wbNew.Sheets(17).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
'Here ends a new sheet!!!!!
End Sub
You'll need to set wbnew in that second sub as well. The second sub has no idea what you mean when you say wbnew. When you have a variable in a subroutine or function it exists only in the subroutine or function. As soon as you move to another subroutine, your variables are 100% worthless.
To get around this, you can pass parameters between subs.
When you start your second sub Sub vanaf_17() Do it like so:
Sub vanaf_17(wbNew as Workbook)
....your code
End Sub
When you call vanaf_17() do it like so:
Call vanaf_17 webNew
Also, since you are declaring webNew as a workbook in the parameters, delete the dim wbNew as Workbook bit in vanaf_17 otherwise you'll get an error.
Lastly, There is no reason why you need to split these up into two subroutines. I've never heard of '15 or 16 handling' limit and I'm not real sure what that means. I've seen some ugly ass recorded macro code that goes on for thousands of lines of .select and .activate and oh-my-god-no-that-is-such-a-bad-idea for what feels like forever. Excel can handle it.
Updated: Here is what the code would look like with this change:
Sub Macro1()
' Macro1 Macro
Dim wbNew As Workbook
'sheet 1----------------------------------------------------------------
Application.ScreenUpdating = False
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
Set wbNew = Workbooks.Add
wbNew.Sheets(1).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
wbNew.Sheets(1).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
Range("A15").Select
Call vanaf_17 wbNew
ActiveWorkbook.SaveAs Filename:= _
"C:\Path\" & "per 1-15" & " " & Format(Range("C13"), "mmmm") & " " & Format(Range("C13"), "YYYY") & ".xlsx"
FileFormat = xlOpenXMLWorkbook
ActiveWindow.Close
End Sub
Sub vanaf_17(wbNew AS Workbook)
Application.ScreenUpdating = False
'sheet 17----------------------------------------------------------------
'here starts a new sheet!!!!!!!!!!!!!
Sheets.Add After:=ActiveSheet
ThisWorkbook.Sheets(1).Activate
Range("A1:S53").Select
Range("S53").Activate
Selection.Copy
'change here sheet nr!!!!!!!
wbNew.Sheets(17).Activate
Range("A1:S53").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
'change here sheet nr!!!!!!!
wbNew.Sheets(17).Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Range("A1").Select
ActiveSheet.Paste
'Here ends a new sheet!!!!!
End Sub
That being said, there are some changes here that I think will help. Namely, you could loop through all the sheets that you care about in thisWorkbook, and call your subroutine to copy and paste the A1:S53 range into a new worksheet in the new workbook. Below I have a quick example of what that would look like. I kept some of the unnecessary .select and .activate stuff in there, because I figured this change was dramatic enough. You'll see that all of your sheet creation and copying/pasting is now done in the second subroutine. The first subroutine just sets up the new workbook, loops through the sheets, and then saves the new workbook.
Sub Macro1()
' Create a new workbook. Then loop through each worksheet in this workbook (that we care about)
' and call the CreateNewWS subroutine to copy the A1:S53 range for each worksheet into the
' new workbook
Application.ScreenUpdating = False
'Create a new workbook, assign it to wbNew variable
Dim wbNew As Workbook
Set wbNew = Workbooks.Add
'Loop through all the sheets in the current workbook that we care about
Dim sheetname as string
For each sheetname in Array("sheet1", "sheet2", "sheet3", "sheet4")
'call the CreateNewWS subroutine to do the sheet creation and copying and pasting
call CreateNewWS wbNew, thisWorkbook.Sheets(sheetname)
Next sheetname
'You could also loop through all of the worksheets in thisworkbook if you want to copy every worksheet:
'Dim ws as worksheet
'For each ws in ThisWorkbook.Worksheets
' call CreateNewWS wbNew, ws
'Next ws
'Save the new workbook
newWb.SaveAs Filename:= _
"C:\Path\" & "per 1-15" & " " & Format(Range("C13"), "mmmm") & " " & Format(Range("C13"), "YYYY") & ".xlsx"
FileFormat = xlOpenXMLWorkbook
'Close the new workbook
newWb.Close
'Don't forget to turn this back on. Yikes.
Application.ScreenUpdating = True
End Sub
Sub CreateNewWS(wbNew AS Workbook, ws as Worksheet)
'This subroutine takes in the wbNew and the worksheet (ws) that we are copying from.
' it copys range A1:S53 from the ws to the wbNew's new worksheet.
'This will hold the new worksheet we are adding to the wbNew
Dim wsNew as worksheet
'Add a new worksheet to the new workbook
wbNew.Activate
set wsNew = wbNew.Sheets.Add After:=ActiveSheet
'Activate and copy from current workbook
ws.Activate
ws.Range("A1:S53").Select
Selection.Copy
'Activate and paste into newWb
wsNew.Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteColumnWidths, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End Sub
I haven't really tested this change, but the guts of it are accurate. If you do decide to switch over to this type of logic and you run into errors, it would be prudent to create a new stackoverflow question to work through the problem.
I'm trying to get the sourcedata from a range of cells on an "input sheet" for data entry to copy this information to 2 different sheets. After this copy, I will use one sheet to leave for all data, and manipulate the other sheet for tracking.
This is what I've gotten so far, but I get an error that an object is required.
Sub CopySource()
Dim NextRow As Range
With Sheets(Array("MasterData", "MainData")).Select
Set NextRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
End With
Range("SourceData").Copy
NextRow.PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub
Just do each copy individually, then:
Sub CopySource()
Range("SourceData").Copy
Sheets("MasterData").Cells(Sheets("MasterData").Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats, Transpose:=False
Sheets("MainData").Cells(Sheets("MainData").Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial _
Paste:=xlPasteValuesAndNumberFormats, Transpose:=False
Application.CutCopyMode = False
End Sub
Possible fix for the original code:
Sub CopySource()
Dim NextRow() As Range 'This makes an array of ranges
With Sheets(Array("MasterData", "MainData")).Select
'not sure if this will now populate multiple elements of NextRow() with multiple
'ranges, one from each sheet, above
Set NextRow = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
End With
Range("SourceData").Copy
NextRow(0).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Transpose:=False
NextRow(1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats, Transpose:=False
Application.CutCopyMode = False
Set NextRow = Nothing
End Sub
Not sure if that'll work, but it might be worth a try