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.
Related
I have Born Dates and want apply this formula
=(YEAR(NOW())-YEAR(A2))
in VBA for calculate age for whole row of dates
for example
A B
1 BornDate Age
2 09.06.1991 28
3 02.07.1973
4
5
my code works only for first two and stop without any error.
Sub btn_GetAge()
Dim LastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count).End(xlUp).Row
.Range("B2:B" & LastRow) = "=(YEAR(NOW())-YEAR(A1))"
End With
End Sub
Any idea or choose different formula ?
1) Cells requires a row and column, e.g. A1 is Cells(1,1)
2) Your formula (and better to specify the property) starts in row 2 but refers to A1
Sub btn_GetAge()
Dim LastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("B2:B" & LastRow).Formula = "=(YEAR(NOW())-YEAR(A2))"
End With
End Sub
You were very close:
Sub btn_GetAge()
Dim LastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
LastRow = .Cells(Rows.Count, "A").End(xlUp).Row
.Range("B2:B" & LastRow) = "=YEAR(TODAY())-YEAR(A2)"
End With
End Sub
Try:
Option Explicit
Sub Test()
Dim Lastrow As Long, i As Long
Dim CurrenctYear As Long, LoopYear As Long
With ThisWorkbook.Worksheets("Sheet1")
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
CurrenctYear = Year(Now)
For i = 1 To Lastrow
LoopYear = Year(.Range("A" & i).Value)
.Range("A" & i).Offset(0, 1).Value = CurrenctYear - LoopYear
Next i
End With
End Sub
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...
I am trying to find month of a date in column A and paste the result to column B. They both have headers, column A’s is Date and column B’s is Month. I would like to have vba codes simply calculating the month of column A.
Here are my codes so far,
Sub Month()
Dim ws As Worksheet
Dim lastrow As Long
Set ws = Worksheets("Sheet1")
ws.Cells(2, "B") = "=Month(A2)"
lastrow = Range("A" & Rows.Count).End(xlUp).Row
Range("B2").AutoFill Destination:=Range("B2:B" & lastrow), Type:=xlFillDefault
End Sub
But I keep getting AutoFill method of range class failed error and I tried to change the AutoFill type but it won’t work. If you guys know a faster way to do it, let me know, too. (not excel functions, plz)
Thank you,
This code will fail if the value of lastrow is 2. You need to add some logic to account for that. Also revised to use better method of finding "last row"
Sub month()
Dim ws As Worksheet
Dim lastrow As Long
Dim startCell As Range
Set ws = Worksheets("sheet1")
With ws
Set startCell = .Cells(2, 2) ' or .Range("B2")
lastrow = startCell.EntireColumn.Find("*", AFter:=startCell, SearchDirection:=xlPrevious).Row
If lastrow = startCell.Row Then lastrow = lastrow + 1
startCell.Formula = "=Month(A2)"
startCell.AutoFill Range(startCell, startCell.Cells(lastrow)), xlFillDefault
End With
End Sub
"The destination must include the source range". Refer the link. So please select the cell. If you want to apply formula to cell use .Formula = "=Month(A2)"
Sub Month()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
ws.Cells(2, "B") = "=Month(A2)"
ws.Cells(2, "B").Select
Selection.AutoFill Destination:=Range("B2:B" & Cells(Rows.Count, "B").End(xlUp).Row), Type:=xlFillDefault
End Sub
I have the following code which looks down column M to find empty cells. Each time an empty cell is found, then the entire row is deleted.
The code always leaves one row undeleted.
Can someone help to identify what is wrong with the code? I suspect that in deleting a row, the cell count goes wrong.
Private Sub CreateInvoice_Click()
Dim LastRow As Long
Dim cl As Range, rng As Range
With Sheet4
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng = Sheet4.Range("M1:M" & LastRow)
For Each cl In rng
If IsEmpty(cl) Then
cl.EntireRow.Select ' MsgBox .Range("A" & cl.Row).Value & " has nothing in it"
End If
Next
End With
End Sub
I would use a filter as it's the fastest and most efficient way of deleting empty rows. Also the below doesn't use .Select method.
Sub RemoveEmpties()
Dim ws As Worksheet
Dim rng As Range
Dim lastRow As Long
Set ws = Sheet4
lastRow = ws.Range("M" & ws.Rows.Count).End(xlUp).Row
Set rng = ws.Range("M1:M" & lastRow)
With rng
.AutoFilter Field:=1, Criteria1:=""
.Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
ws.AutoFilterMode = False
End Sub
Columns("M:M").Select
Selection.SpecialCells(xlCellTypeBlanks).Select
Selection.EntireRow.Delete
Try using this
Hi fellow communiteers,
I'm running a macro to delete entire rows that contain a certain value. The code works fine on small data sets but on the current one (~22,000 records) it consistently crashes Excel (2010). The code is below. Short of splitting the data into smaller chunks and running the macro again and again I'm not sure what to do.
Any help appreciated and here's the code:
Sub CleanOcc()
'Row counting
Dim Firstrow As Long
Dim Lastrow As Long
Dim Lrow As Long
Dim Lrow2 As Long
With Sheets("Occ_Prep")
'Cleans the occ_prep sheet ready for upload (Column and value can be changed)
Sheets("Occ_Prep").Activate
'Set the first and last row to loop through
Firstrow = .UsedRange.Cells(1).Row
Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
'We loop from Lastrow to Firstrow (bottom to top)
For Lrow2 = Lastrow To Firstrow Step -1
'We check the values in the A column in this example
With .Cells(Lrow2, "K")
If Not IsError(.Value) Then
If .Value = "0" Then .EntireRow.Delete
'This will delete each row with the Value "ron"
'in Column A, case sensitive.
End If
End With
Next Lrow2
End With
End Sub
Agree with Siddharth comment autofilter is way to go. This should be a lot quicker.
Option Explicit
Sub delrows()
Dim ws As Worksheet
Dim LR As Long
Dim rng As Range, frng As Range
Application.ScreenUpdating = False
Set ws = Sheets("dataset") '<-- Change this to name of your worksheet
With ws
LR = .Range("A" & Rows.Count).End(xlUp).Row
.AutoFilterMode = False
Set rng = .Range("A1:C" & LR) '<-- Assuming K is the last column
rng.AutoFilter 3, "0" '<-- 11 referes to Column K
Set frng = rng.Offset(1, 0).SpecialCells(xlCellTypeVisible) '<-- Don't delete the header
frng.EntireRow.Delete
.AutoFilterMode = False
End With
Application.ScreenUpdating = True
End Sub
Edit: I just cleaned ~20000 rows (3 columns) of data in ~5 seconds. Obviously it depends how many matches there are too.