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

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

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

Excel VBA - Do Until Blank Cell

I'm recording a macro and need some help. I'd like copy and paste the values from the column G of the "SalesData" worksheet into cells A2, A12, A22 etc of the "Results" worksheet until there's no more values in the column G.
VBA is pretty new to me, I've tried using Do/Until, but everything crashed. Could you please help me? Please see the code I've recorded below. Thank you!
Sub(x)
Sheets("SalesData").Select
Range("G2").Select
Selection.Copy
Sheets("Results").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A12").Select
Sheets("SalesData").Select
Range("G3").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Results").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A22").Select
Sheets("SalesData").Select
Range("G4").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Results").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A32").Select
Sheets("SalesData").Select
Range("G5").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Results").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub
I prefer to find the last cell in the column first then use a For loop.
Since you are only doing the values we can avoid the clipboard and assign the values directly.
Since you paste is every 10 cells we can use a separate counter to move down 10 each loop.
Sub x()
Dim ws As Worksheet
Dim lst As Long
Dim i As Long, j As Long
'use variable to limit the number of times we type the same thing
Set ws = Worksheets("Results")
'First row of the output
j = 2
'using with and the "." in front of those items that belong to it also limits the typing.
With Worksheets("SalesData")
'Find the last row with values in Column G
lst = .Cells(.Rows.Count, 7).End(xlUp).Row
'Loop from the second row to the last row.
For i = 2 To lst
'Assign the value
ws.Cells(j, 1).Value = .Cells(i, 7).Value
'Move down 10 rows on the output
j = j + 10
Next i
End With
End Sub
here is the same thing but using range variables
Sub x()
Dim src As Range
Dim dst As Range
Set dst = Worksheets("Results").Range("a2") ' point to top cell of destination
With Worksheets("SalesData")
For Each src In Range(.Cells(2, "g"), .Cells(.Rows.Count, "g").End(xlUp)) ' loop through used cell range in column G
dst.Value = src.Value
Set dst = dst.Offset(10) ' move destination pointer down 10 rows
Next src
End With
End Sub
This is just for fun/practice for another way to do it:
Sub copyFromG()
Dim copyRng As Range, cel As Range
Dim salesWS As Worksheet, resultsWS As Worksheet
Set salesWS = Sheets("SalesData")
Set resultsWS = Sheets("Results")
Set copyRng = salesWS.Range("G2:G" & salesWS.Range("G2").End(xlDown).Row) ' assuming you have a header in G1
For Each cel In copyRng
resultsWS.Range("A" & 2 + 10 * copyRng.Rows(cel.Row).Row - 30).Value = cel.Value
Next cel
End Sub

Broken Macro -- Find Last Row and Add Data

I'm so close, but this isn't working quite yet.
What's wrong here?
Sub DUMMY_ITEMS()
'
' DUMMY_ITEMS Macro
Sheets("Operations").Select
Range("H2:V73").Select
Selection.Copy
Sheets("Raw Data").Select
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End Sub '
I guess you mean you got an error trying to use the PasteSpecial line.
As a recommendation, try to avoid using Select, Selection, and ActiveSheet, instead use fully qualified Worksheets and Ranges.
"Reduced" Code
Sub DUMMY_ITEMS()
'
' DUMMY_ITEMS Macro
Dim LastRow As Long
Sheets("Operations").Range("H2:V73").Copy
With Sheets("Raw Data")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("A" & LastRow + 1).PasteSpecial xlPasteValues
End With
End Sub

loop not iterating through list vba

The list seems to be only selecting the first cell in the list, can someone tell me where I am going wrong?
Everytime I run this, it takes the first cell in the list assigns that value to the cell in ATL tab (which will then run numerous formulas) and copies the range that I want and pastes on the Final tab. I want it to do this, but it will not move down the list to the other cells. I have about 40 cells that it should be iterating through, but it simply won't work. Any ideas?
Dim x As Integer
Dim List As Range
Dim intcount As Integer
Dim DCs As Worksheet
Dim Form As Worksheet
Dim Final As Worksheet
Dim DCdata As String
Dim wsList As String
Dim rnglistrange As Range
With ThisWorkbook
Set DCs = .Sheets("List1")
Set Form = .Sheets("ATL")
Set Final = .Sheets("Final")
End With
DCs.Select
intcount = DCs.Cells(Rows.Count, "A").End(xlUp).Row '--Get last row of list.
Set List = DCs.Range("A1:A" & intcount) '--Qualify our list.
For Each rnglistrange In List '--For every name in list...
Form.Select
Range("A2") = List.Value
Range("A632:N646").Copy
Final.Select
ActiveCell.SpecialCells(xlLastCell).Select
Selection.End(xlToLeft).Select
Selection.Offset(2, 0).Select
ActiveCell.Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next
the problem is in:
Range("A2") = List.Value
that would just put first value of List range in cell "A2"
while you want to put:
Range("A2") = rnglistrange
which would put current List cell Value in cell A2
but you may also want to consider this refactoring of your code, which has the main goal to avoid Select/Selection/Activate/ActiveXXX pattern in favor of fully qualified range references to both not loose control over what you're actually referencing and improve performance (and screen flickering)
Option Explicit
Sub main()
Dim listRng As Range, listCell As Range
Dim DCs As Worksheet, Form As Worksheet, Final As Worksheet
With ThisWorkbook
Set DCs = .Worksheets("List1")
Set Form = .Worksheets("ATL")
Set Final = .Worksheets("Final")
End With
With DCs
Set listRng = .Range("A1", .Cells(Rows.count, "A").End(xlUp)) '--Qualify our list.
End With
For Each listCell In listRng '--For every name in list...
With Form
.Range("A2") = listCell
.Range("A632:N646").Copy
End With
With Final
With .Cells(Rows.count, "A").End(xlUp).Offset(2)
.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
End With
End With
Next
End Sub
Line 25 of your listing says:
Range("A2") = List.Value
Change that line to:
Range("A2") = rnglistrange.Value
You will see then that it is iterating through the cells of your "List" range.

Simple VBA Script Error [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm still pretty new with VBA (learning for work, coming from a JS background) and I need a little help with this. My goal is: loop through each worksheet (except the "Summary" sheet, although I'm not sure how to exclude this from the loop) in the workbook and copy A2 in each sheet, as well as the last cell containing a value in column L of each sheet, and paste those next to each other in columns A and B on the "Summary Sheet", respectively. I'm not an expert with VBA syntax by any means, so if anyone has any way to refactor this (I know I don't need all the .select methods), I would appreciate it. Right now I'm getting an "invalid or unqualified reference" error on line 28. My goal is to learn, so if you have any input I would appreciate a short explanation of the logic. Thanks.
Sub Macro7()
'
' Macro7 Macro
'
' Keyboard Shortcut: Ctrl+c
Dim ws As Worksheet
Dim lastRow As Integer
Dim summaryRow As Integer
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
'Copy item number and paste on Summary Page'
Range("A2").Select
Selection.Copy
Sheets("Summary").Select
Range("A" & summaryRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy corresponding BOM item # and paste on Summary Page'
ws.Select
lastRow = .Cells(.Rows.Count, "L").End(xlUp).Row
Range("L" & lastRow).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Summary").Select
Range("B" & summaryRow).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
summaryRow = summaryRow + 1
Next ws
End Sub
You can avoid using .Select¹ by constructing a With ... End With statement that passes the parent worksheet reference along to the cells and range references. Direct value transfer is more expedient and more efficient than copying and pasting. Additionally, it avoids involving the clipboard altogether.
Sub Macro7()
Dim ws As Worksheet
Dim lastRow As Long
Dim summaryRow As Long
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
With ws
If LCase(.Name) <> "summary" Then
Worksheets("Summary").Range("A" & summaryRow).Resize(1, 2) = _
Array(.Range("A2").Value, .Cells(Rows.Count, "L").End(xlUp).Value)
summaryRow = summaryRow + 1
End If
End With
Next ws
End Sub
.¹ See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.
Your code looks fine apart from the '.' reference Jeeped pointed out.
I have just neatened up your code here as using .select is a little messy and long-winded (if you are building big macros it can add unnecessary work and slow it down a lot).
You can just do the commands straight from a range reference as shown below:
Sub Macro7()
Dim ws As Worksheet
Dim lastRow As Integer
Dim summaryRow As Integer
summaryRow = 1
For Each ws In ActiveWorkbook.Worksheets
'Copy item number and paste on Summary Page'
Range("A2").Copy
Sheets("Summary").Range("A" & summaryRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
'Copy corresponding BOM item # and paste on Summary Page'
lastRow = ws.Cells(Rows.Count, "L").End(xlUp).Row
Application.CutCopyMode = False
ws.Range("L" & lastRow).copy
Sheets("Summary").Range("B" & summaryRow).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
summaryRow = summaryRow + 1
Next ws
End Sub
I typically code out worksheets("").Range("").action everytime unless I am doing a lot of work on 1 sheet so that I can see easily what is going on when I glance over, but you'll find your own preference to working (don't forget you can step through your code with F8 to look at what it is doing every step of the way)
I hope this helps you start your VBA journey!