How to specify a sheet to determine 'lastrow'? - excel

I am trying to determine 'lastrow' of the sheet that the macro is being run on.
I am working with two sheets. Sheet1 has about 150 rows of data and Sheet 2 only has two.
I expected that when I selected Sheet2 and assigned lastrow that it would take the count of rows from Sheet2, instead it is storing the row count from sheet1.
sub row_count()
dim lastrow as long
lastrow = Range("A" & Rows.Count).End(xlUp).row
if lastrow = 150 then
with sheets("sheet2")
.select
lastrow = Range("A" & Rows.Count).End(xlUp).row
msgbox lastrow '<----- Always returns the value of sheet1 instead of sheet2.
end with
end sub

You're using a With block, which means the program sees anything between 'With' and 'End With' as being prefixed by whatever you put after the keyword 'With', so to modify your code in place for sheet2 only:
Sub row_count()
Dim lastrow As Long
lastrow = Sheets("sheet2").Range("A" & Rows.Count).End(xlUp).Row
If lastrow = 150 Then
With Sheets("sheet2")
' .Select = Sheets("sheet2").Select
.Select
' .Range = Sheets("sheet2").Range
lastrow = .Range("A" & Rows.Count).End(xlUp).Row
MsgBox lastrow
End With
End Sub
If you want the code to run on the currently visible sheet you should change it to use the ActiveSheet property:
Sub row_count()
Dim lastrow As Long
lastrow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
If lastrow = 150 Then
With ActiveSheet ' use the currently visible sheet
.Select
lastrow = .Range("A" & Rows.Count).End(xlUp).Row
MsgBox lastrow
End With
End Sub
However, there are some ways to improve this code: for flexibility you could pass the worksheet as a parameter. Also, your End function might return the first used row if there is already data in the last used row (it's the same as clicking in the last row and pressing Ctrl & the up arrow, so you should start in a cell below that). Lastly, you do not need to select the sheet to get the last row:
Sub GetRowCounts()
row_count Sheets("sheet1")
row_count Sheets("sheet2")
End Sub
Sub row_count(ws As Worksheet)
Dim lastrow As Long
lastrow = ws.Range("A1000000").End(xlUp).Row
MsgBox lastrow
End Sub

I think these examples are the easiest to follow.
Sub FindingLastRow()
'PURPOSE: Different ways to find the last row number of a range
'SOURCE: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
'Ctrl + Shift + End
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
'Using UsedRange
sht.UsedRange 'Refresh UsedRange
LastRow = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Row
'Using Table Range
LastRow = sht.ListObjects("Table1").Range.Rows.Count
'Using Named Range
LastRow = sht.Range("MyNamedRange").Rows.Count
'Ctrl + Shift + Down (Range should be first cell in data set)
LastRow = sht.Range("A1").CurrentRegion.Rows.Count
End Sub
https://www.thespreadsheetguru.com/blog/2014/7/7/5-different-ways-to-find-the-last-row-or-last-column-using-vba
Keep an open mind though, there are lots of ways to do this same kind of thing.

If this statement...
lastrow = Range("A" & Rows.Count).End(xlUp).row
... really always returns the last row of Sheet1 instead of last row of Sheet2, then that is because you are looking at your Workbook open at Sheet1 all the time.
Whenever you have a Range or Cells statement like the above ( Range(...) ) without an explicit reference to a Worksheet, then ActiveSheet is what it is referenced to.
So to avoid that, this is what you do:
Dim Sht_1 as Worksheet
Dim Sht_2 as Worksheet
Dim Sht_1_Lastrow as Long
Dim Sht_2_Lastrow as Long
Set Sht_1 = ActiveWorkbook.Worksheets(1)
Set Sht_2 = ActiveWorkbook.Worksheets(2)
Sht_1_Lastrow = Sht_1.Range("A" & Sht_1.Rows.Count).End(xlUp).Row
Sht_2_Lastrow = Sht_2.Range("A" & Sht_2.Rows.Count).End(xlUp).Row
or
Sht_1_Lastrow = Sht_1.Cells(Sht_1.Rows.Count, "A").End(xlUp).Row
Sht_2_Lastrow = Sht_2.Cells(Sht_2.Rows.Count, "A").End(xlUp).Row
Above code block highlights the difference that makes a LastRow Variable explicitly tied to a certain Worksheet...
This way your problem cannot happen...

Related

Proper /Shorter code to select a Range from after Last Row till end of usedRange, VBA?

I need to select a Range from after Last Row till end of usedRange.
The below code works, But is there Proper /Shorter code.
Option Explicit
Sub Select_Blank_in_Usedrange()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim LastR As Long, LastR_UsedRange As Long
LastR = ws.Cells(Rows.Count, "A").End(xlUp).Row
LastR_UsedRange = ws.UsedRange.Rows.Count
ws.Range("A" & LastR + 1, "AE" & LastR_UsedRange).Select
End Sub
If the code works and has no redundant parts, I would say it's good. If I were to suggest an improvement, it would be to save the relevant addresses as Range Objects instead of Row numbers. This way you can assemble the larger range directly from the two corners, instead of having to concatenate the address in the final step.
Sub Select_Blank_in_Usedrange()
Dim ws As Worksheet: Set ws = ActiveSheet
Dim TopCorner As Range
Set TopCorner = ws.Cells(ws.Rows.Count, "A").End(xlUp).Offset(1, 0)
Dim BottomCorner As Range
With ws.UsedRange.Columns(31)
Set BottomCorner = .Cells(.Cells.Count)
End With
ws.Range(TopCorner, BottomCorner).Select
End Sub
To me, this is much clearer, and the constants are clearly displayed. This will make it easier to edit later, if the number of columns changes, or if the starting column moves from "A".
The shortest code will be the next:
Dim ws As Worksheet: Set ws = ActiveSheet
ws.Range("A" & ws.Range("A" & ws.rows.count).End(xlUp).row + 1, _
"AE" & ws.UsedRange.rows.count + ws.UsedRange.cells(1).row - 1).Select
It will also deal with the case when UsedRange does not start from the first row...

Copy rows from multiple sheets to another sequentially

I am trying to write a script that takes all the rows (after the header row), and copies them sequentially into the first tab. I also have 10 tabs i would like it to do this for, and sequentially paste them into the first tab (basically pull everything from the other sheets, and put it into the first sheet like a big master sheet or report)
I tried this, but its not working
Sub Report()
page = 2
row = 1
Dim lastRow As Integer
Dim pae As Integer
Dim rw As Integer
Dim WSheet(1 To 12) As Worksheet
lastRow = Worksheets(page).Cells(Rows.Count, "A").End(xlUp).rw
While (pge <= 12)
While (rw <= lastRow)
rw = rw + 1
ws1.Rows(row).EntireRow.Copy WSheet(pge).Range("A" & lastRow)
Wend
pge = pge + 1
Wend
End Sub
I was trying to get it to count how many rows have data, and then copy all of those rows to the first sheet before moving on to the next sheet,
It seems to skip over where i declare the variables, and then errors out on the lastrow assignment
Any help would be greatly appreciated
Please, try the next code:
Sub ReportMaster()
Dim ws1 As Worksheet, ws As Worksheet, lastRow As Long, lastER As Long, lastCol As Long
Set ws1 = Worksheets(1)
For Each ws In ActiveWorkbook.Worksheets
If ws.Name <> ws1.Name Then
lastRow = ws.Range("A" & ws.rows.count).End(xlUp).row
lastCol = ws.cells(1, ws.Columns.count).End(xlToLeft).Column
lastER = ws1.Range("A" & ws.rows.count).End(xlUp).row + 1 'last empty row
ws.Range(ws.Range("B1"), ws.cells(lastRow, lastCol)).Copy ws1.Range("A" & lastER)
End If
Next ws
End Sub

Copy a range in column using Excel VBA

I am trying to add a button, that adds a new column after the last column with values. This works.
Now I want to copy values to the new column. Values shall be copied from the last column from row 32 to the last one with a value in column A.
Right now Ihave a code for copying the whole column. How do I concentrate on the specific range?
Sub AddMeeting()
Dim ws As Worksheet
Dim lastcol As Long
Set ws = ActiveSheet
lastcol = ws.Cells(32, ws.Columns.Count).End(xlToLeft).Column
Columns(lastcol).Copy Destination:=Columns(lastcol + 1)
Range ((Cells.Columns.Count.End(xlLeft)) & Range(32)), (lastcol + 1) & Cells.Rows.Count.End(xlUp)
Application.CutCopyMode = False
End Sub
Values shall be copied from the last column from row 32 to the last one with a value in column A
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long, lCol As Long
Dim LastColumn As String
Dim rngToCopy As Range
'~~> Set this to the relevant worksheet
Set ws = Sheet1
With ws
'~~> Find last row in Col A
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Find last column in row 32
lCol = .Cells(32, .Columns.Count).End(xlToLeft).Column
'~~> Get Column Name from column number
' https://stackoverflow.com/questions/10106465/excel-column-number-from-column-name
LastColumn = Split(Cells(, lCol).Address, "$")(1)
Set rngToCopy = .Range("A32:" & LastColumn & lRow)
Debug.Print rngToCopy.Address
With rngToCopy
'
' Do what you want here
'
End With
End With
End Sub

Copy a column of data from the second row until the last row with data in it and paste as the last row in a column on another sheet VBA

I am working on a VBA code to copy data from the second cell "A2" down to the last cell with data in it (this range will change). I then want to paste that data starting at the last row of column A on another sheet.
My VBA code as of now seems to do nothing. Can someone help me figure out why?
Option Explicit
Public Sub AddNotes()
Dim lastRow1 As String
Dim lastRow2 As String
lastRow1 = Sheets("PropertiesToMatch").Cells(Rows.Count, 1).End(xlUp).Row
Sheets("PropertiesToMatch").Range("A2" & lastRow1).Copy
lastRow2 = Sheets("PropertyNotesToUpload").Cells(Rows.Count, "A").End(xlUp).Row + 1
Sheets("PropertyNotesToUpload").Range("A" & lastRow2).PasteSpecial Paste:=xlPasteValues
End Sub
Change
.Range("A2" & lastRow1)
to
.Range("A2:A" & lastRow1)
The first is only one cell, the second is the range you want.
Also, change
Dim lastRow1 As String
Dim lastRow2 As String
to
Dim lastRow1 As Long
Dim lastRow2 As Long
because Range.Row is a Long, not a String.
Option Explicit
Sub CopyPaste()
Dim i, j As Integer
Dim LastRow As Integer
With Sheets("PropertiesToMatch")
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
j = 2
For i = LastRow To 2 Step -1
Sheets("PropertiesToMatch").Cells(i, 1).Copy
Sheets("PropertyNotesToUpload").Cells(j, 1).PasteSpecial Paste:=xlPasteValues
j = j + 1
Next i
End Sub

1004 Application-Defined or Object Defined error

The error appears on the line before end sub, what is the correct way to select the range with the last row calculated?
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
End With
ActiveSheet.Range(Cells(LastRow, Columns("D:AH"))).Select
End Sub
The code below select all cells in the LastRow only , from Column "D" to Column "AH".
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
.Range(.Range("D" & LastRow), .Range("AH" & LastRow)).Select
End With
End Sub
If you wanted to select all rows (from row 1 to LastRow), from Column "D" to Column "AH".
Sub My_Script()
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, "D").End(xlUp).Row
.Range(.Range("D1"), .Range("AH" & LastRow)).Select
End With
End Sub
Note: not sure why you want to Select this range ? You can set this Range to a variable of type Range, and later to Copy or whatever you want to do with it. There's hardly a reason to ever use Select.

Resources