Почему ваш метод не работает: здесь есть две причины. Первое, когда вы кладете Rows.Count
, что для Rows
нет ссылки - это свойство Range
. Чтобы исправить это, вам просто нужно сослаться на тот же диапазон, который вы уже используете (просто добавьте его перед вызовом Rows.Count
так:
Function FindLastDataLine(strColName As String) As Long
FindLastDataLine = Range(strColName).Offset(Range(strColName).Rows.Count - 1, 0).End(xlUp).Row
End Function
Вторая причина в том, что вы используете Offset
. Offset
буквально сдвигает Range
, насколько вы говорите. Вы не хотите сдвигать весь диапазон ячеек, но найдите последнюю ячейку в этом диапазоне. Вы можете сделать это довольно просто, изменив Offset
на Cells
, удалив начальный вызов Range()
(так как мы собираемся выбрать одну ячейку), и изменив 0
на нужный вам столбец. Однако, поскольку вы передаете столбец как "A:A"
, это невозможно, поэтому вам придется заменить его на Range(strColName).Column
следующим образом:
Function FindLastDataLine(strColName As String) As Long
FindLastDataLine = Cells(Range(strColName).Rows.Count, Range(strColName).Column).End(xlUp).Row
End Function
Лучшее решение: следующее решение будет работать на всех последних версиях MS Office (2003, 2007 и 2010) и обрабатывать ошибки. Вы вызываете это, передавая либо букву столбца, либо номер столбца:
Function GetLastDataRow(col As Variant) As Long
GetLastDataRow = -1
If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
On Error Resume Next
GetLastDataRow = _
Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
On Error GoTo 0
End If
End Function
Ниже показано, как вы будете вызывать эту функцию, и некоторые примеры выходных данных. Предположим, что весь лист чист, за исключением некоторых случайных данных, введенных в ячейки с B1
по B8
и B10
(B9
оставлено пустым). Обратите внимание, что вы не вводите столбец как диапазон, а скорее букву столбца или номер столбца (недопустимые значения возвращают -1):
GetLastDataRow(1) = 1 GetLastDataRow("A") = 1
GetLastDataRow(2) = 10 GetLastDataRow("B") = 10
GetLastDataRow("AX") = 1 GetLastDataRow("A:X") = -1
GetLastDataRow("Oops...") = -1 GetLastDataRow(200) = 1
В качестве технического примечания, если метод Cells
завершается ошибкой, предполагается, что ввод был неверным, поэтому функция возвращает -1. Я призываю вас использовать эту практику (возвращать неверные значения, если ввод был неверным) в вашей функции, это очень поможет вам избежать ошибок в будущем.
Как это работает, он находит последнюю возможную строку в любом конкретном столбце (зависит от вашей версии MS Office), а затем использует метод End
чтобы найти последнюю ячейку в этом столбце с данными.
Вот альтернативная версия, которая будет возвращать 0, если все ячейки в этом столбце пустые:
Function GetLastDataRow(col As Variant) As Long
GetLastDataRow = -1
If (IsNumeric(col) And col >= 1) Or Len(col) <= 2 Then
On Error Resume Next
If IsEmpty(Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Value) Then
GetLastDataRow = 0
Else
GetLastDataRow = _
Cells(Cells(1, col).EntireColumn.Rows.Count, col).End(xlUp).Row
End If
On Error GoTo 0
End If
End Function
Пример вывода:
GetLastDataRow(1) = 0 GetLastDataRow("A") = 0
GetLastDataRow(2) = 10 GetLastDataRow("B") = 10
GetLastDataRow("AX") = 0 GetLastDataRow("A:X") = -1
GetLastDataRow("Oops...") = -1 GetLastDataRow(200) = 0