VBA - Range.Row.Count

Я написал простой код, чтобы проиллюстрировать мое затруднительное положение.

Sub test()
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Sheets("Sheet1")

    Dim k As Long

    k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
End Sub

Что происходит: мы подсчитываем строки, содержащие значения, начинающиеся с A1. Если число строк, содержащих значения > 1, код отлично работает. Однако, если A1 является единственной ячейкой, которая содержит любое значение, k = 1 048 576, которое, я думаю, является максимальным количеством строк, разрешенных в Excel.

Почему не k = 1?

Изображения:

The code works

This is wrong

EDIT: Обходной путь, который я использую, следующий:

Sub test()
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Sheets("Sheet1")

    Dim k As Long

    k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
    If k = 1048576 Then
        k = 1
    End If
    MsgBox (k)
End Sub

Так как k всегда равно 1048576, когда число строк со значениями равно 1. Просто немного глупо делать что-то вроде этого.

Ответы

Ответ 1

Возможно, лучшим решением является работа вверх снизу:

k=sh.Range("A1048576").end(xlUp).row

Ответ 2

Вы должны использовать UsedRange вместо этого так:

Sub test()
    Dim sh As Worksheet
    Dim rn As Range
    Set sh = ThisWorkbook.Sheets("Sheet1")

    Dim k As Long

    Set rn = sh.UsedRange
    k = rn.Rows.Count + rn.Row - 1
End Sub

Часть + rn.Row - 1 заключается в том, что UsedRange запускается только в первой строке и столбце, поэтому, если у вас есть что-то в строках с 3 по 10, но строки 1 и 2 пустые, rn.Rows.Count будет 8

Ответ 3

Вы также можете использовать функцию "Last" от Ron de Bruin (http://www.rondebruin.nl/win/s9/win005.htm), она отлично работала для меня, а также возвращает последний столбец и ячейка, если хотите. Чтобы получить последнюю строку, используйте ее как

lastRow = Last(1,yourRange)

Я нашел это довольно удобным.

Function Last(choice As Long, rng As Range)
'Ron de Bruin, 5 May 2008
' 1 = last row
' 2 = last column
' 3 = last cell
    Dim lrw As Long
    Dim lcol As Long

    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
        On Error GoTo 0

        On Error Resume Next
        lcol = rng.Find(What:="*", _
                        After:=rng.Cells(1), _
                        Lookat:=xlPart, _
                        LookIn:=xlFormulas, _
                        SearchOrder:=xlByColumns, _
                        SearchDirection:=xlPrevious, _
                        MatchCase:=False).Column
        On Error GoTo 0

        On Error Resume Next
        Last = rng.Parent.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

    End Select
End Function

Ответ 4

CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count

Ответ 5

Это хороший вопрос:)

Если у вас есть ситуация с 1 ячейкой (A1), важно определить, не является ли вторая заявленная ячейка пустой (sh.Range("A1").End(xlDown)). Если это правда, значит, ваш ассортимент вышел из-под контроля:) Посмотрите на код ниже:

Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Arkusz1")

Dim k As Long

If IsEmpty(sh.Range("A1").End(xlDown)) = True Then
    k = 1

Else
    k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count

End If

Ответ 6

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Rows.Count

или

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Cells.Count

или

k = sh.Range("A2", sh.Range("A1").End(xlDown)).Count

Ответ 7

Если кто-то снова посмотрит на это, вы можете использовать это:

Sub test()
    Dim sh As Worksheet
    Set sh = ThisWorkbook.Sheets("Sheet1")

    Dim k As Long
    k = sh.Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp)).Rows.Count
End Sub

Ответ 8

Вы пробовали: -

Sub test()

    k = Cells(Rows.Count, "A").End(xlUp).Row

    MsgBox (k)

End Sub

///catch заключается в том, что, если нет данных, он все равно возвращает 1.

Ответ 9

Это работает для меня особенно в фильтрации столбцов pivots, когда я хочу подсчет ячеек с данными в отфильтрованном столбце. Уменьшите k соответственно (k - 1), если у вас есть строка заголовка для фильтрации:

k = Sheets("Sheet1").Range("$A:$A").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants).Count

Ответ 10

Лучшее решение - использовать

Cells(Rows.Count, 1).End(xlUp).Row

так как он считает количество ячеек, пока не найдет последнюю записанную.

В отличие от

Range("A1", sh.Range("A1").End(xlDown)).Rows.Count

он выбирает диапазон "от-до" и отображает номер строки последнего занятого.
Диапазон подразумевает два минимальных значения, поэтому... пока A1 имеет значение диапазона, он продолжает считать до предела (1048576), после чего отображается.

Sub test()

Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets(1)
Dim k As Long

    k = Cells(Rows.Count, 1).End(xlUp).Row
    MsgBox k

    k = sh.Range("A1", sh.Range("A1").End(xlDown)).Rows.Count
    MsgBox k

End Sub

enter image description here