I'm new here and I'm looking to use Excel VBA to return the last used cell in a worksheet.
I'vv looked at Error in finding last used cell in Excel with VBA ) but that didn't answer the two problems I have:
The .Cells.Find(...).Row
method takes WAY too long in my code.
My meaning of "last used cell" might be odd...the cell can be blank. I want to take the column that has the last used cell and pair it with the row that has the last used cell.
To explain: Assume a sheet is empty except for data in A1:C3
, D2
and B4
. ( Exhibit 1 )
The last cell I'm interested in is D4
because I want the last cell in the sheet that includes all data in the sheet.
Now that I've explained what I'm looking for, can anyone provide suggestions as to either
Thank you!
Did you try this?
Dim r As Range
Set r = Sheet1.UsedRange.SpecialCells(xlCellTypeLastCell)
Debug.Print r.Address
Output for your example:
$D$4
The UsedRange is known to not always match the actually used data range. Some workaround would be to use CurrentRegion
:
Dim r As Range
With Sheet1.Range("A1").CurrentRegion
Set r = Sheet1.Cells(.Rows.count, .Columns.count)
End With
Debug.Print r.Address
also if the data does not start at A1
, maybe this:
With Sheet1.Cells.Find("*").CurrentRegion
Use Find
both by row and column to identify this cell.
Sub GetLastCellRange()
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Set rng1 = Cells.Find("*", [a1], xlFormulas, , xlByRows, xlPrevious)
Set rng2 = Cells.Find("*", [a1], xlFormulas, , xlByColumns, xlPrevious)
If Not rng1 Is Nothing Then
Set rng3 = Range([a1], Cells(rng1.Row, rng2.Column))
MsgBox "Range is " & rng3.Address(0, 0)
'if you need to actual select the range (which is rare in VBA)
Application.Goto rng3
Else
MsgBox "sheet is blank", vbCritical
End If
End Sub
'function that return a range object
Function fRNGlastCellInWorksheet(owsActive As Worksheet) As Range
Dim dblValues As Double
Dim dblRow As Double
Dim dblColumn As Double
Dim rngActive As Range
Dim dblValuesCount As Double
'total number of cells found containing a value in the whole worksheet
dblValues = Application.WorksheetFunction.CountA(owsActive.Cells)
dblValuesCount = 0
'loop through all columns in the worksheet until the condition is met and store the column number is a variable
For Each rngActive In owsActive.Columns
'add the total number of cells found containing a value in a specific column to the total number of cells found containing a value of all previous columns
dblValuesCount = dblValuesCount + Application.WorksheetFunction.CountA(rngActive.Cells)
'if the total number of cells found containing a value in the whole worksheet is equal to the total number of cells found containing a value in all previous columns, exit the loop
If dblValuesCount = dblValues Then
dblColumn = rngActive.Column
Exit For
End If
Next rngActive
dblValuesCount = 0
'loop through all rows in the worksheet until the condition is met and store the row number in a variable
For Each rngActive In owsActive.Rows
'add the total number of cells found containing a value in a specific row to the total number of cells found containing a value of all previous rows
dblValuesCount = dblValuesCount + Application.WorksheetFunction.CountA(rngActive.Cells)
'if the total number of cells found containing a value in the whole worksheet is equal to the total number of cells found containing a value in all previous rows, exit the loop
If dblValuesCount = dblValues Then
dblRow = rngActive.Row
Exit For
End If
Next rngActive
'use the variable containing the column number and the variable containing the row number to define the range cell
Set fRNGlastCellInWorksheet = owsActive.Cells(dblRow, dblColumn)
End Function
Although the answers are very valid, I'd be careful using SpecialCells, CurrentRegion and all those.
Although they work most of the time, they are not 100% reliable in my experience.
For example, CurrentRegion will not pick up all data if the data happens to have an empty column or row etc.
The best Approach, in my opinion is to always use headers with your data. You can then enumerate all headers and find the last used row in that column. You can then determine the greatest row used and now define your data range.
Btw, if you select the last cell in a specified column then use the Range.End(xlUp) you can quickly determine the last used row for that column without Looping.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.