VBA: PasteSpecial method of Range class failed - vba

I am using this to move orders from the new orders page to the previous orders page however I get the title error when I attempt to run it. I have looked at several different places to try to get it to work and I see that theirs should work but mine isn't.
Sheets("New_Orders").Range("B3:E29").Cut
Sheets("Previous_Orders").Range("B31").PasteSpecial Paste:=xlPasteValues
This is more code that is supposed to do the same thing that isn't working either
Sheets("New_Orders").Select
Range("B3:E29").Select
Selection.Cut
Sheets("Previous_Orders").Select
Range("B:B").Find("").Select
ActiveSheet.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
I have tried Selection.Copy as well. It gave the same error

As stated above in the comment you can only Paste everything when using Cut. If only values are wanted then assign the values directly then clear the range.
Sub foo()
Dim rng As Range
Dim lastRow As Long
Set rng = Sheets("New_Orders").Range("B3:E29")
With Sheets("Previous_Orders")
lastRow = .Cells(.Rows.Count, 2).End(xlUp).Row + 1
.Cells(lastRow, 2).Resize(rng.Rows.Count, rng.Columns.Count).Value = rng.Value
End With
rng.Clear
End Sub

Related

Creating a record of data in excel

Currently I have an excel sheet that works out certain prices which change everyday. I would like to have a vba button that records everyday's prices for reference, saving the last price of the data everyday (I update the price frequently during the day)
I wrote the code below but seem to be getting the error:
Compile error: Invalid Qualifier
[on the first LastRow.Offset() line]. I am quite new to vba and so any help would be appreciated
Private Sub CommandButton1_Click()
'Selecting the data to copy
Range("C23:O23").Select
Selection.Copy
'Find the last used row in Column B
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
End With
'if still today, replace data, if not record the data on the next line
If LastRow = Date Then
LastRow.Offset(0, 1).Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats,
Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Else
LastRow.Offset(1, 0) = Date
LastRow.offset(1, 1).Select
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats,
Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
End Sub
UPDATE: So, Ive changed a bit of my code where I define the LastRow variable differnetly:
Dim LastRow As Range
Set LastRow = Range("B31").End(xlDown)
This seemed to lead to a different error, "1004", in the line just after the else statement
LastRow.Offset(1, 0).Value = "=today"
Any advice will be appreciated
LastRow is defined as Long
Dim LastRow As Long
And then you are trying to use an Offset method, which is only available on Range objects.
Make the following changes and you should be good to go.
Dim LastRow As Range
With ActiveSheet
Set LastRow = .Cells(.Rows.Count, "B").End(xlUp)
End With
Reading this post on how and why to avoid select will take you far too. The code above can be optimized to work much smarter.
Looks like you have a typo in your else statement:
LastRow.oofset(1, 1).Select

VBA copy formatting from a row to several rows

Alright so I am really close to getting this but I am just trying to make it work better. I want to copy row 2 formatting that goes until like Column H. The data only goes until Column H. So my code copies ONLY row 2 until Column H. But when it goes to paste, it highlights the whole sheet besides row 1 and it looks like it copies the formatting across the whole thing. It is not really an issue but I would rather know how to make it paste only in the rows and columns I want for future reference. I only want it going to cells that have data in it basically. Thanks for the help in advance!
Range("A2", Cells(2, Columns.Count).End(xlToLeft)).COPY
Range("A2", Cells(Range("A" & Rows.Count).End(xlDown).Row)).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
Try this:
Dim rngCopy As Range, rngPaste As Range
With ActiveSheet
Set rngCopy = .Range(.Range("A2"), .Cells(2, Columns.Count).End(xlToLeft))
Set rngPaste = .Range(.Range("A2"), _
.Cells(Rows.Count, 1).End(xlUp)).Resize( , rngCopy.Columns.Count)
End With
rngCopy.Copy
rngPaste.PasteSpecial Paste:=xlPasteFormats
Application.CutCopyMode = False

Excel VBA Dynamic Code Repeat Failure

This code is a bit complex but the problem with it is the second and third time it is run it will start to lose columns on the "Base434" worksheet that it pulls information from. I tried a quick fix of adding "Range("A1").Select so that anything previously highlighted couldn't throw it off but it keeps ditching the 20th row which is column "T". I have left all of the code below in hope that someone can find my bug. I just cannot sort it.
Essentially this code sorts set fields of data on an imported worksheet called "Base434", copies specific fields to another page which has some embeded formulas then checks to see if the worksheet "NoStdHC" exists. If it doesn't it will create said worksheet and add the header. Then move to the filtered worksheet called "Base434" and copy all visible cells in that worksheet. It will then paste those in the first available cell in column A of "NoStdHC". My issue is after running this once it refuses to copy the final column on the next "Base434" sheet that has been imported. Can anyone find the fault in my code? Yes I know a lot of this could be condensed if I were better at coding but I would prefer to understand what the code is doing which is why I have it written this way.
Sub NoStdHC()
'
' NoStdHC Macro created by
'
'
Application.ScreenUpdating = False
Sheets("Base434").Select
LastRow = Cells(Rows.Count, "B").End(xlUp).Row
ActiveSheet.Range("A1:T" & LastRow).AutoFilter Field:=15
ActiveSheet.Range("A1:T" & LastRow).AutoFilter Field:=10
ActiveSheet.Range("A1:T" & LastRow).AutoFilter Field:=10, Criteria1:="<=.5", _
Operator:=xlAnd
Columns(11).Cells.SpecialCells(xlCellTypeVisible).Cells(2).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("Processing").Select
Range("AC1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("C5").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=COUNTA(C[26])"
Range("e5").Select
ActiveCell.FormulaR1C1 = "=SUM(C[24])"
Range("C8").Select
Sheets("Base434").Select
Dim wsTest As Worksheet
Const strSheetName As String = "PR0OnStd"
Set wsTest = Nothing
On Error Resume Next
Set wsTest = ActiveWorkbook.Worksheets(strSheetName)
On Error GoTo 0
If wsTest Is Nothing Then
Worksheets.Add.Name = strSheetName
Sheets("Base434").Select
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("PR0OnStd").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.Columns.AutoFit
Range("A2").Select
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
End With
ActiveWindow.FreezePanes = True
End If
Sheets("Base434").Select
Range("a1").Select
Columns(1).Cells.SpecialCells(xlCellTypeVisible).Cells(2).Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("PR0OnStd").Select
LastRow = ActiveSheet.Cells(Rows.Count, "A").End(xlUp).Row + 1
Range("A" & LastRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.ScreenUpdating = True
End Sub'
As commented by #A.S.H avoid using Select/Activate/ActiveCell if at all possible. Ranges should be qualified by using their sheet names. With...End With constructs achieve both of these goals. The With statement allows you to perform a series of statements on a specified object without requalifying the name of the object.
Indentation makes code much easier to read and understand.
With the foregoing in mind I think this code is understandable
Sub NoStdHC()
Dim LastRow As Long
Dim sht As Worksheet
Application.ScreenUpdating = False
With Sheets("Base434")
LastRow = .Cells(Rows.Count, "B").End(xlUp).Row
.Range("A1:T" & LastRow).AutoFilter Field:=10, Criteria1:="<=.5"
.Range(.Cells(2, 11), .Cells(LastRow, 11)).Copy
End With
With Sheets("Processing")
.Range("AC1").PasteSpecial xlPasteValues
Application.CutCopyMode = False
.Range("C5").FormulaR1C1 = "=COUNTA(C[26])"
.Range("E5").FormulaR1C1 = "=SUM(C[24])"
End With
Dim wsTest As Worksheet
Const strSheetName As String = "PR0OnStd"
'Loop through sheets to find strSheetName
'if not found, then wsTest will be Nothing
For Each sht In ThisWorkbook.Sheets
If sht.Name = strSheetName Then
Set wsTest = ActiveWorkbook.Worksheets(strSheetName)
Exit For
End If
Next
If wsTest Is Nothing Then
'Add the sheet, set up headings, column widths and frozen pane
Worksheets.Add.Name = strSheetName
With Sheets("Base434")
.Range("A1", .Range("A1").End(xlToRight)).Copy
End With
With Sheets("PR0OnStd")
.Range("A1").PasteSpecial xlPasteValues
.UsedRange.Columns.AutoFit
End With
With ActiveWindow
.SplitColumn = 0
.SplitRow = 1
.FreezePanes = True
End With
End If
With Sheets("Base434")
.Range(.Cells(2, 1), .Cells(LastRow, 2).End(xlToRight)).Copy
End With
With Sheets("PR0OnStd")
LastRow = .Cells(Rows.Count, "A").End(xlUp).Row + 1
.Range("A" & LastRow).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
Application.ScreenUpdating = True
End Sub
If you wanted to write write code you can easily understand you wouldn't write code like this:-
Sheets("Base434").Select
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
This is what your code says, translated into plain language:-
Look at sheet "Base434"
Look at cell A1 (implied: in that sheet)
Look at what you are looking at and extend your view to the last ??? right
(This is where the mistake is)
Copy what you are looking at.
Now, surely, if you wanted to understand what all this looking is aiming to do you might express the idea somewhat like this:-
Copy the cells in Row 1 of Sheet "Base434" from A1 to the end of the row.
With this kind of approach you would end up with code like this:-
Dim RangeToCopy As Range
Dim Cl As Long ' the last used column
With Worksheets("Base434")
Cl = .Cells(1, .Columns.Count).End(xlToLeft).Column
Set RangeToCopy = .Range(.Cells(1, 1), .Cells(1, Cl))
End With
MsgBox "Range to copy = " & RangeToCopy.Address
RangeToCopy.Copy
Would you say that this code is harder to read and understand than your version? Well, it has three advantages, even if it is. One, it doesn't have the fault that yours has. Two, it never got near to wanting to make the mistake that your approach made. Three, whatever errors it might still contain are easy to find and quick to eliminate.
Besides, it runs faster.

Copy cells by row containing text to column on another worksheet

I'm fairly new to macros etc..and I've been trying to figure this problem out for a few days now!
I'm trying to go from a large spreadsheet of data, selecting specific cells based on the contents of specific cells, and paste into another worksheet.
Source spreadsheet:
Columns go: Site, Sub-location, Date, Month, Inspector, Action 1, Action 2 etc up to a max of 67 actions for each inspection.
Each row is a separate inspection submission
Target spreadsheet:
Columns go: Site, Sub-location, Date, Month, Inspector, Action, Due date of Action
where each row is a separate action.
I want it to skip pasting any values from the actions columns that would be blank (since no action is required). When it pastes the actions, it will also paste the first 5 columns (with site name, location, date etc), so that the action can be identified to the right site, date etc.
Hopefully that makes sense. By the end, I want the target spreadsheet to be able to be filtered by whatever the people need, e.g. by due date, or by location etc.
Code that I tried my hardest to get working...Unfortunately I can only get it working for the first row, and then it still pastes the blank (or zero) values and I need to filter them out. I'm thinking some sort of loop to do all the rows.
Sub test1257pm()
Application.ScreenUpdating = False
Sheets("Corrective Actions").Select
Range("A3:E3").Select
Selection.Copy
Sheets("Corrective Actions Tracker").Select
Range("A3").Select
ActiveSheet.Paste
Sheets("Corrective Actions").Select
Range("F3").Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Sheets("Corrective Actions Tracker").Select
Range("F3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
.Cells(Rows.Count, "F").End(xlUp).Offset(1, 0).PasteSpecial
Rows("2:2").Select
Selection.AutoFilter
Range("F4").Select
ActiveSheet.Range("$A$2:$L$300").AutoFilter Field:=6, Criteria1:=Array( _
"CMC to conduct clean of ceiling fans. Close out by 17/04/2014", _
"Provide bins", "Send to contractor", "="), Operator:=xlFilterValues
Application.ScreenUpdating = True
End Sub
Many thanks to anyone that can give me any assistance! :)
Edit:24-4-2014
Okay so after L42's code, it works fine if I could just consodidate my data first before putting it in the 1 column (stacking). The code I tried (using Macro recorder) is:
Sub Macro2()
Dim r As Range
Dim i As Integer
For i = 3 To 10
Range("P" & i).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.Copy
Range("F" & i).Select
ActiveSheet.PasteSpecial Format:=3, Link:=1, DisplayAsIcon:=True, _
IconFileName:=False
Next i
End Sub
My problem with this is that it gives unexpected results...it doesn't consolidate it all into rows how I would expect. I'm thinking that this isn't the best solution...and probably the original macro needs to be changed..however I'm not sure how.
Overhaul #1: Using the provided sample data
Option Explicit '~~> These two lines are important
Option Base 1
Sub StackMyActions()
Dim sourceWS As Worksheet, targetWS As Worksheet
Dim staticRng As Range, copyRng As Range
Dim inspCnt As Long, i As Long, fRow As Long, tRow As Long
Dim myactions
Set sourceWS = ThisWorkbook.Sheets("Corrective Actions")
Set targetWS = ThisWorkbook.Sheets("Corrective Actions Tracker")
With sourceWS
'~~> count the total inspection
'~~> here we incorporate .Find method finding the last cell not equal to 0
inspCnt = .Range("A3", .Range("A:A").Find(0, [a2], _
xlValues, xlWhole).Offset(-1, 0).Address).Rows.Count
'~~> set the Ranges
Set copyRng = .Range("F3:BT3")
Set staticRng = .Range("A3:E3")
'~~> loop through the ranges
For i = 0 To inspCnt - 1
'~~> here we use the additional code we have below
'~~> which is GetCARng Function
myactions = GetCARng(copyRng.Offset(i, 0))
'~~> this line just checks if there is no action
If Not IsArray(myactions) Then GoTo nextline
'~~> copy and paste
With targetWS
fRow = .Range("F" & .Rows.Count).End(xlUp).Offset(1, 0).Row
tRow = fRow + UBound(myactions) - 1
.Range("F" & fRow, "F" & tRow).Value = Application.Transpose(myactions)
staticRng.Offset(i, 0).Copy
.Range("A" & fRow, "A" & tRow).PasteSpecial xlPasteValues
End With
nextline:
Next
End With
End Sub
Function to get the actions:
Private Function GetCARng(rng As Range) As Variant
Dim cel As Range, x
For Each cel In rng
If cel.Value <> 0 Then
If IsArray(x) Then
ReDim Preserve x(UBound(x) + 1)
Else
ReDim x(1)
End If
x(UBound(x)) = cel.Value
End If
Next
GetCARng = x
End Function
Results:
1: Using your sample data which looks like below:
2: Which after running the macro stacks the data like below:
Above code only stack inpections with at least 1 Action.
For example, Site 3 which was conducted by MsExample do not reflect on the Corrective Actions Tracker Sheet since no action was posted.
Well I really can't explain it enough, all the properties and methods used above.
Just check out the links below to help you understand most parts:
Avoid Using Select
Using .Find Method
Returning Array From VBA Function
And of course practice, practice, practice.

'Range' of Object ' _Global' failed error when selectng range

I'm really new to programming in VBA and having a problem with this code I'm trying to write. I am wanting the code to figure out the first row in column A that is unused then copy and paste data from a different part of the sheet into that row.
Sub CopyandPaste()
Dim RowLast As Long
RowLast = ThisWorkbook.Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Row
Set NewRange = ThisWorkbook.Worksheets("Sheet2").Cells(RowLast, 1)
ThisWorkbook.Worksheets("Sheet1").Cells(8, "B").Select
Selection.Copy
Range("NewRange").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
Any help would be extremely helpful.
Try this code :
Sub CopyandPaste()
Dim RowLast As Long
ThisWorkbook.Activate
With Worksheets("Sheet2")
RowLast = .Cells(.Rows.Count, "A").End(xlUp).Offset(1, 0).Row
Sheets("Sheet1").Cells(8, "B").Copy Sheets("Sheet2").Cells(RowLast, 1)
End With
End Sub
I have added comments into the code explaining changes I made.
Sub CopyandPaste()
Dim RowLast As Long
Dim newRange As Range
'this works easier if I understand your intent right
'I generally use some large row number with Excel 2010
'You may ahve to make this smaller if you are in 03
RowLast = Sheets("Sheet2").Range("B99999").End(xlUp) + 1
'if you KNOW you have continuous data in this column (no spaces)
RowLast = Sheets("Sheet2").Range("B1").End(xldown) + 1
'this is slightly better way to do this
Set newRange = ThisWorkbook.Worksheets("Sheet2").Range("A" & RowLast)
'don't do this
'ThisWorkbook.Worksheets("Sheet1").Cells(8, "B").Select
'Selection.Copy
'do this instead
Sheets("Sheet1").Range("B8").Copy
newRange.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'you were attempting to use a variable name (newrange) as a
'name of a named range in the Excel sheet
'use the variable range itself (as above)
End Sub