#excel #vba
Вопрос:
Как я могу найти последнюю строку в диапазоне ячеек, содержащих формулу, где результатом формулы является фактическое значение, а не пустое?
Скажем упрощенно, что диапазон ячеек ("E1:E10")
содержит формулу, относящуюся к ячейкам от A1 до A10, как показано ниже =IF("A1"="","","A1")
. Но только ячейки с A1 по A6 имеют заполненное значение, поэтому результат формулы для ячеек с E7 по E10 будет пустым.
Пытаюсь сделать это с помощью:
lastRow = ActiveSheet.Range("E" amp; Rows.Count).End(xlUp).Row
приводит к тому, что последнее значение имеет значение 10
. Я хочу, чтобы значение lastRow было 6
в этом примере.
Фактический код намного сложнее, чем этот, поэтому я не могу просто проверить последнюю заполненную строку столбца A, так как формулы относятся к отдельным ячейкам на разных листах и добавляются динамически.
Ответ №1:
Я думаю, что более элегантный способ, чем был предложен @D_Bester
, — это использовать find()
опцию без зацикливания на диапазоне ячеек:
Sub test()
Dim cl As Range, iamp;
Set cl = Range("E1:E" amp; Cells(Rows.Count, "E").End(xlUp).Row)
i = cl.Find("*", , xlValues, , xlByRows, xlPrevious).Row
Debug.Print "Last row with data: " amp; i
End Sub
тест
Кроме того, более короткая версия кода, которая была предоставлена выше, является:
Sub test2()
Debug.Print [E:E].Find("*", , xlValues, , xlByRows, xlPrevious).Row
End Sub
Комментарии:
1. Отлично работает и было больше того, что я искал. У меня только один вопрос: что означает амперсанд
amp;
в объявлении переменнойi
? (Поскольку, похоже, это работает точно так же без амперсанда)2. @Pascale это значит
Dim i as Long
, что если вы удалитеamp;
, тоi
будет объявленоas Variant
. Это просто сокращенный метод кодирования, например%
, естьInteger
,amp;
естьLong
,$
естьString
,@
естьCurrency
,!
естьSingle
,#
естьDouble
, если не указано, тоVariant
3. @Василий, спасибо, что дал мне весь список сокращенных объявлений и -1 для Micrososft за то, что они не включили их в общую страницу объявления переменных
4. Этот ответ элегантен! Россия красиво
Ответ №2:
Вы хотите найти последнюю ячейку в столбце, которая не является пустой и не является пустой строкой(«»).
Просто следуйте последнему шагу с проверкой цикла на наличие непустой ячейки.
lastrow = ActiveSheet.Range("E" amp; ActiveSheet.Rows.Count).End(xlUp).Row
Do
If ActiveSheet.Cells(lastrow, 5).Value <> "" Then
Exit Do
End If
lastrow = lastrow - 1
Loop While lastrow > 0
If lastrow > 0 Then
Debug.Print "Last row with data: " amp; lastrow
Else
Debug.Print "No data in the column"
End If
Обратите внимание, что вы Rows.count
не указываете, на каком листе. Это означает, что он будет использовать активный лист. Конечно ActiveSheet.Range()
, также находится на активном листе. Но это плохая практика-смешивать Range
или Rows
с .Range
или .Rows
. Это указывает на бездумное использование, которое может укусить вас, если вы изменили ActiveSheet
, но не изменили неуказанную ссылку.
Комментарии:
1. Я уже думал о том, чтобы просмотреть их в обратном порядке, как вы предлагаете, но надеялся на более элегантный способ добиться этого.
2. Спасибо вам за ваш ответ и за то, что вы объяснили, как улучшить использование строк. Подсчет и ведомость активов.
3. Я думаю, что есть, попробуйте использовать подход «разделяй и властвуй». Как
2^20
равно 1048576. В этом и заключается ценностьRows.Count
. Тем не менее, выDo...Loop
никогда не будете повторять более 20 раз, чтобы достичьlastrow
.4. @D_Bester есть еще один вариант, чтобы найти последнюю непустую ячейку с помощью
find()
опции, без зацикливания по диапазону
Ответ №3:
Это должно помочь вам определить последнюю строку, содержащую формулу (в столбце A
на листе Sheet1
1).:
lastRow = Split(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ",")(UBound(Split(Sheet1.Range("A:A").SpecialCells(xlCellTypeFormulas).Address, ","))), "$")(2)
SpecialCells
используется для определения диапазона всех ячеек, содержащих формулу. Затем этот диапазон анализируется с использованием Split
. При Ubound
этом последняя из этих ячеек извлекается. Результат снова разделяется, чтобы извлечь номер строки.
Комментарии:
1. Я попытался применить ваш код, но он возвращает первую строку с формулой в ней. (Диапазон на моем листе от строки 3 до строки 26, и ваш последний ряд возвращает 3: когда я распечатываю его с помощью MsgBox, когда я ожидал, что он будет 21) Не уверен, что мне нужно настроить или даже если это хороший подход. Вы говорите: «Это должно помочь вам определить последнюю строку, содержащую формулу», но мне нужна последняя строка, содержащая формулу, в которой результат этой формулы не «» (пустая строка). Извините, если я неправильно понял ваш ответ, но у меня вообще нет опыта работы с vba, поэтому я полностью полагаюсь на то, что нахожу в stackoverflow.
2. @Ralph Свойство адреса ограничено строкой из 255 символов и поэтому может включать не все области, содержащие формулы.
Ответ №4:
Function returnLastRow()
With ActiveSheet.UsedRange
returnLastRow = .Find("*", , xlValues, , xlByRows, xlPrevious).Row
End With
End Function