Последняя ячейка листа excel vba

Хитрости »

1 Май 2011              403912 просмотров


Очень часто при внесении данных на лист Excel возникает вопрос определения последней заполненной или первой пустой ячейки. Чтобы впоследствии с этой первой пустой ячейки начать заносить данные. В этой теме я опишу несколько способов определения последней заполненной ячейки.

В качестве переменной, которой мы будем присваивать номер последней заполненной строки, у нас во всех примерах будет lLastRow. Объявлять мы её будем как Long. Для экономии памяти можно было бы использовать и тип Integer, но т.к. строк на листе может быть больше 32767(это максимальное допустимое значение переменных типа Integer) нам понадобиться именно Long, во избежание ошибки. Подробнее про типы переменных можно прочитать в статье Что такое переменная и как правильно её объявить

Одинаковые переменные для всех примеров
Во всех примерах ниже мы будем запоминать номер последней строки или столбца в одни и те же переменные:

    Dim lLastRow As Long
    'а для lLastCol можно было бы применить и тип Integer,
    'т.к. столбцов в Excel пока меньше 32767, но для однообразности назначим тоже Long
    Dim lLastCol As Long
  • Определение последней ячейки через свойство End
  • Определение последней ячейки через SpecialCells
  • Определение последней ячейки через UsedRange
  • Определение последней ячейки через метод Find
  • Несколько практических кодов

  • Способ 1:

    Определение

    последней заполненной строки

    через свойство End

        lLastRow = Cells(Rows.Count,1).End(xlUp).Row
        'или
        lLastRow = Cells(Rows.Count, "A").End(xlUp).Row

    1 или «A» — это номер или имя столбца, последнюю заполненную ячейку в котором мы определяем. По сути обе приведенные строки дадут абсолютно одинаковый результат. Просто иногда удобнее указать номер столбца, а иногда его имя. Поэтому использовать можно любой из приведенных вариантов, в зависимости от ситуации.
    Определение последнего столбца через свойство End

    lLastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    1 — это номер строки, последнюю заполненную ячейку в которой мы определяем.

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

    Метод основан именно на принципе работы свойства End. На примере поиска последней строки опишу принцип так, как бы мы это делали руками через выделение ячеек на листе:

    • выделили самую последнюю ячейку столбца А на листе(для Excel 2007 и выше это А1048576, а для Excel 2003 — А65536)
    • и выполнили переход вверх комбинацией клавиш Ctrl+стрелка вверх. Данная комбинация заставляет Excel двигаться вверх(если точнее, то в направлении стрелки, нажатой вместе с Ctrl) до тех пор, пока не встретиться первая ячейка с формулой или значением. А в случае, если сочетание было вызвано из уже заполненных ячеек — то до первой пустой. И как только Excel доходит до этой ячейки — он её выделяет
    • А через свойство .Row мы просто получаем номер строки этой выделенной ячейки

    Нюансы:

    • даже если в ячейке нет видимого значения, но есть формула — End посчитает ячейку не пустой. С одной стороны вполне справедливо. Но иногда нам надо определить именно «визуально» заполненные ячейки. Поиск ячеек при подобных условиях будет описан ниже(Способ 4: Определение последней ячейки через метод Find)
    • если на листе заполнены все строки в просматриваемом столбце(или будут заполнены несколько последних ячеек столбца или даже только одна последняя) — то результат может быть неверный(ну или не совсем такой, какой ожидали)
    • Данный способ игнорирует строки, скрытые фильтром, группировкой или командой Скрыть (Hide). Т.е. если последняя строка таблицы будет скрыта, то данный метод вернет номер последней видимой заполненной строки, а не последней реально заполненной.

    Ну а если надо получить первую пустую ячейку на листе(а не первую заполненную) — придется вспомнить математику. Т.к. последнюю заполненную мы определили, то первая пустая — следующая за ней. Т.е. к результату необходимо прибавить 1. Это хоть и очевидно, но на всякий случай все же лучше об этом напомнить.


    Способ 2:

    Определение

    последней заполненной строки

    через SpecialCells

        lLastRow = Cells.SpecialCells(xlLastCell).Row

    Определение последнего столбца через SpecialCells

        lLastCol = Cells.SpecialCells(xlLastCell).Column

    Данный метод не требует указания номера столбца и возвращает последнюю ячейку(Row — строку, Column — столбец).
    Если хотите получить номер первой пустой строки или столбца на листе — к результату необходимо прибавить 1.
    Нюансы:

    • Используя данный способ следует помнить, что не всегда можно получить реальную последнюю заполненную ячейку, т.е. именно ячейку со значением. Метод SpecialCells определяет самую «дальнюю» ячейку на листе, используя при этом механизм «запоминания» тех ячеек, в которых мы работали в данном листе. Т.е. если мы занесем в ячейку AZ90345 значение и сразу удалим его — lLastRow, полученная через SpecialCells будет равна значению именно этой ячейки, из которой вы только что удалили значения(т.е. 90345). Другими словами требует обязательного обновления данных, а этого можно добиться только сохранив файла, а временами даже только закрыв файл и открыв его снова. Так же, если какая-либо ячейка содержит форматирование(например, заливку), но не содержит никаких значений, то метод SpecialCells посчитает её используемой и будет учитывать как заполненную.
      Этот недостаток можно попробовать обойти, вызвав перед определением последней ячейки вот такую строку кода:

      With ActiveSheet.UsedRange: End With

      Это должно переопределить границы рабочего диапазона и тогда определение последней строки/столбца сработает как ожидается, даже если до этого в ячейке содержались данные, которые впоследствии были удалены.
      Выглядеть в единой процедуре это будет так:

      Sub GetLastCell()
          Dim lLastRow As Long
          'переопределяем рабочий диапазон листа
          With ActiveSheet.UsedRange: End With
          'ищем последнюю заполненную ячейку на листе
          lLastRow = Cells.SpecialCells(xlLastCell).Row
      End Sub
    • даже если в ячейке нет видимого значения, но есть формула — SpecialCells посчитает ячейку не пустой
    • Данный метод определения последней ячейки не будет работать на защищенном листе(Рецензирование(Review)Защитить лист(Protect Sheet)).
    • Данный метод не будет работать при использовании внутри UDF. Точнее будет работать не так, как ожидается. Подробнее про некоторые «баги» работы встроенных методов внутри UDF(функций пользователя) я описывал в этой статье: Глюк работы в UDF методов SpecialCells и FindNext

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


    Способ 3:
    Определение последней строки через UsedRange

        lLastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count - 1

    Определение последнего столбца через UsedRange

        lLastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count - 1

    НЕМНОГО ПОЯСНЕНИЙ:

    • ActiveSheet.UsedRange.Row — этой строкой мы определяем первую ячейку, с которой начинаются данные на листе. Важно понимать для чего это — если у вас первые строк 5 не заполнены ничем(т.е. самые первые данные заносились начиная с 6-ой строки листа), то ActiveSheet.UsedRange.Row вернет именно 6(т.е. номер первой строки с данными). Если же все строки заполнены — то вернет 1.
    • ActiveSheet.UsedRange.Rows.Count — определяем кол-во строк, входящих в весь диапазон данных на листе. При этом неважно, есть ли данные в ячейках или нет — достаточно было поработать в этих ячейках и удалить значения или просто изменить цвет заливки.
      В итоге получается: первая строка данных + кол-во строк с данными — 1. Зачем вычитать единицу? Попробуем посчитать вместе: первая строка: 6. Всего строк: 3. 6 + 3 = 9. Вроде все верно. А теперь выделим на листе три ячейки, начиная с 6-ой. Выделение завершилось на 8-ой строке. Потому что в 6-ой строке уже есть данные. Поэтому и надо вычесть 1, чтобы учесть этот момент. Думаю, не надо пояснять, что если надо получить первую пустую ячейку — можно 1 не вычитать :)
    • То же самое и с ActiveSheet.UsedRange.Column, только уже не для строк, а для столбцов.

    Нюансы:

    • Обладает некоторыми недостатками предыдущего метода. Определяет самую «дальнюю» ячейку на листе, используя при этом механизм «запоминания» тех ячеек, в которых мы работали в данном листе. Следовательно попробовать обойти этот момент можно точно так же: перед определением последней строки/столбца записать строку: With ActiveSheet.UsedRange: End With
      Это должно переопределить границы рабочего диапазона и тогда определение последней строки/столбца сработает как ожидается, даже если до этого в ячейке содержались данные, которые впоследствии были удалены.
    • даже если в ячейке нет видимого значения, но есть формула — UsedRange посчитает ячейку не пустой

    Однако метод через UsedRange.Row работает прекрасно и при установленной на лист защите и внутри UDF, что делает его более предпочтительным, чем метод через SpecialCells при равных условиях.


    Способ 4:
    Определение последней строки и столбца, а так же адрес ячейки методом Find

    Sub GetLastCell_Find()
        Dim rF As Range
        Dim lLastRow As Long, lLastCol As Long
        'ищем последнюю ячейку на листе, в которой хранится хоть какое-то значение
        Set rF = ActiveSheet.UsedRange.Find(What:="*", LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlPrevious, MatchCase:=False, MatchByte:=False)
        If Not rF Is Nothing Then
            lLastRow = rF.Row    'последняя заполненная строка
            lLastCol = rF.Column 'последний заполненный столбец
            MsgBox rF.Address 'показываем сообщение с адресом последней ячейки
        Else
            'если ничего не нашлось - значит лист пустой
            'и можно назначить в качестве последних первую строку и столбец
            lLastRow = 1
            lLastCol = 1
            MsgBox "A1" 'показываем сообщение с адресом ячейки А1
        End If
    End Sub

    Этот метод, пожалуй, самый оптимальный в случае, если надо определить последнюю строку/столбец на листе без учета форматов и формул — только по отображаемому значению в ячейке. Например, если на листе большая таблица и последние строки заполнены формулами, возвращающими при определенных условиях пустую ячейку(=ЕСЛИ(A1>0;1;»»)), предыдущие варианты вернут строку/столбец ячейки с последней ячейкой, в которой формула. В то время как данный метод вернет адрес ячейки только в случае, если в ячейке реально отображается какое-то значение. Такой подход часто используется для того, чтобы определить границы данных для последующего анализа заполненных данных, чтобы не захватывать пустые ячейки с формулами и не тратить время на их проверку.
    Здесь следует обратить внимание на параметры метода Find. В данном случае мы специально указываем искать по значениям, а не по формулам:
    Set rF = ActiveSheet.UsedRange.Find(What:=»*», LookIn:=xlValues, LookAt:=xlWhole, SearchDirection:=xlPrevious, MatchCase:=False, MatchByte:=False)
    Нюансы:

    • Метод Find, вызванный с листа или другим кодом, имеет свойство запоминать все параметры последнего поиска, а если поиск еще не вызывался — то применяются параметры по умолчанию. А по умолчанию поиск идет всегда по формулам. Поэтому я настоятельно рекомендую указывать принудительно все необходимые параметры, как в примере.
    • Метод Find не будет учитывать в просмотре скрытые строки и столбцы. Это следует учитывать при его применении.

    Пара небольших практических кодов

    Коды ниже могут помочь понять, как использовать приведенные выше строки кода по поиску последней ячейки/строки:

    Sub GetLastCell()
        Dim lLastRow As Long
        Dim lLastCol As Long
        'определили последнюю заполненную ячейку с учетом формул в столбце А
        lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
        MsgBox "Заполненные ячейки в столбце А: " & Range("A1:A" & lLastRow).Address
        'определили последний заполненный столбец на листе(с учетом формул и форматирования)
        lLastCol = Cells.SpecialCells(xlLastCell).Column
        MsgBox "Заполненные ячейки в первой строке: " & Range(Cells(1, 1), Cells(1, lLastCol)).Address
        'выводим сообщение с адресом последней ячейки на листе(с учетом формул и форматирования)
        MsgBox "Адрес последней ячейки диапазона на листе: " & Cells.SpecialCells(xlLastCell).Address
    End Sub

    Выделяем диапазон ячеек в столбцах с А по С, определяя последнюю ячейку по столбцу A этого же листа:

    Sub SelectToLastCell()
        Range("A1:C" & Cells(Rows.Count, 1).End(xlUp).Row).Select
    End Sub

    Копируем ячейку B1 в первую пустую ячейку столбца A этого же листа:

    Sub CopyToFstEmptyCell()
        Dim lLastRow As Long
        lLastRow = Cells(Rows.Count, 1).End(xlUp).Row 'определили последнюю заполненную ячейку
        Range("B1").Copy Cells(lLastRow+1, 1)         'скопировали В1 и вставили в следующую после определенной ячейки
    End Sub

    А код ниже делает тоже самое, но одной строкой — применяется Offset и используется тот факт, что изначально методом End мы получаем именно ячейку, а не номер строки(номер строки мы получаем позже через свойство .Row):

    Sub CopyToFstEmptyCell()
        Range("B1").Copy Destination:=Cells(Rows.Count, 1).End(xlUp).Offset(1)
    End Sub

    Range(«B1»).Copy — копирует ячейку В1. Если для аргумента Destination указать другую ячейку, то в неё будет вставлена скопированная ячейка. Мы передаем в этот аргумент определенную методом End ячейку
    Cells(Rows.Count, 1).End(xlUp) — возвращает последнюю заполненную ячейку в столбце А (не строку, а именно ячейку)
    Offset(1) — смещает полученную ячейку на строку вниз
    Используем инструмент автозаполнение(протягивание) столбца В, начиная с ячейки B2 и определяя последнюю ячейку для заполнения на основании столбца А

    Sub AutoFill_B()
        Dim lLastRow As Long
        lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
        Range("B2").AutoFill Destination:=Range("B2:B" & lLastRow)
    End Sub

    На самом деле практических кодов может быть куда больше, т.к. определение последней заполненной или первой пустой ячейки является чуть ли не самой распространенной задачей при написании кодов в Excel.

    Так же см.:
    Как получить последнюю заполненную ячейку формулой?
    Как определить первую заполненную ячейку на листе?
    Что такое переменная и как правильно её объявить?


    Статья помогла? Поделись ссылкой с друзьями!

      Плейлист   Видеоуроки


    Поиск по меткам

    

    Access
    apple watch
    Multex
    Power Query и Power BI
    VBA управление кодами
    Бесплатные надстройки
    Дата и время
    Записки
    ИП
    Надстройки
    Печать
    Политика Конфиденциальности
    Почта
    Программы
    Работа с приложениями
    Разработка приложений
    Росстат
    Тренинги и вебинары
    Финансовые
    Форматирование
    Функции Excel
    акции MulTEx
    ссылки
    статистика

    Как определить последнюю ячейку на листе через VBA?

    Очень часто при внесении данных на лист Excel возникает вопрос определения последней заполненной или первой пустой ячейки. Чтобы впоследствии с этой первой пустой ячейки начать заносить данные. В этой теме я опишу несколько способов определения последней заполненной ячейки.

    В качестве переменной, которой мы будем присваивать номер последней заполненной строки, у нас во всех примерах будет lLastRow. Объявлять мы её будем как Long. Для экономии памяти можно было бы использовать и тип Integer, но т.к. строк на листе может быть больше 32767(это максимальное допустимое значение переменных типа Integer) нам понадобиться именно Long, во избежание ошибки. Подробнее про типы переменных можно прочитать в статье Что такое переменная и как правильно её объявить

    Одинаковые переменные для всех примеров

    Dim lLastRow As Long ‘а для lLastCol можно применить тип Integer, ‘т.к. столбцов в Excel пока меньше 32767 Dim lLastCol As Long

    1

    2

    3

    4

        Dim lLastRow As Long

        ‘а для lLastCol можно применить тип Integer,

        ‘т.к. столбцов в Excel пока меньше 32767

        Dim lLastCol As Long


    Способ 1:
    Определение последней заполненной строки через свойство End

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

    1

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

    определяя таким способом нам надо знать что:
    1 — это номер столбца, последнюю заполненную ячейку в котором мы определяем. В данном случае это столбце №1 или А.
    Это самый распространенный метод определения последней строки. Используя его мы можем определить последнюю ячейку только в одном конкретном столбце. Но в большинстве случаев этого достаточно.

    Правда, следует знать одну вещь: если у вас заполнены все строки в просматриваемом столбце(или будет заполнена самая последняя ячейка столбца) — то результат будет неверный(ну или не совсем такой, какой ожидали увидеть вы)
    Определение последнего столбца через свойство End

    lLastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    1

        lLastCol = Cells(1, Columns.Count).End(xlToLeft).Column

    1 — это номер строки, последнюю заполненную ячейку в которой мы определяем.

    Данный метод лишен недостатков, присущих второму и третьему способам. Однако есть другой, в определенных ситуациях даже полезный: при таком методе определения игнорируются строки, скрытые фильтром, группировкой или командой Скрыть (Hide). Т.е. если последняя строка таблицы будет скрыта, то данный метод вернет номер последней видимой заполненной строки, а не последней реально заполненной.


    Способ 2:
    Определение последней заполненной строки через SpecialCells

    lLastRow = Cells.SpecialCells(xlLastCell).Row

    1

        lLastRow = Cells.SpecialCells(xlLastCell).Row

    Определение последнего столбца через SpecialCells

    lLastCol = Cells.SpecialCells(xlLastCell).Column

    1

        lLastCol = Cells.SpecialCells(xlLastCell).Column

    Данный метод не требует указания номера столбца и возвращает максимальную последнюю ячейку(строку — Row либо столбец — Column). Но используя данный метод следует помнить, что не всегда можно получить реальную последнюю заполненную ячейку, т.е. именно ячейку со значением. Если вы где-то ниже занесете данные и сразу удалите их из таблицы, а затем примените такой метод, то lLastRow будет равна значению строки, из которой вы только что удалили значения. Другими словами требует обязательного обновления данных, а этого можно добиться только сохранив и закрыв документ и открыв его снова. Так же, если какая-либо ячейка содержит форматирование(например, заливку), но не содержит никаких значений, то она тоже будет считаться заполненной.
    Плюс данный метод определения последней ячейки не будет работать на защищенном листе(Рецензирование -Защитить лист).

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


    Способ 3:
    Определение последней строки через UsedRange

    lLastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count — 1

    1

        lLastRow = ActiveSheet.UsedRange.Row + ActiveSheet.UsedRange.Rows.Count — 1

    Определение последнего столбца через UsedRange

    lLastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count — 1

    1

        lLastCol = ActiveSheet.UsedRange.Column + ActiveSheet.UsedRange.Columns.Count — 1

    НЕМНОГО ПОЯСНЕНИЙ:

    • ActiveSheet.UsedRange.Row — этой строкой мы определяем первую ячейку, с которой начинаются данные на листе. Важно понимать для чего это — если у вас первые строк 5 не заполнены ничем, то данная строка вернет 6(т.е. номер первой строки с данными). Если же все строки заполнены — то вернет 1.
    • ActiveSheet.UsedRange.Rows.Count — определяем кол-во строк, входящих в весь диапазон данных на листе.
      Т.е. получается: первая строка данных + кол-во строк с данными — 1. Зачем вычитать единицу? Попробуем посчитать вместе: первая строка: 3. Всего строк: 3. 3 + 3 = 6. Вроде все верно, чего тут непонятного? А теперь выделите на листе три ячейки, начиная с 3-ей. Все верно. Ведь у нас в 3-ей строке уже есть данные. Думаю, остальное уже понятно и без моих пояснений.
    • То же самое и с ActiveSheet.UsedRange.Column, только уже не для строк, а для столбцов.

    Обладает всеми недостатками предыдущего метода.. Однако, можно перед определением последней строки/столбца записать строку: With ActiveSheet.UsedRange: End With
    Это должно переопределить границы рабочего диапазона и тогда определение последней строки/столбца сработает как ожидается, даже если до этого в ячейке содержались данные, которые впоследствии были удалены.

    Если хотите получить первую пустую ячейку на листе придется вспомнить математику. Т.к. последнюю заполненную мы определили, то первая пустая — следующая за ней. Т.е. к результату необходимо прибавить 1.


    Способ 4:
    Определение последней строки и столбца, а так же адрес ячейки методом Find

    Dim rF As Range Dim lLastRow As Long, lLastCol As Long ‘ищем последнюю ячейку на листе, в которой хранится хоть какое-то значение Set rF = ActiveSheet.UsedRange.Find(«*», , xlValues, xlWhole, xlPrevious) If Not rF Is Nothing Then lLastRow = rF.Row ‘последняя заполненная строка lLastCol = rF.Column ‘последний заполненный столбец MsgBox rF.Address ‘показываем сообщение с адресом последней ячейки Else ‘если ничего не нашлось — значит лист пустой ‘и можно назначить в качестве последних первую строку и столбец lLastRow = 1 lLastCol = 1 End If

    Dim rF As Range

        Dim lLastRow As Long, lLastCol As Long

        ‘ищем последнюю ячейку на листе, в которой хранится хоть какое-то значение

        Set rF = ActiveSheet.UsedRange.Find(«*», , xlValues, xlWhole, xlPrevious)

        If Not rF Is Nothing Then

            lLastRow = rF.Row    ‘последняя заполненная строка

            lLastCol = rF.Column ‘последний заполненный столбец

            MsgBox rF.Address ‘показываем сообщение с адресом последней ячейки

        Else

            ‘если ничего не нашлось — значит лист пустой

            ‘и можно назначить в качестве последних первую строку и столбец

            lLastRow = 1

            lLastCol = 1

        End If

    Этот метод, пожалуй, самый оптимальный в случае, если надо определить последнюю строку/столбец на листе без учета форматов и формул — только по отображаемому значению в ячейке. Например, если на листе большая таблица и последние строки заполнены формулами, возвращающими пустую ячейку(=»»), предыдущие варианты вернут строку/столбец ячейки с последней формулой, в то время как данный метод вернет адрес ячейки только в случае, если в ячейке реально отображается какое-то значение. Такой подход часто используется для того, чтобы определить границы данных для последующего анализа заполненных данных, чтобы не захватывать пустые ячейки и не тратить время на их проверку.

    Однако данный метод не будет учитывать в просмотре скрытые строки и столбцы. Это следует учитывать при его применении.


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

    Sub Get_Last_Cell() Dim lLastRow As Long Dim lLastCol As Long lLastRow = Cells(Rows.Count, 1).End(xlUp).Row MsgBox «Заполненные ячейки в столбце А: » & Range(«A1:A» & lLastRow).Address lLastCol = Cells.SpecialCells(xlLastCell).Column MsgBox «Заполненные ячейки в первой строке: » & Range(Cells(1, 1), Cells(1, lLastCol)).Address MsgBox «Адрес последней ячейки диапазона на листе: » & Cells.SpecialCells(xlLastCell).Address End Sub

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    Sub Get_Last_Cell()

        Dim lLastRow As Long

        Dim lLastCol As Long

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

        MsgBox «Заполненные ячейки в столбце А: » & Range(«A1:A» & lLastRow).Address

        lLastCol = Cells.SpecialCells(xlLastCell).Column

        MsgBox «Заполненные ячейки в первой строке: » & Range(Cells(1, 1), Cells(1, lLastCol)).Address

        MsgBox «Адрес последней ячейки диапазона на листе: » & Cells.SpecialCells(xlLastCell).Address

    End Sub

    А такой код выделит диапазон ячеек в столбцах с А по С, определяя последнюю ячейку по столбцу A этого же листа:

    Sub Copy_To_Last_Cell() Range(«A1:C» & Cells(Rows.Count, 1).End(xlUp).Row).Select End Sub

    1

    2

    3

    Sub Copy_To_Last_Cell()

        Range(«A1:C» & Cells(Rows.Count, 1).End(xlUp).Row).Select

    End Sub

    А вот такой код скопирует ячейку B1 в первую пустую ячейку столбца A этого же листа:

    Sub Copy_To_Last_Cell() Range(«B1»).Copy Cells(Rows.Count, 1).End(xlUp).Offset(1) End Sub

    1

    2

    3

    Sub Copy_To_Last_Cell()

        Range(«B1»).Copy Cells(Rows.Count, 1).End(xlUp).Offset(1)

    End Sub

    Важно знать: необходимо помнить, что если ячейка содержит формулу, пусть и возвращающую значение «», Excel не считает её пустой(к слову совершенно справедливо) и включает в просмотр при поиске последней ячейки.

    NOTE: I intend to make this a «one stop post» where you can use the Correct way to find the last row. This will also cover the best practices to follow when finding the last row. And hence I will keep on updating it whenever I come across a new scenario/information.


    Unreliable ways of finding the last row

    Some of the most common ways of finding last row which are highly unreliable and hence should never be used.

    1. UsedRange
    2. xlDown
    3. CountA

    UsedRange should NEVER be used to find the last cell which has data. It is highly unreliable. Try this experiment.

    Type something in cell A5. Now when you calculate the last row with any of the methods given below, it will give you 5. Now color the cell A10 red. If you now use the any of the below code, you will still get 5. If you use Usedrange.Rows.Count what do you get? It won’t be 5.

    Here is a scenario to show how UsedRange works.

    enter image description here

    xlDown is equally unreliable.

    Consider this code

    lastrow = Range("A1").End(xlDown).Row
    

    What would happen if there was only one cell (A1) which had data? You will end up reaching the last row in the worksheet! It’s like selecting cell A1 and then pressing End key and then pressing Down Arrow key. This will also give you unreliable results if there are blank cells in a range.

    CountA is also unreliable because it will give you incorrect result if there are blank cells in between.

    And hence one should avoid the use of UsedRange, xlDown and CountA to find the last cell.


    Find Last Row in a Column

    To find the last Row in Col E use this

    With Sheets("Sheet1")
        LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
    End With
    

    If you notice that we have a . before Rows.Count. We often chose to ignore that. See THIS question on the possible error that you may get. I always advise using . before Rows.Count and Columns.Count. That question is a classic scenario where the code will fail because the Rows.Count returns 65536 for Excel 2003 and earlier and 1048576 for Excel 2007 and later. Similarly Columns.Count returns 256 and 16384, respectively.

    The above fact that Excel 2007+ has 1048576 rows also emphasizes on the fact that we should always declare the variable which will hold the row value as Long instead of Integer else you will get an Overflow error.

    Note that this approach will skip any hidden rows. Looking back at my screenshot above for column A, if row 8 were hidden, this approach would return 5 instead of 8.


    Find Last Row in a Sheet

    To find the Effective last row in the sheet, use this. Notice the use of Application.WorksheetFunction.CountA(.Cells). This is required because if there are no cells with data in the worksheet then .Find will give you Run Time Error 91: Object Variable or With block variable not set

    With Sheets("Sheet1")
        If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
            lastrow = .Cells.Find(What:="*", _
                          After:=.Range("A1"), _
                          Lookat:=xlPart, _
                          LookIn:=xlFormulas, _
                          SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious, _
                          MatchCase:=False).Row
        Else
            lastrow = 1
        End If
    End With
    

    Find Last Row in a Table (ListObject)

    The same principles apply, for example to get the last row in the third column of a table:

    Sub FindLastRowInExcelTableColAandB()
    Dim lastRow As Long
    Dim ws As Worksheet, tbl as ListObject
    Set ws = Sheets("Sheet1")  'Modify as needed
    'Assuming the name of the table is "Table1", modify as needed
    Set tbl = ws.ListObjects("Table1")
    
    With tbl.ListColumns(3).Range
        lastrow = .Find(What:="*", _
                    After:=.Cells(1), _
                    Lookat:=xlPart, _
                    LookIn:=xlFormulas, _
                    SearchOrder:=xlByRows, _
                    SearchDirection:=xlPrevious, _
                    MatchCase:=False).Row
    End With
    
    End Sub
    

    We use  Range.SpecialCells() method in the below VBA Code to find and return details of last used row, column, and cell in a worksheet.

    Sample Data:

    Sample Data

    Syntax:

    expression.SpecialCells (Type, Value)

    Eg: To return the last used cell address in an activesheet. ActiveSheet.Range(“A1”).SpecialCells(xlCellTypeLastCell).Address

    VBA Code:

    Declaring Variables:

    Variable Data Type Comments
    LastRow Long Find and store last used row
    LastCol Long store last used column
    LastCell String store last used cell address
    'Variable Declaration
    
    Dim LastRow As Long, LastCol As Long, LastCell As String

    Use SpecialCells function to find last used row/column/cell 

    'Find Last Used Row
    LastRow = ActiveSheet.Range("A1").SpecialCells(xlCellTypeLastCell).Row
    
    'Find Last Used Column
    LastCol = ActiveSheet.Range("A1").SpecialCells(xlCellTypeLastCell).Column
    
    'Find Last Used Cell
    LastCell = ActiveSheet.Range("A1").SpecialCells(xlCellTypeLastCell).Address

    Concatenate all three variables (LastRow/LastCol/LastCell), add a new line between variables use Chr(10).   Show the final output in an Excel Message box.

    'Display the last used row/column/cell
    
    MsgBox "Last Used Row : " & LastRow & Chr(10) & "Last Used Column : " & LastCol & Chr(10) & "Last Used Cell : " & LastCell

    Implementation:

    Follow the below steps to find the Last Used Row and Last Used Column in Excel VBA

    Step 1: Add a shape (Find Last Row/Column/Cell) on your worksheet.  

    Step 2: Right-click on “Find Last Row/Column/Cell” and “Assign Macro..”

    Step 3: Select “findLastUsedCell”, you can see a list of macros if available in your workbook

    Step 4: Save your excel file as “Excel Macro-Enabled Workbook” *.xlsm

    Step 5: Click “Find Last Row/Column/Cell” to execute the VBA code.  Code will popup below output for the above given example (Output).

    Output:

     

    Столкнулся с проблемой, не могу понять как правильно сделать подсчет строки. Что бы например с одного файла вытягивало конкретный диапазон до пустого поля. И подставляло в таблицу по порядку( без пропуска и перезаписи)

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

    В принципе в файле на листе пример как должно быть  и макрос  

     

    Jack Famous

    Пользователь

    Сообщений: 10852
    Регистрация: 07.11.2014

    OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

    #2

    13.12.2019 19:11:45

    aosunproject, попробуйте слепить что-то по аналогии…

    Ваш макрос (это больше для помогающих, чтобы не качать файл)

    Мой код

    P.S.:

    мой код взят

    отсюда

    Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

     

    Jack Famous

    Пользователь

    Сообщений: 10852
    Регистрация: 07.11.2014

    OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

    Изменено: Jack Famous16.12.2019 16:15:28

    Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

     

    Ну извините, сам толком не могу понять суть проблемы где не идет. Вот и не знаю как правильно назвать тему)

     

    Трабл в том что именно надо это сделать с множества файлов. Но вот не задача, хз как реализовать считывание с ячейки и перенос на лист где макрос. И при эти данные добавлять в столбец, не удаляя прежние. Уже ломал голову и пробовал по разному. Результат вот что вышло, но с одним файлом увы. Следующий файл перезаписывает прежнее данные. А надо что бы именно добавило данные после первого файла. Как то так)

     

    vikttur

    Пользователь

    Сообщений: 47199
    Регистрация: 15.09.2012

    #6

    13.12.2019 23:30:31

    Цитата
    aosunproject написал: сам толком не могу понять суть проблемы

    Это Ваша задача и если Вы ее не понимаете, то кто поймет и сделает то, что Вы не можете сформулировать?!

    Цитата
    aosunproject написал: Что бы например с одного файла вытягивало конкретный диапазон до пустого поля.

    Значит ли это, что нужно определить последнюю строку диапазона? Это главная проблема?

     

    ocet p

    Пользователь

    Сообщений: 438
    Регистрация: 24.03.2018

    #7

    14.12.2019 04:30:58

    Цитата
    aosunproject написал:
    Следующий файл перезаписывает прежнее данные

    Например:

    Код
    Sub record_1()
        '...
        With ThisWorkbook.Sheets(1)
            SrcWbkSht.Range("C7", SrcWbkSht.Range("C7").End(xlDown)).Copy _
                Destination:=.Range("F" & .Rows.Count).End(xlUp).Offset(1, 0)
                    Application.CutCopyMode = False
            '...
        End With
        '...
    End Sub
    
     

    а почему бы не применять простое правило: у темы нет названия — тему в топку
    может люди когда-нибудь начнут писать в названии темы не о проблемах, с которыми столкнулись используя определенную функцию для решения задачи,  а  будут писать о задаче, которую не могут решить

    Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

     

    vikttur

    Пользователь

    Сообщений: 47199
    Регистрация: 15.09.2012

    Так мы пол-форума вычистим )

     

    БМВ

    Модератор

    Сообщений: 21385
    Регистрация: 28.12.2016

    Excel 2013, 2016

    #10

    14.12.2019 12:49:57

    off

    Цитата
    vikttur написал:
    Так мы пол-форума вычистим )

    Я тут прикинул, это 35 дней по 8 часов непрерывной работы, без рыбы и детского питания .  :D

    По вопросам из тем форума, личку не читаю.

     

    vikttur

    Пользователь

    Сообщений: 47199
    Регистрация: 15.09.2012

    Вот-вот. Пожалейте кота. Он же без детского питания загнется :)

     

    Юрий М

    Модератор

    Сообщений: 60587
    Регистрация: 14.09.2012

    Контакты см. в профиле

    #12

    14.12.2019 22:01:46

    Цитата
    БМВ написал:
    без рыбы

    Стоп! Это как без рыбы?!!

     

    Igor67

    Пользователь

    Сообщений: 3729
    Регистрация: 21.12.2012

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #14

    16.12.2019 15:51:19

    Цитата
    vikttur написал:
    Значит ли это, что нужно определить последнюю строку диапазона? Это главная проблема

    Да.  

    Изменено: aosunproject16.12.2019 15:52:04

     

    Нужно что бы данные добавили следующие строки после первых. То есть как на рисунке, там где помечено должно добавить следующие данные. И так столько нужно будет. В идеале нужно было реализовать что бы с выбранных файлов вытягивало например столбец «С» и до последней включно заполненной ячейки(кроме пустых).
    И скопировать это туда где мне надо и вставить(проверяя где последняя заполненная ячейка и вставлять после). Аналогично сделать с полем «В» и «А». При этом что бы данные были друг на против друга. Так как вытягиваются отдельные поля, а не вся книга.

    Прикрепленные файлы

    • 12212.jpg (146.49 КБ)

    Изменено: aosunproject16.12.2019 16:08:03

     

    Вот что у меня выходит. Хз как бороться с этим. Каждые данные с отступом идут. Ноль идей

     

    допустим на листе заполнены ячейки
    а1, в1, с1, д1, е1
    а2

    какая последняя ячейка заполнена на листе? знаете???

    Изменено: Ігор Гончаренко16.12.2019 16:43:21

    Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

     

    RAN

    Пользователь

    Сообщений: 7091
    Регистрация: 21.12.2012

    #18

    16.12.2019 17:35:07

    Как я понял, проблема в  использовании

    Код
    Range("A1").CurrentRegion.Rows.Count

    Если это вычислить 1 раз и записать в переменную, то все последующие вставки попадут в 1 строку, а если это пересчитывать после каждой вставки, то (3 попытки для угадать).

     

    ocet p

    Пользователь

    Сообщений: 438
    Регистрация: 24.03.2018

    #19

    17.12.2019 23:21:40

    Цитата
    aosunproject написал: Нужно что бы данные добавили следующие строки после первых

    Вы привели «много» примеров, за исключением того, как выглядят исходные данные, то есть те, которые должны быть скопированы.

    Цитата
    вытягивало например столбец «С» и до последней включно заполненной ячейки(кроме пустых).

    У вас есть «дыры» в данных ?

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #20

    18.12.2019 03:25:27

    Цитата
    RAN написал:
    Если это вычислить 1 раз и записать в переменную, то все последующие вставки попадут в 1 строку, а если это пересчитывать после каждой вставки, то (3 попытки для угадать).

    Я не для того пишу, что бы угадывать. Суть проблемы описал. Вот спрашиваю у знатоков пример решения. Или дать решение в целом. Пока никто выше не дал толком ответ.  

     

    Ігор Гончаренко

    Пользователь

    Сообщений: 13746
    Регистрация: 01.01.1970

    #21

    18.12.2019 04:34:12

    Цитата
    Ігор Гончаренко написал:
    допустим на листе заполнены ячейки
    а1, в1, с1, д1, е1
    а2
    какая последняя ячейка заполнена на листе?

    пока никто не дал толком ответ…

    Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #22

    18.12.2019 04:57:37

    В общем посидел чутка и начал в цикле загонять и понял в чем проблема. Так вот у меня есть счетчик от:

    Код
     DestWbk.Worksheets(1).Range("E1").CurrentRegion.Rows.Count 
    

    и получается так, что считает последнюю заполненную ячейку по всему листу. А не по конкретному полю. Итоге и не выходит. Мне нужно что бы счетчик каждый начинался отдельно. Вот и вся проблема)

    Изменено: aosunproject18.12.2019 04:58:51

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #23

    18.12.2019 05:17:12

    Цитата
    Ігор Гончаренко написал:
    пока никто не дал толком ответ…

    нужно последняя заполненная строка по определенной колонке например а1, строка 5 последняя. В поле б1 строка 7

    Изменено: aosunproject18.12.2019 05:17:29

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #24

    18.12.2019 05:34:42

    Цитата
    Ігор Гончаренко написал: пока никто не дал толком ответ…

    нужно последняя заполненная строка по определенной колонке например а1, строка 5 последняя. В поле б1 строка 7

    Итоги недели мучений вот решение:

    Код
     Set SrcWbk = Workbooks.Open(MasivWbs)
        For i = 0 To N
            N = DestWbk.Worksheets(1).Range("F1").End(xlDown).Row
        
        i = N + 1
        'MsgBox i
            SrcWbk.Worksheets(1).Range("C7", Range("C7").End(xlDown)).Copy _
                        Destination:=DestWbk.Worksheets(1).Cells(i, 6)
        Next i
        
         For k = 0 To L
            L = DestWbk.Worksheets(1).Range("E1").End(xlDown).Row
         'MsgBox L
        k = L + 1
       
       ' MsgBox i
           SrcWbk.Worksheets(1).Range("D7", Range("D7").End(xlDown)).Copy _
    Destination:=DestWbk.Worksheets(1).Cells(k, 5)
        Next k
    

    Тут момент с .End(xlDown).Row (Проверка последней ячейки). Может кому то надо будет. Теперь осталось разобраться как залить несколько файлов и что бы с них сразу свело в одну таблицу)

    Изменено: aosunproject18.12.2019 12:38:53

     

    Ігор Гончаренко

    Пользователь

    Сообщений: 13746
    Регистрация: 01.01.1970

    #25

    18.12.2019 05:50:43

    aosunproject,
    пока нет ответа на конкретную ситуацию:  если на листе заполнены ячейки
    а1, в1, с1, д1, е1
    а2
    какая последняя заполненная на этом листе ячейка?
    не возможно

    Цитата
    aosunproject написал:
    определить последнюю ячейку на листе через VBA?

    т.е. пока не понятно как вообще определяется последняя ячейка — не возможно определить последнюю ячейку с помощью VBA.
    просто хоть с VBA хоть без него не возможно определить последнюю ячейку, если не известно, как ее определять

    Изменено: Ігор Гончаренко18.12.2019 06:09:50

    Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

     

    Дмитрий(The_Prist) Щербаков

    Пользователь

    Сообщений: 14182
    Регистрация: 15.09.2012

    Профессиональная разработка приложений для MS Office

    #26

    18.12.2019 08:54:30

    Цитата
    aosunproject написал:
    Суть проблемы описал. Пока никто выше не дал толком ответ

    Вам ответ дали на проблему еще в сообщении

    #3

    от 13 Дек 2019 19:21:10. Там ссылки на статью, где разные методы определения последней ячейки расписаны, включая и упомянутый Вами .End(xlDown).Row с его достоинствами и недостатками.
    А вот Вы на задаваемые Вам вопросы отвечать не хотите. Отсюда и отсутствие решений конкретно под Вашу проблему.

    Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

     

    Jack Famous

    Пользователь

    Сообщений: 10852
    Регистрация: 07.11.2014

    OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

    #27

    18.12.2019 09:21:05

    Цитата
    Дмитрий(The_Prist) Щербаков: Вам ответ дали на проблему еще в сообщении  #3

    один-в-один по названию темы, кстати говоря  :D

    Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

     

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

    Изменено: Ігор Гончаренко18.12.2019 12:35:41

    Программисты — это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!

     

    Jack Famous

    Пользователь

    Сообщений: 10852
    Регистрация: 07.11.2014

    OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

    Ігор Гончаренко, это не проблема помогающих, поэтому мне вот не жаль))

    Изменено: Jack Famous18.12.2019 12:39:28

    Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

     

    aosunproject

    Пользователь

    Сообщений: 11
    Регистрация: 13.12.2019

    #30

    18.12.2019 12:51:22

    Я написал выше как мне надо в сообщении #23. Решение нашел, благодаря выводу в сообщении. Оттуда математика и результат. Чутка позже напишу полный код, может кому то поможет для подобных задач.

    Понравилась статья? Поделить с друзьями:
  • Последняя дата значения excel
  • Последняя ячейка в excel сочетание клавиш
  • Последняя дата если в excel
  • Последняя ячейка в excel как перейти
  • Последняя версия word 2021