programing

특정 열에 데이터가 포함된 마지막 행을 찾으려면 어떻게 해야 합니까?

starjava 2023. 4. 17. 21:13
반응형

특정 열에 데이터가 포함된 마지막 행을 찾으려면 어떻게 해야 합니까?

특정 열과 특정 시트의 데이터가 포함된 마지막 행을 찾으려면 어떻게 해야 합니까?

그럼 어떻게 해?

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

코멘트에 관해서는 마지막 행의 단일 셀에만 데이터가 있는 경우에도 마지막 셀의 행 번호가 반환됩니다.

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

를 사용해야 합니다..End(xlup)65536 대신 다음을 사용할 수 있습니다.

sheetvar.Rows.Count

이렇게 하면 65536개 이상의 행을 가진 Excel 2007에서 작동합니다.

심플하고 신속함:

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

사용 예:

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

'or 

Range("A" & lastRow).Value = "FIM, THE END"
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

사용방법:

? LastRowIndex(ActiveSheet, 5)
? LastRowIndex(ActiveSheet, "AI")
Public Function LastData(rCol As Range) As Range    
    Set LastData = rCol.Find("*", rCol.Cells(1), , , , xlPrevious)    
End Function

사용방법:?lastdata(activecell.EntireColumn).Address

내장된 동작에 의존하는 모든 솔루션(예:.Find그리고..End에는 충분한 설명이 없는 제한이 있습니다(자세한 내용은 다른 답변을 참조).

난 뭔가 필요한게 있었어:

  • 특정 열에서 비어 있지 않은 마지막 셀(예: 비어 있는 문자열일지라도 공식 또는 값이 있는 셀)을 찾습니다.
  • 명확한 동작을 가진 기본 요소에 의존합니다.
  • 자동 필터 및 사용자 수정 시 안정적으로 작동
  • 10,000개의 행에서 가능한 한 빠르게 실행(실행)Worksheet_Change핸들러(느림하지 않음)
  • ...시트의 맨 끝에 우발적인 데이터나 포맷을 배치하여 성능 저하가 발생하지 않음(최대 100만 행)

솔루션:

  • 사용하다UsedRange행 번호의 상한을 찾는다(사용된 범위의 끝에 가까운 일반적인 경우에서 진정한 "마지막 행"을 빠르게 검색한다).
  • 지정된 열에 데이터가 있는 행을 찾기 위해 뒤로 이동합니다.
  • ...VBA 어레이를 사용하여 각 행에 개별적으로 액세스하지 않도록 합니다(여러 행이 있는 경우).UsedRange건너뛸 필요가 있다)

(테스트 없음, 죄송합니다)

' 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

다음은 마지막 행, 마지막 열 또는 마지막 셀을 찾기 위한 솔루션입니다.발견된 열에 대한 A1 R1C1 참조 스타일의 딜레마를 해결합니다.신용을 주고 싶지만 어디서 구했는지 기억이 안 나기 때문에 어딘가에 원래 코드를 게시한 사람에게 "감사합니다!"라고 말합니다.

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

다음 중 하나의 신뢰할 수 있는 방법을 추가하고자 합니다.UsedRange마지막으로 사용한 행을 찾으려면:

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

마찬가지로 마지막으로 사용한 열을 찾으려면 다음과 같이 하십시오.

여기에 이미지 설명 입력

즉시창이 나타납니다.

?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.Used Range.Rows.Count: 사용된 행의 개수, 사용된 첫 번째 행 위에 빈 행을 포함하지 않음

행 1이 비어 있고 마지막으로 사용한 행이 10인 경우 UsedRange.Rows.Count는 10이 아닌 9를 반환합니다.

이 함수는 UsedRange의 첫 번째 행 번호와 UsedRange 행 수를 계산합니다.

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

확인을 위해 마지막 행의 행 번호를 C1 셀의 데이터와 함께 인쇄하려고 합니다.

Range("C1").Select
Last_Row = Range("A1").End(xlDown).Row
ActiveCell.FormulaR1C1 = Last_Row

이진 검색을 사용하여 비어 있지 않은 마지막 행 가져오기

  • 숨겨진 값이 있더라도 올바른 값 이벤트를 반환합니다.
  • 마지막으로 비어 있지 않은 셀 앞에 빈 셀이 있는 경우 잘못된 값이 반환될 수 있습니다(예를 들어 5행은 비어 있지만 10행은 비어 있지 않은 마지막 행).
Function getLastRow(col As String, ws As Worksheet) As Long
    Dim lastNonEmptyRow As Long
    lastNonEmptyRow = 1
    Dim lastEmptyRow As Long

    lastEmptyRow = ws.Rows.Count + 1
    Dim nextTestedRow As Long
    
    Do While (lastEmptyRow - lastNonEmptyRow > 1)
        nextTestedRow = Application.WorksheetFunction.Ceiling _
            (lastNonEmptyRow + (lastEmptyRow - lastNonEmptyRow) / 2, 1)
        If (IsEmpty(ws.Range(col & nextTestedRow))) Then
            lastEmptyRow = nextTestedRow
        Else
            lastNonEmptyRow = nextTestedRow
        End If
    Loop
    
    getLastRow = lastNonEmptyRow
    

End Function
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 
Sub test()
    MsgBox Worksheets("sheet_name").Range("A65536").End(xlUp).Row
End Sub

을 찾고 있습니다.A "A65536".

첫 번째 줄은 커서를 열의 비어 있지 않은 마지막 행으로 이동합니다.두 번째 줄은 해당 열 행을 인쇄합니다.

Selection.End(xlDown).Select
MsgBox(ActiveCell.Row)

언급URL : https://stackoverflow.com/questions/71180/how-can-i-find-last-row-that-contains-data-in-a-specific-column

반응형