簡體   English   中英

查找僅包含最后一行的第一個單元格的范圍?

[英]Find range which contains first cell only of last line?

我需要計算一個僅包含一個單元格的范圍。 該單元格來自最后一行和第一列。 如果工作表為空,則范圍為A1:A1

我知道有很多方法可以計算出最后一行,但是我正在尋找一種優雅的方法來獲得最后一行的第一個單元格。 也許一些例子可以更好地解釋。

例子1

 A B C D
1
2  X
3      X
4    X

結果1

Range = A4:A4

范例#2

 A B C D
1

結果#2

Range = A1:A1

這個怎么做?

如果我正確理解,則希望找到某個范圍(或一堆列)中的最后一行。

實現此目的的一種方法可能是遍歷該范圍內的每一列,找到最后一個單元格(在該特定列中)的哪一行,並檢查它是否超出了循環中到目前為止最大的最后一行。

在下面的代碼中,如果將"Sheet1"更改為工作表所需要的名稱,並將范圍從"A4:Z5"更改為"A:Z""A1:D4" (或您所用的形式) ),然后應顯示您要保存的單元格的地址。

Option Explicit

Private Sub ShowLastCell()
    ' Change this to what your sheet is called.
    With ThisWorkbook.Worksheets("Sheet1")

        ' Change this to the range you need to check.
        With .Range("A4:Z5")
            Dim firstColumnToCheck As Long
            firstColumnToCheck = .Columns(1).Column

            Dim lastColumnToCheck As Long
            lastColumnToCheck = .Columns(.Columns.Count).Column
        End With

        Dim maxLastRow As Long
        Dim columnIndex As Long

        For columnIndex = firstColumnToCheck To lastColumnToCheck
            maxLastRow = Application.Max(maxLastRow, .Cells(.Rows.Count, columnIndex).End(xlUp).Row)
        Next columnIndex

        MsgBox ("I think the cell you want is " & .Cells(maxLastRow, "A").Address & ":" & .Cells(maxLastRow, "A").Address)

    End With
End Sub

GetFirstCellInLastLine將返回所引用工作表的最后一行中的第一個單元格作為Range對象。 然后,您可以使用它來做您想做的事情。 例如,為活動工作表打印到立即窗口:

Debug.Print GetFirstCellInLastLine(ActiveSheet).Address

如果工作表為空白,則設置為返回“ 注意 ”,但是您可以根據需要進行修改:

'''
''' Returns the first used cell in the last line of the worksheet.
''' Returns "Nothing" if the worksheet is blank.
'''
Public Function GetFirstCellInLastLine(ws As Excel.Worksheet) As Excel.Range

Dim rng As Excel.Range

    Set rng = ws.UsedRange.Cells(ws.UsedRange.Rows.Count, 1)

    If ((ws.UsedRange.Columns.Count > 1) And ws.Range(rng, rng.End(xlToRight)).Columns.Count <= ws.UsedRange.Columns.Count) Then
        Set rng = ws.Range(rng, rng.End(xlToRight))
        If VBA.IsEmpty(rng.Cells(1, 1)) Then
            Set rng = rng.Cells(1, rng.Columns.Count)
        Else
            Set rng = rng.Cells(1, 1)
        End If
    ElseIf (ws.UsedRange.Columns.Count = 1) And VBA.IsEmpty(rng.Cells(1, 1)) Then
        Set rng = Nothing
    End If

    Set GetFirstCellInLastLine = rng

End Function

上次使用的行和指定的列相交專長。 二手范圍

優雅的方法之一是使用UsedRange屬性。

進階版

'*******************************************************************************
' Purpose:    Using the UsedRange Property, creates a reference to the cell    *
'             range at the intersection of the last used row and a specified   *
'             column in a worksheet and prints its address and the address     *
'             of the UsedRange to the Immediate Window.                        *
'*******************************************************************************
Sub LastUR_Column_UsedRange()

  Const cVntCol As Variant = "A"  ' Column
  Dim objRngT As Range            ' Target Range

  With ThisWorkbook.Worksheets("Sheet1")
    If .Cells(.UsedRange.Rows.Count + .UsedRange.Row - 1, cVntCol).Row = 1 _
        And .Cells(1, Columns.Count).End(xlToLeft).Column = 1 _
        And IsEmpty(.Cells(1, 1)) Then
      Debug.Print "objRngT = Nothing (Empty Worksheet)"
     Else
      Set objRngT = .Cells(.UsedRange.Rows.Count + .UsedRange.Row - 1, cVntCol)
      Debug.Print "objRngT = " & objRngT.Address & " calculated from the " _
          & "used range (" & .UsedRange.Address & ")."
      Set objRngT = Nothing
    End If
  End With

End Sub
'*******************************************************************************

課程版本

'*******************************************************************************
' Purpose:    Using the UsedRange Property, creates a reference to the cell    *
'             range at the intersection of the last used row and a specified   *
'             column in a worksheet and prints subresults and  its address     *
'             to the Immediate Window.                                         *
'*******************************************************************************
Sub LastUR_Column_UsedRange_Lesson()

  ' When you declare the column as variant you can use
  ' column letter or number e.g. "A" or 1, "D" or 4 ...
  Const cVntCol As Variant = "A"    ' Column

  Dim objRngT As Range              ' Target Range

  Dim lngLast As Long               ' Last Row
  Dim lngRows As Long               ' Number of Rows
  Dim lngFirst As Long              ' First Row

  With ThisWorkbook.Worksheets("Sheet1")

    ' Finding first row and number of rows is easy.
    lngFirst = .UsedRange.Row
        Debug.Print "lngFirst  = " & lngFirst
    lngRows = .UsedRange.Rows.Count
        Debug.Print "lngRows   = " & lngRows

    ' Note1: Only when there is data in the first row, the number of rows
    '        is equal to the last row.

    ' Therefore we have to calculate the last row.
    lngLast = lngRows + lngFirst - 1
        Debug.Print "lngLast   = " & lngLast

    ' Now imagine you have the first data in row 2, and you have 3 rows
    ' which would mean the last data is in row 4 (rows 2, 3, 4). So when you add
    ' 2 + 3 = 5, you have to subtract 1 row, because you counted row 2 twice.

    ' Note2: If there is data in the first row then lngFirst = 1.
    '        So the formula will calculate:
    '          lnglast = lngRows + 1 - 1
    '          lngLast = lngRows + 0
    '         which proves the statement in Note1.

    ' The previous three lines could have been written in one line:
    lngLast = .UsedRange.Rows.Count + .UsedRange.Row - 1
        Debug.Print "lngLast   = " & lngLast & " (One Row Version)"

    ' Now we have all the ingredients for the Target Range.
    Set objRngT = .Cells(lngLast, cVntCol)
        Debug.Print "objRngT   = " & objRngT.Address _
            & " (Before Check if Empty)"

    ' And again all this could have been written in one line:
    Set objRngT = .Cells(.UsedRange.Rows.Count + .UsedRange.Row - 1, cVntCol)
        Debug.Print "objRngT   = " & objRngT.Address & " (One Row Version)" _
             & " (Before Check if Empty)"
    ' then you wouldn't need variables lngLast, lngFirst and lngRows. On the
    ' other hand you wouldn't have learned how this big formula was created.

    ' Now the problem is that if the worksheet is empty, UsedRange will show
    ' the cell in the first row as the used range. So we have to address this
    ' issue by checking if all of the following three conditions are true.
    ' - Check if the resulting cell range is in the first row (1).
    ' - Check if from the end of the first row to the beginning the result
    '   is the first cell (1) (all other cells are empty).
    ' - Check if the cell ("A1") is empty.
    If objRngT.Row = 1 And _
        .Cells(1, Columns.Count).End(xlToLeft).Column = 1 And _
        IsEmpty(.Cells(1, 1)) Then
      Debug.Print "objRngT   = Nothing (Empty Worksheet)"
     Else
      Debug.Print "objRngT   = " & objRngT.Address
    End If
    ' Although this is a working code, we can conclude that we should have done
    ' this checking at the beginning which will be done in the advanced version.

  End With

  Set objRngT = Nothing

End Sub
'*******************************************************************************

上次使用的行和指定的列相交專長。

查找方法

我將這稱為最安全 ,最優雅的方法:使用Find方法。

'*******************************************************************************
' Purpose:    Using the Find method, creates a reference to the cell range at  *
'             the intersection of the last used row and a specified column     *
'             in a worksheet and prints its address to the Immediate window.   *
'*******************************************************************************
Sub LastUR_Column_Find()

  Const cVntCol As Variant = "A"  ' Column Letter or Number ("A" or 1)
  Dim objRngT As Range            ' Target Range

  With ThisWorkbook.Worksheets("Sheet1")
    If Not .Cells.Find("*", .Cells(.Rows.Count, .Columns.Count), -4123, , 1) _
        Is Nothing Then
      Set objRngT = .Cells(.Cells.Find("*", , , , , 2).Row, cVntCol)
      Debug.Print "objRngT = " & objRngT.Address
      Set objRngT = Nothing
     Else
      Debug.Print "objRngT = Nothing (Empty Worksheet)"
    End If
  End With

End Sub
'*******************************************************************************
' Remarks:    If you carefully study the "Find method as it applies to         *
'             the Range object." from "Visual Basic Help", you will realize    *
'             why exactly those four arguments and their parameters in         *
'             the If statement must be included and why three of them can      *
'             be omitted, but a new one has to be added in the Else clause.    *
'*******************************************************************************

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM