Calculate the last populated row once, then use that value in both the sort key and the complete sort range.
Sub SortTransactions()
Dim wb As Workbook
Dim ws As Worksheet
Dim lastRow As Long
Set wb = Workbooks("AllTransactions.xlsm")
Set ws = wb.Worksheets("AllTransactions")
lastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
If lastRow < 2 Then Exit Sub
With ws.Sort
.SortFields.Clear
.SortFields.Add Key:=ws.Range("B2:B" & lastRow), _
SortOn:=xlSortOnValues, Order:=xlAscending, _
DataOption:=xlSortNormal
.SetRange ws.Range("A1:F" & lastRow)
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.Apply
End With
End Sub
lastRow is found by starting at the bottom of column B and moving upward to the final populated cell. Range.End behaves like pressing End+Up Arrow in Excel.^1^
The two dynamic ranges serve different purposes:
-
B2:B<lastRow>is the sort key—the values determining row order. TheKeyparameter accepts aRange.^2^ -
A1:F<lastRow>is the complete range whose rows are rearranged.SetRangedefines the worksheet range over which the sort operates.^3^
All Range, Cells, and Rows references are qualified with ws, preventing Excel from accidentally using whichever worksheet happens to be active. Consequently, Activate and Select are unnecessary; VBA can operate directly on a worksheet’s ranges.^4^
If column B can contain blanks near the bottom while other columns still contain data, determine lastRow from a column that is populated on every transaction row, such as column A, and keep column B as the sort key:
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
References