Ответ 1
Возможно, лучшим решением является работа вверх снизу:
k=sh.Range("A1048576").end(xlUp).row
Я написал простой код, чтобы проиллюстрировать мое затруднительное положение.
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?
Изображения:
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. Просто немного глупо делать что-то вроде этого.
Возможно, лучшим решением является работа вверх снизу:
k=sh.Range("A1048576").end(xlUp).row
Вы должны использовать 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
Вы также можете использовать функцию "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
CountRows = ThisWorkbook.Worksheets(1).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
Это хороший вопрос:)
Если у вас есть ситуация с 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
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
Если кто-то снова посмотрит на это, вы можете использовать это:
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
Вы пробовали: -
Sub test()
k = Cells(Rows.Count, "A").End(xlUp).Row
MsgBox (k)
End Sub
///catch заключается в том, что, если нет данных, он все равно возвращает 1.
Это работает для меня особенно в фильтрации столбцов pivots, когда я хочу подсчет ячеек с данными в отфильтрованном столбце. Уменьшите k
соответственно (k - 1)
, если у вас есть строка заголовка для фильтрации:
k = Sheets("Sheet1").Range("$A:$A").SpecialCells(xlCellTypeVisible).SpecialCells(xlCellTypeConstants).Count
Лучшее решение - использовать
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