Hvordan kan jeg finne siste raden som inneholder data i Excel-ark med en makro?

stemmer
52

Hvordan kan jeg finne den siste raden som inneholder data i en bestemt kolonne, og på en bestemt ark?

Publisert på 16/09/2008 klokken 08:54
kilden bruker
På andre språk...                            


13 svar

stemmer
-2
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 
Svarte 16/09/2008 kl. 08:56
kilden bruker

stemmer
7
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

bruk:

? LastRowIndex(ActiveSheet, 5)
? LastRowIndex(ActiveSheet, "AI")
Svarte 16/09/2008 kl. 09:14
kilden bruker

stemmer
41

Hva med:

 Sub GetLastRow(strSheet, strColumn)
 Dim MyRange As Range
 Dim lngLastRow As Long

    Set MyRange = Worksheets(strSheet).Range(strColum & "1")

    lngLastRow = Cells(Rows.Count, MyRange.Column).End(xlUp).Row
 End Sub

Re Kommentar

Dette

  Cells.Find("*",SearchOrder:=xlByRows,SearchDirection:=xlPrevious).Row

Vil returnere radnummeret for den siste cellen selv når bare en enkelt celle i den siste raden har data.

Svarte 16/09/2008 kl. 09:16
kilden bruker

stemmer
-1

Første funksjon flytter markøren til den siste ikke-tom rad i kolonnen. Andre funksjonen utskrifter som kolonner rad.

Selection.End(xlDown).Select
MsgBox (ActiveCell.Row)
Svarte 16/09/2008 kl. 09:23
kilden bruker

stemmer
21

Du bør bruke den .End(xlup), men i stedet for å bruke 65 536 du kanskje vil bruke:

sheetvar.Rows.Count

På den måten det fungerer for Excel 2007 som jeg tror har mer enn 65536 rader

Svarte 16/09/2008 kl. 13:21
kilden bruker

stemmer
3
Public Function LastData(rCol As Range) As Range    
    Set LastData = rCol.Find("*", rCol.Cells(1), , , , xlPrevious)    
End Function

bruk: ?lastdata(activecell.EntireColumn).Address

Svarte 16/09/2008 kl. 14:34
kilden bruker

stemmer
3

Her er en løsning for å finne den siste raden, siste kolonne, eller siste cellen. Det løser A1 R1C1 Reference stil dilemma for kolonnen den finner. Skulle ønske jeg kunne gi kreditt, men kan ikke finne / huske hvor jeg fikk det fra, så "Takk!" til hvem var det som postet den opprinnelige koden et sted der ute.

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
Svarte 07/06/2009 kl. 16:53
kilden bruker

stemmer
7

Enkel og rask:

Dim lastRow as long
Range("A1").select
lastRow = Cells.Find("*",SearchOrder:=xlByRows,SearchDirection:=xlPrevious).Row

Eksempel bruk:

cells(lastRow,1)="Ultima Linha, Last Row. Youpi!!!!"

'or 

Range("A" & lastRow).Value = "FIM, THE END"
Svarte 26/08/2014 kl. 13:14
kilden bruker

stemmer
-1
sub test()
msgbox Worksheets("sheet_name").Range("A65536").End(xlUp).Row
end sub

Dette er å se etter verdien i kolonne A på grunn av "A65536"

Svarte 30/10/2015 kl. 09:08
kilden bruker

stemmer
1

Jeg vil gjerne legge til en mer pålitelig måte å bruke UsedRangefor å finne den sist brukte rad:

lastRow = Sheet1.UsedRange.Row + Sheet1.UsedRange.Rows.Count - 1

Tilsvarende for å finne den sist brukte kolonnen kan du se dette

skriv bildebeskrivelse her

Resultere i en umiddelbar vindu:

?Sheet1.UsedRange.Row+Sheet1.UsedRange.Rows.Count-1
 21 
Svarte 13/03/2016 kl. 18:16
kilden bruker

stemmer
0
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 antall rader som brukes, ikke omfatte tom rad over den første raden for

hvis rad 1 er tom, og den sist brukte p er 10, vil UsedRange.Rows.Count returnere 9, ikke 10.

Denne funksjon beregner den første raden antall UsedRange pluss antall UsedRange rader.

Svarte 26/09/2017 kl. 05:21
kilden bruker

stemmer
1

Alle løsningene er avhengige av innebygde atferd (som .Findog .End) har begrensninger som ikke er godt dokumentert (se mine andre svar for detaljer).

Jeg trengte noe som:

  • Finner den siste ikke er tom celle (dvs. som ikke har noen formel eller verdi , selv om det er en tom streng) i en bestemt kolonne
  • Avhengig av primitiver med veldefinerte oppførsel
  • Fungerer pålitelig med autofilters og bruker modifikasjoner
  • Kjører så fort som mulig på 10.000 rader (som skal kjøres i et Worksheet_Changebehandlingsprogram uten følelsen svak)
  • ... med ytelsen ikke faller utenfor en skrent med tilfeldige data eller formater sette helt i enden av platen (på ~ 1 M rader)

Løsningen nedenfor:

  • Bruker UsedRangeå finne den øvre grensen for radnummer (for å gjøre søket etter den sanne "siste raden" fast i den vanlige tilfelle hvor det er nær slutten av brukt område);
  • Går bakover for å finne den rad med data i en gitt kolonne;
  • ... bruker VBA arrays for å unngå å få tilgang til hver rad individuelt (i tilfelle det er mange rader i UsedRangevi trenger å hoppe over)

(Ingen tester, beklager)

' 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
Svarte 22/04/2018 kl. 21:53
kilden bruker

stemmer
0
  Last_Row = Range("A1").End(xlDown).Row

Bare for å bekrefte, la oss si at du ønsker å skrive ut radnummeret siste raden med dataene i celle C1.

Range("C1").Select
Last_Row = Range("A1").End(xlDown).Row
ActiveCell.FormulaR1C1 = Last_Row
Svarte 27/03/2019 kl. 15:27
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more