Ron de Bruin said:
In VBA the best thing is to use this functions
You can use this in your code then for example
Lr = LastRow(Sheets("Sheet2"))
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _ ....
Function Lastcol(sh As Worksheet)
On Error Resume Next
Lastcol = sh.Cells.Find(What:="*", _ ....
Ron's suggestion only works in VBA when his functions are called from VBA
procedures (Subs). As there's no way to pass worksheet objects from
worksheet cells to VBA udfs, as well as the fact that the .Find *method* of
the Range class always fails when called from UDFs (at least through
XL2000), they won't work as udfs.
Since the OP states that these would be used 'in excel formulas', it's not
unreasonable to suppose that means in cell formulas. To do that, a different
approach is needed.
Function lr(Optional r As Range) As Variant
Dim ur As Range, c As Range, i As Long, n As Long
'there arguments for & against volatility - optional to uncomment
'Application.Volatile
If r Is Nothing Then Set r = Application.Caller
If Not TypeOf r Is Range Then Set r = ActiveCell
Set ur = r.Parent.UsedRange
n = ur.Rows.Count
For i = n To 1 Step -1
Set c = ur.Cells(n, 1)
If Not IsEmpty(c.Value) Then Exit For
If Not IsEmpty(c.End(xlToRight).Value) Then Exit For
Next i
lr = ur.Row + i - 1
End Function
Function lc(Optional r As Range) As Variant
Dim ur As Range, c As Range, i As Long, n As Long
'there arguments for & against volatility - optional to uncomment
'Application.Volatile
If r Is Nothing Then Set r = Application.Caller
If Not TypeOf r Is Range Then Set r = ActiveCell
Set ur = r.Parent.UsedRange
n = ur.Columns.Count
For i = n To 1 Step -1
Set c = ur.Cells(1, n)
If Not IsEmpty(c.Value) Then Exit For
If Not IsEmpty(c.End(xlDown).Value) Then Exit For
Next i
lc = ur.Column + i - 1
End Function