Найти диапазон, который содержит только первую ячейку последней строки? - PullRequest
0 голосов
/ 09 декабря 2018

Мне нужно вычислить диапазон, который содержит только одну ячейку.Эта ячейка из последней строки и первого столбца.Если лист пуст, диапазон составляет 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

Как это сделать?

Ответы [ 4 ]

0 голосов
/ 10 декабря 2018

Последняя использованная строка и заданный уровень пересечения столбцов.

Метод поиска

Я бы назвал это самым безопасным и самым элегантным способом: с помощью Найти метод.

'*******************************************************************************
' 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.    *
'*******************************************************************************
0 голосов
/ 09 декабря 2018

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
0 голосов
/ 09 декабря 2018

Последняя использованная строка и указанный столбец Пересечение feat.UsedRange

Одним из элегантных способов было бы использование свойства 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
'*******************************************************************************
0 голосов
/ 09 декабря 2018

Если я правильно понял, вы хотите найти последнюю строку в некотором диапазоне (или группу столбцов).

Один из способов достижения этого может заключаться в цикле по каждому столбцу в пределах диапазона, поиске какой строки в последней ячейке (в этом конкретном столбце) и проверке, не превышает ли она наибольшую последнюю строку в этой области.цикл.

В приведенном ниже коде, если вы измените "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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...