Error in Finding Last Used Cell in Excel With VBA - Stack Overflow
Error in Finding Last Used Cell in Excel With VBA - Stack Overflow
LastRow = Range("E4:E48").End(xlDown).Row
Debug.Print LastRow
152
I am getting the wrong output when I put a single element into a cell. But when I put more than
one value into the cell, the output is correct. What's the reason behind this?
NOTE: I intend to make this a "one stop post" where you can use the Correct way to find the last
row. This will also cover the best practices to follow when finding the last row. And hence I will
311 keep on updating it whenever I come across a new scenario/information.
1. UsedRange
2. xlDown
3. CountA
UsedRange should NEVER be used to find the last cell which has data. It is highly unreliable. Try
this experiment.
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 1/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
Type something in cell A5 . Now when you calculate the last row with any of the methods given
below, it will give you 5. Now color the cell A10 red. If you now use the any of the below code,
you will still get 5. If you use Usedrange.Rows.Count what do you get? It won't be 5.
lastrow = Range("A1").End(xlDown).Row
What would happen if there was only one cell ( A1 ) which had data? You will end up reaching the
last row in the worksheet! It's like selecting cell A1 and then pressing End key and then
pressing Down Arrow key. This will also give you unreliable results if there are blank cells in a
range.
is also unreliable because it will give you incorrect result if there are blank cells in
CountA
between.
And hence one should avoid the use of UsedRange , xlDown and CountA to find the last cell.
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 2/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
With Sheets("Sheet1")
LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
End With
If you notice that we have a . before Rows.Count . We often chose to ignore that. See THIS
question on the possible error that you may get. I always advise using . before Rows.Count and
Columns.Count . That question is a classic scenario where the code will fail because the
Rows.Count returns 65536 for Excel 2003 and earlier and 1048576 for Excel 2007 and later.
Similarly Columns.Count returns 256 and 16384 , respectively.
The above fact that Excel 2007+ has 1048576 rows also emphasizes on the fact that we should
always declare the variable which will hold the row value as Long instead of Integer else you will
get an Overflow error.
Note that this approach will skip any hidden rows. Looking back at my screenshot above for
column A, if row 8 were hidden, this approach would return 5 instead of 8 .
With Sheets("Sheet1")
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lastrow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lastrow = 1
End If
End With
Sub FindLastRowInExcelTableColAandB()
Dim lastRow As Long
Dim ws As Worksheet, tbl as ListObject
Set ws = Sheets("Sheet1") 'Modify as needed
'Assuming the name of the table is "Table1", modify as needed
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 3/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
Set tbl = ws.ListObjects("Table1")
With tbl.ListColumns(3).Range
lastrow = .Find(What:="*", _
After:=.Cells(1), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End With
End Sub
9 @phan: Type something in cell A5. Now when you calculate the last row with any of the methods given
above, it will give you 5. Now color the cell A10 red. If you now use the any of the above code, you will still
get 5. If you use Usedrange.Rows.Count what do you get? It won't be 5. Usedrange is highly unreliable to
find the last row. – Siddharth Rout Aug 13 '12 at 19:48
6 Do note that .Find unfortunately messes up the user's settings in the Find dialog - i.e. Excel only has 1 set
of settings for the dialog, and you using .Find replaces them. Another trick is to still use UsedRange, but
use it as an absolute (but unreliable) maximum from which you determine the correct maximum. –
Carl Colijn Jan 31 '14 at 12:34
4 @CarlColijn: I wouldn't call it messing. :) Excel simply remembers the last setting. Even when you
manually do a Find , it remembers the last setting which in fact is a boon if one knows this "fact" –
Siddharth Rout Jan 31 '14 at 12:37
3 @KeithPark: Please go ahead :) Knowledge only has a meaning if it is spread :) – Siddharth Rout Aug 29
'14 at 7:11
9 I think that your description of UsedRange (it is highly unreliable to find the last cell which has data) is
misleading. UsedRange is simply not intended for that purpose, even though in some cases it may give the
correct result. I think that the experiment proposed adds to the confusion. The result obtained with
UsedRange ($A$1:$A$8) does not depend on first entering data an deleting it. The figure on the right will
still be the same even without having entered data an deleted it. Please see my answer. –
sancho.s ReinstateMonicaCellio Dec 24 '14 at 13:52
Note: this answer was motivated by this comment. The purpose of UsedRange is different
from what is mentioned in the answer above.
35
As to the correct way of finding the last used cell, one has first to decide what is
considered used, and then select a suitable method. I conceive at least three meanings:
2. Used = "... in use, meaning the section that contains data or formatting." As per official
documentation, this is the criterion used by Excel at the time of saving. See also this official
documentation. If one is not aware of this, the criterion may produce unexpected results, but
it may also be intentionally exploited (less often, surely), e.g., to highlight or print specific
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 4/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
regions, which may eventually have no data. And, of course, it is desirable as a criterion for
the range to use when saving a workbook, lest losing part of one's work.
3. Used = "... in use, meaning the section that contains data or formatting" or conditional
formatting. Same as 2., but also including cells that are the target for any Conditional
Formatting rule.
How to find the last used cell depends on what you want (your criterion).
For criterion 1, I suggest reading this answer. Note that UsedRange is cited as unreliable. I think
that is misleading (i.e., "unfair" to UsedRange ), as UsedRange is simply not meant to report the last
cell containing data. So it should not be used in this case, as indicated in that answer. See also
this comment.
For criterion 2, UsedRange is the most reliable option, as compared to other options also designed
for this use. It even makes it unnecessary to save a workbook to make sure that the last cell is
updated. Ctrl + End will go to a wrong cell prior to saving (“The last cell is not reset until you
save the worksheet”, from http://msdn.microsoft.com/en-
us/library/aa139976%28v=office.10%29.aspx. It is an old reference, but in this respect valid).
For criterion 3, I do not know any built-in method. Criterion 2 does not account for Conditional
Formatting. One may have formatted cells, based on formulas, which are not detected by
UsedRange or Ctrl + End . In the figure, the last cell is B3, since formatting was applied explicitly
to it. Cells B6:D7 have a format derived from a Conditional Formatting rule, and this is not
detected even by UsedRange . Accounting for this would require some VBA programming.
Your code uses the first cell in your range E4:E48 as a trampoline, for jumping down with
End(xlDown) .
The "erroneous" output will obtain if there are no non-blank cells in your range other than perhaps
the first. Then, you are leaping in the dark, i.e., down the worksheet (you should note the
difference between blank and empty string!).
Note that:
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 5/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
1. If your range contains non-contiguous non-blank cells, then it will also give a wrong result.
2. If there is only one non-blank cell, but it is not the first one, your code will still give you the
correct result.
3 I agree that one has first to decide what is considered used. I see at least 6 meanings. Cell has: 1) data,
i.e., a formula, possibly resulting in a blank value; 2) a value, i.e., a non-blank formula or constant; 3)
formatting; 4) conditional formatting; 5) a shape (including Comment) overlapping the cell; 6) involvement in
a Table (List Object). Which combination do you want to test for? Some (such as Tables) may be more
difficult to test for, and some may be rare (such as a shape outside of data range), but others may vary
based on the situation (e.g., formulas with blank values). – GlennFromIowa Apr 12 '17 at 18:42
I created this one-stop function for determining the last row, column and cell, be it for data,
formatted (grouped/commented/hidden) cells or conditional formatting.
21
Sub LastCellMsg()
Dim strResult As String
Dim lngDataRow As Long
Dim lngDataCol As Long
Dim strDataCell As String
Dim strDataFormatRow As String
Dim lngDataFormatCol As Long
Dim strDataFormatCell As String
Dim oFormatCond As FormatCondition
Dim lngTempRow As Long
Dim lngTempCol As Long
Dim lngCFRow As Long
Dim lngCFCol As Long
Dim strCFCell As String
Dim lngOverallRow As Long
Dim lngOverallCol As Long
Dim strOverallCell As String
With ActiveSheet
'DATA:
'last data row
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
lngDataRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 6/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
Else
lngDataRow = 1
End If
'strResult = strResult & "Last data row: " & lngDataRow & vbCrLf
'FORMATS:
'last data/formatted/grouped/commented/hidden row
strDataFormatRow = StrReverse(Split(StrReverse(.UsedRange.Address), "$")(0))
'strResult = strResult & "Last data/formatted row: " & strDataFormatRow &
vbCrLf
'CONDITIONAL FORMATS:
For Each oFormatCond In .Cells.FormatConditions
'OVERALL:
lngOverallRow = Application.WorksheetFunction.Max(lngDataRow, strDataFormatRow,
lngCFRow)
'strResult = strResult & "Last overall row: " & lngOverallRow & vbCrLf
lngOverallCol = Application.WorksheetFunction.Max(lngDataCol, lngDataFormatCol,
lngCFCol)
'strResult = strResult & "Last overall column: " & lngOverallCol & vbCrLf
strOverallCell = Replace(.Cells(lngOverallRow, lngOverallCol).Address, "$",
vbNullString)
strResult = strResult & "Last overall cell: " & strOverallCell & vbCrLf
MsgBox strResult
Debug.Print strResult
End With
End Sub
For more detailed results, some lines in the code can be uncommented:
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 8/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
One limitation exists - if there are tables in the sheet, results can become unreliable, so I decided
to avoid running the code in this case:
2 @franklin - I've just noticed an inbox message with your correction which was rejected by reviewers. I
corrected that mistake. I already used this function once when I needed and I will use it again, so really,
huge thanks, my friend! – ZygD Feb 9 '16 at 4:36
One important note to keep in mind when using the solution ...
Otherwise you will end up getting OVERFLOW errors in certain situations in .XLSX workbooks
I wonder that nobody has mentioned this, But the easiest way of getting the last used cell is:
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 9/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
This essentially returns the same cell that you get by Ctrl + End after selecting Cell A1 .
A word of caution: Excel keeps track of the most bottom-right cell that was ever used in a
worksheet. So if for example you enter something in B3 and something else in H8 and then later
on delete the contents of H8, pressing Ctrl + End will still take you to H8 cell. The above
function will have the same behavior.
2 Last Cell in Excel sometimes refers to an empty cell (from Used Range ) that is different from Last
Used Cell ;). – shA.t Apr 28 '15 at 4:28
1 The OP needed just the last row but you are right, last cell should be H5; But you can test your function
after deleting value in A5 You will see that the last cell is that empty cell, and I think your code needs some
edits like that Cells(1,1).Select() is invalid it maybe is ActiveSheet.Cells(1,1).Select ; Also in VBA
it's not recommended to use Select ;). – shA.t Apr 28 '15 at 5:06
5 This breaks two cardinal rules for Excel VBA: Don't use Select! And don't assume sheet you want is the
active one. – Rachel Hettinger Jun 4 '15 at 0:04
1 This is an old answer, but it is missing a Set . – BigBen Oct 11 '19 at 11:57
I would add to the answer given by Siddarth Rout to say that the CountA call can be skipped by
having Find return a Range object, instead of a row number, and then test the returned Range
8 object to see if it is Nothing (blank worksheet).
Also, I would have my version of any LastRow procedure return a zero for a blank worksheet,
then I can know it is blank.
Since the original question is about problems with finding the last cell, in this answer I will list
the various ways you can get unexpected results; see my answer to "How can I find last row
8 that contains data in the Excel sheet with a macro?" for my take on solving this.
I'll start by expanding on the answer by sancho.s and the comment by GlennFromIowa, adding
even more detail:
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 10/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
[...] one has first to decide what is considered used. I see at least 6 meanings. Cell has:
3) formatting;
4) conditional formatting;
Which combination do you want to test for? Some (such as Tables) may be more difficult
to test for, and some may be rare (such as a shape outside of data range), but others
may vary based on the situation (e.g., formulas with blank values).
A) Can there be hidden rows (e.g. autofilter), blank cells or blank rows?
C) Can the VBA macro affect the workbook or the application settings in any way?
With that in mind, let's see how the common ways of getting the "last cell" can produce
unexpected results:
The .End(xlDown) code from the question will break most easily (e.g. with a single non-
empty cell or when there are blank cells in between) for the reasons explained in the
answer by Siddharth Rout here (search for "xlDown is equally unreliable.") 👎
Any solution based on Count ing ( CountA or Cells*.Count ) or .CurrentRegion will also break
in presence of blank cells or rows 👎
A solution involving .End(xlUp) to search backwards from the end of a column will, just as
CTRL+UP, look for data (formulas producing a blank value are considered "data") in visible
rows (so using it with autofilter enabled might produce incorrect results ⚠).
You have to take care to avoid the standard pitfalls (for details I'll again refer to the answer by
Siddharth Rout here, look for the "Find Last Row in a Column" section), such as hard-coding
the last row ( Range("A65536").End(xlUp) ) instead of relying on sht.Rows.Count .
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 11/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
sht.UsedRange (described in detail in the answer by sancho.s here) considers both data and
formatting (though not conditional formatting) and resets the "used range" of the
worksheet, which may or may not be what you want.
Note that a common mistake is to use .UsedRange.Rows.Count ⚠, which returns the number of
rows in the used range, not the last row number (they will be different if the first few rows are
blank), for details see newguy's answer to How can I find last row that contains data in the
Excel sheet with a macro?
.Find allows you to find the last row with any data (including formulas) or a non-blank value
in any column. You can choose whether you're interested in formulas or values, but the
catch is that it resets the defaults in the Excel's Find dialog ⚠, which can be highly
confusing to your users. It also needs to be used carefully, see the answer by Siddharth Rout
here (section "Find Last Row in a Sheet")
More explicit solutions that check individual Cells ' in a loop are generally slower than re-
using an Excel function (although can still be performant), but let you specify exactly what
you want to find. See my solution based on UsedRange and VBA arrays to find the last cell
with data in the given column -- it handles hidden rows, filters, blanks, does not modify the
Find defaults and is quite performant.
to use Long instead of Integer to store the row numbers (to avoid getting Overflow with
more than 65k rows) and
to always specify the worksheet you're working with (i.e. Dim ws As Worksheet ...
ws.Range(...) instead of Range(...) )
when using .Value (which is a Variant ) avoid implicit casts like .Value <> "" as they will fail
if the cell contains an error value.
However this question is seeking to find the last row using VBA, I think it would be good to
include an array formula for worksheet function as this gets visited frequently:
4
{=ADDRESS(MATCH(INDEX(D:D,MAX(IF(D:D<>"",ROW(D:D)-ROW(D1)+1)),1),D:D,0),COLUMN(D:D))}
You need to enter the formula without brackets and then hit Shift + Ctrl + Enter to make it an
array formula.
This will give you address of last used cell in the column D.
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 12/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
M--
17.7k 7 42 73
sub last_filled_cell()
msgbox range("A65536").end(xlup).row
3 end sub
Here, A65536 is the last cell in the Column A this code was tested on excel 2003.
Can you explain how your code answers this old question? – shoover Oct 1 '15 at 19:14
1 While this answer is probably correct and useful, it is preferred if you include some explanation along with it
to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a
change (possibly unrelated) that causes it to stop working and users need to understand how it once
worked. – Kevin Brown Oct 2 '15 at 21:48
I was looking for a way to mimic the CTRL + Shift + End , so dotNET solution is great, except
with my Excel 2010 I need to add a set if I want to avoid an error:
2
Function GetLastCell(sh As Worksheet) As Range
Set GetLastCell = sh.Cells(1, 1).SpecialCells(xlLastCell)
End Function
Sub test()
Dim ws As Worksheet, r As Range
Set ws = ActiveWorkbook.Sheets("Sheet1")
Set r = GetLastCell(ws)
MsgBox r.Column & "-" & r.Row
End Sub
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 13/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
IMHO the risk of a hidden row with data being excluded is too significant to let xlUp be
1
considered a One stop answer. I agree it's simple and will work MOST of the time, but it presents
the risk of understating the last row, without any warning. This could produce CATASTROPHIC
results at some poinit for someone who jumped on Stack Overlow and was looking to "sure way"
to capture this value.
The Find method is flawless and I would approve of it as a One Stop Answer. However the
drawback of changing the Find settings can be annoying, particularly if this is part of a UDF.
The other answers posted are okay, however the complexity gets a little excessive. Thus here's
my attempt to find a balance of reliability, minimal complexity, and not using Find .
End If
End If
Do While IsEmpty(Intersect(rng, _
rng.Parent.Rows(LastRowNumber)))
LastRowNumber = LastRowNumber - 1
Loop
End Function
With very large sets of data and a massive gap between used range and last row in specified
columns, this will perform slower, in rare cases SIGNIFICANTLY slower.
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 14/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
For the last 3+ years these are the functions that I am using for finding last row and last column
per defined column(for row) and row(for column):
1
Last Column:
Dim ws As Worksheet
End Function
Last Row:
Dim ws As Worksheet
End Function
For the case of the OP, this is the way to get the last row in column E :
Debug.Print lastRow(columnToCheck:=Range("E4:E48").Column)
Here we may use the well-known Excel formulas, which give us the last row of a worksheet in
Excel, without involving VBA - =IFERROR(LOOKUP(2,1/(NOT(ISBLANK(A:A))),ROW(A:A)),0)
In order to put this in VBA and not to write anything in Excel, using the parameters for the latter
functions, something like this could be in mind:
Dim ws As Worksheet
End Function
End Function
This will return an incorrect result if the last row/column is hidden. – PGSystemTester Nov 28 '19 at 4:15
@PGSystemTester - yes, but in my understanding, when I program it, if it is hidden it is not the last
column/row that is needed. – Vityata Nov 28 '19 at 7:20
Glad that works for you. I suspect your situation is not a typical use-case. More frequently when i work with
clients that need the last row, they are seaching for the lowest cell with data, not the lowest visible cell with
data. Anyway... glad it works. 👍 – PGSystemTester Nov 29 '19 at 7:09
@PGSystemTester - I got your point, but taking care of the structure and not allowing invisible cells works
like a charm. – Vityata Nov 29 '19 at 10:19
@PGSystemTester - yeah, if the task possibly allows empty rows, I would probably use the EVAL() and
the famous Excel formula. Although people may think that Eval() is evil and this is another interesting
story on which to write... – Vityata Nov 29 '19 at 19:42
Sub lastRow()
0 Dim i As Long
i = Cells(Rows.Count, 1).End(xlUp).Row
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 16/17
9/27/2020 Error in finding last used cell in Excel with VBA - Stack Overflow
MsgBox i
End Sub
sub LastRow()
'Paste & for better understanding of the working use F8 Key to run the code .
dim WS as worksheet
dim i as long
set ws = thisworkbook("SheetName")
ws.activate
ws.range("a1").select
ws.range("a1048576").select
activecell.end(xlup).select
i= activecell.row
End sub
Highly active question. Earn 10 reputation in order to answer this question. The reputation requirement helps
protect this question from spam and non-answer activity.
https://stackoverflow.com/questions/11169445/error-in-finding-last-used-cell-in-excel-with-vba/11169920#11169920 17/17