Wie kann ich letzte Zeile finden, die Daten in einer bestimmten Spalte enthält?
Frage
Wie finde ich die letzte Zeile, die Daten in einer bestimmten Spalte enthält und auf einem bestimmten Blatt?
Lösung
Wie wäre:
Function GetLastRow(strSheet, strColumn) As Long
Dim MyRange As Range
Set MyRange = Worksheets(strSheet).Range(strColumn & "1")
GetLastRow = Cells(Rows.Count, MyRange.Column).End(xlUp).Row
End Function
In Bezug auf einen Kommentar, dies wird die Zeilennummer der letzten Zelle zurückkehren, selbst wenn nur eine einzelne Zelle in der letzten Zeile Daten hat:
Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Andere Tipps
Sie sollten die .End(xlup)
verwenden, sondern stattdessen 65536 verwenden Sie vielleicht verwenden möchten:
sheetvar.Rows.Count
Auf diese Weise es für Excel arbeitet 2007, die ich glaube, mehr als 65536 Zeilen hat
function LastRowIndex(byval w as worksheet, byval col as variant) as long
dim r as range
set r = application.intersect(w.usedrange, w.columns(col))
if not r is nothing then
set r = r.cells(r.cells.count)
if isempty(r.value) then
LastRowIndex = r.end(xlup).row
else
LastRowIndex = r.row
end if
end if
end function
Verbrauch:
? LastRowIndex(ActiveSheet, 5)
? LastRowIndex(ActiveSheet, "AI")
Einfach und schnell:
Dim lastRow as long
Range("A1").select
lastRow = Cells.Find("*",SearchOrder:=xlByRows,SearchDirection:=xlPrevious).Row
Beispiel für die Verwendung:
cells(lastRow,1)="Ultima Linha, Last Row. Youpi!!!!"
'or
Range("A" & lastRow).Value = "FIM, THE END"
Hier ist eine Lösung für die letzte Zeile, letzte Spalte zu finden, oder letzte Zelle. Es befasst sich mit der A1 Z1S1-Bezugsart Dilemma für die Spalte es findet. Ich wünsche, ich Kredit geben könnte, aber nicht finden können / erinnern, wo ich es her habe, so „Danke!“ es war wem auch immer, dass der ursprüngliche Code irgendwo dort.
Sub Macro1
Sheets("Sheet1").Select
MsgBox "The last row found is: " & Last(1, ActiveSheet.Cells)
MsgBox "The last column (R1C1) found is: " & Last(2, ActiveSheet.Cells)
MsgBox "The last cell found is: " & Last(3, ActiveSheet.Cells)
MsgBox "The last column (A1) found is: " & Last(4, ActiveSheet.Cells)
End Sub
Function Last(choice As Integer, rng As Range)
' 1 = last row
' 2 = last column (R1C1)
' 3 = last cell
' 4 = last column (A1)
Dim lrw As Long
Dim lcol As Integer
Select Case choice
Case 1:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
Case 2:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Case 3:
On Error Resume Next
lrw = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
lcol = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Last = Cells(lrw, lcol).Address(False, False)
If Err.Number > 0 Then
Last = rng.Cells(1).Address(False, False)
Err.Clear
End If
On Error GoTo 0
Case 4:
On Error Resume Next
Last = rng.Find(What:="*", _
After:=rng.Cells(1), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
Last = R1C1converter("R1C" & Last, 1)
For i = 1 To Len(Last)
s = Mid(Last, i, 1)
If Not s Like "#" Then s1 = s1 & s
Next i
Last = s1
End Select
End Function
Function R1C1converter(Address As String, Optional R1C1_output As Integer, Optional RefCell As Range) As String
'Converts input address to either A1 or R1C1 style reference relative to RefCell
'If R1C1_output is xlR1C1, then result is R1C1 style reference.
'If R1C1_output is xlA1 (or missing), then return A1 style reference.
'If RefCell is missing, then the address is relative to the active cell
'If there is an error in conversion, the function returns the input Address string
Dim x As Variant
If RefCell Is Nothing Then Set RefCell = ActiveCell
If R1C1_output = xlR1C1 Then
x = Application.ConvertFormula(Address, xlA1, xlR1C1, , RefCell) 'Convert A1 to R1C1
Else
x = Application.ConvertFormula(Address, xlR1C1, xlA1, , RefCell) 'Convert R1C1 to A1
End If
If IsError(x) Then
R1C1converter = Address
Else
'If input address is A1 reference and A1 is requested output, then Application.ConvertFormula
'surrounds the address in single quotes.
If Right(x, 1) = "'" Then
R1C1converter = Mid(x, 2, Len(x) - 2)
Else
x = Application.Substitute(x, "$", "")
R1C1converter = x
End If
End If
End Function
Public Function LastData(rCol As Range) As Range
Set LastData = rCol.Find("*", rCol.Cells(1), , , , xlPrevious)
End Function
Verbrauch: ?lastdata(activecell.EntireColumn).Address
die Lösungen auf alle unter Berufung Einbau-Verhalten (wie .Find
und .End
) Beschränkungen, die nicht gut dokumentiert sind (siehe beantworten für Details).
Ich brauche etwas, das:
- Findet die letzte nicht leer Zelle (dh, dass hat eine Formel oder Wert , auch wenn es eine leere Zeichenfolge) in einer bestimmten Spalte
- setzt auf Primitiven mit gut definierten Verhalten
- Funktioniert zuverlässig mit Autofilter und Benutzeränderungen
- Läuft so schnell wie möglich auf 10.000 Zeilen (in einem
- ... mit Leistung Abfallen nicht von einer Klippe mit zufälligen Daten oder Formatierung am Ende des Blattes (bei ~ 1 M Zeilen) put
Worksheet_Change
Handler, ohne das Gefühl träge ausgeführt werden)
Die Lösung unter:
- Verwendet
UsedRange
die obere Schranke für die Zeilennummer zu finden (die Suche nach der wahren „letzten Zeile“ schnell im gemeinsamen Fall zu machen, wo es bis zum Ende des verwendeten Bereichs liegt); - Geht rückwärts die Zeile mit Daten in der angegebenen Spalte zu finden;
- ... VBA-Arrays mit einzeln jede Zeile zu vermeiden Zugriff (im Fall gibt es viele Zeilen in den
UsedRange
wir überspringen müssen)
(keine Tests, sorry)
' Returns the 1-based row number of the last row having a non-empty value in the given column (0 if the whole column is empty)
Private Function getLastNonblankRowInColumn(ws As Worksheet, colNo As Integer) As Long
' Force Excel to recalculate the "last cell" (the one you land on after CTRL+END) / "used range"
' and get the index of the row containing the "last cell". This is reasonably fast (~1 ms/10000 rows of a used range)
Dim lastRow As Long: lastRow = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row - 1 ' 0-based
' Since the "last cell" is not necessarily the one we're looking for (it may be in a different column, have some
' formatting applied but no value, etc), we loop backward from the last row towards the top of the sheet).
Dim wholeRng As Range: Set wholeRng = ws.Columns(colNo)
' Since accessing cells one by one is slower than reading a block of cells into a VBA array and looping through the array,
' we process in chunks of increasing size, starting with 1 cell and doubling the size on each iteration, until MAX_CHUNK_SIZE is reached.
' In pathological cases where Excel thinks all the ~1M rows are in the used range, this will take around 100ms.
' Yet in a normal case where one of the few last rows contains the cell we're looking for, we don't read too many cells.
Const MAX_CHUNK_SIZE = 2 ^ 10 ' (using large chunks gives no performance advantage, but uses more memory)
Dim chunkSize As Long: chunkSize = 1
Dim startOffset As Long: startOffset = lastRow + 1 ' 0-based
Do ' Loop invariant: startOffset>=0 and all rows after startOffset are blank (i.e. wholeRng.Rows(i+1) for i>=startOffset)
startOffset = IIf(startOffset - chunkSize >= 0, startOffset - chunkSize, 0)
' Fill `vals(1 To chunkSize, 1 To 1)` with column's rows indexed `[startOffset+1 .. startOffset+chunkSize]` (1-based, inclusive)
Dim chunkRng As Range: Set chunkRng = wholeRng.Resize(chunkSize).Offset(startOffset)
Dim vals() As Variant
If chunkSize > 1 Then
vals = chunkRng.Value2
Else ' reading a 1-cell range requires special handling <http://www.cpearson.com/excel/ArraysAndRanges.aspx>
ReDim vals(1 To 1, 1 To 1)
vals(1, 1) = chunkRng.Value2
End If
Dim i As Long
For i = UBound(vals, 1) To LBound(vals, 1) Step -1
If Not IsEmpty(vals(i, 1)) Then
getLastNonblankRowInColumn = startOffset + i
Exit Function
End If
Next i
If chunkSize < MAX_CHUNK_SIZE Then chunkSize = chunkSize * 2
Loop While startOffset > 0
getLastNonblankRowInColumn = 0
End Function
Ich mag eine zuverlässige Art und Weise hinzuzufügen UsedRange
mit der zuletzt benutzten Zeile zu finden:
lastRow = Sheet1.UsedRange.Row + Sheet1.UsedRange.Rows.Count - 1
Ebenso die zuletzt verwendete Spalte finden Sie können finden Sie in diesem
Ergebnis in Direkt-Fenster:
?Sheet1.UsedRange.Row+Sheet1.UsedRange.Rows.Count-1
21
Public Function GetLastRow(ByVal SheetName As String) As Integer
Dim sht As Worksheet
Dim FirstUsedRow As Integer 'the first row of UsedRange
Dim UsedRows As Integer ' number of rows used
Set sht = Sheets(SheetName)
''UsedRange.Rows.Count for the empty sheet is 1
UsedRows = sht.UsedRange.Rows.Count
FirstUsedRow = sht.UsedRange.Row
GetLastRow = FirstUsedRow + UsedRows - 1
Set sht = Nothing
End Function
sheet.UsedRange.Rows.Count: retrurn Anzahl von Zeilen verwendet wird, nicht leere Zeile über der ersten Reihe verwendet wird, schließen
Wenn Zeile 1 leer ist, und die zuletzt verwendete Zeile 10, UsedRange.Rows.Count wird 9 zurückkehren, nicht 10.
Diese Funktion gibt die erste Zeile Anzahl von Usedrange berechnen und Anzahl der Zeilen Usedrange.
Last_Row = Range("A1").End(xlDown).Row
Nur um zu überprüfen, lassen Sie uns sagen, dass Sie die Zeilennummer der letzten Zeile mit den Daten in der Zelle C1 drucken möchten.
Range("C1").Select
Last_Row = Range("A1").End(xlDown).Row
ActiveCell.FormulaR1C1 = Last_Row
Sub test()
MsgBox Worksheets("sheet_name").Range("A65536").End(xlUp).Row
End Sub
Dies ist auf der Suche nach einem Wert in der Spalte A
wegen "A65536"
.
Die erste Zeile bewegt den Cursor auf dem letzten nicht-leere Zeile in der Spalte. Die zweite Zeile druckt, die Spalten Zeile.
Selection.End(xlDown).Select
MsgBox(ActiveCell.Row)
Function LastRow(rng As Range) As Long
Dim iRowN As Long
Dim iRowI As Long
Dim iColN As Integer
Dim iColI As Integer
iRowN = 0
iColN = rng.Columns.count
For iColI = 1 To iColN
iRowI = rng.Columns(iColI).Offset(65536 - rng.Row, 0).End(xlUp).Row
If iRowI > iRowN Then iRowN = iRowI
Next
LastRow = iRowN
End Function