Как посчитать количество строк в Excel с данными?

в столбце A есть такие данные (т.е. частые пустые ячейки):

HEADING  <-- this is A1
kfdsl
fdjgnm
fdkj

gdfkj
4353

fdjk  <-- this is A9

Я хотел бы получить ссылку на последнюю ячейку, в которой есть данные. Итак, в приведенном выше примере я хочу вернуть: A9

Я пробовал это, но он останавливается на первой пустой ячейке (т.е. возвращается A4)

numofrows = destsheet.Range("A2").End(xlDown).Row - 1

person pjj    schedule 10.06.2011    source источник
comment
comment
Dim lastRow As Long Dim ws As Worksheet Set ws = Application.ActiveSheet With ws If WorksheetFunction.CountA (Cells) ›0 Тогда lastRow = Cells.Find (what: = *, SearchOrder: = xlByRows, _ SearchDirection: = xlPrevious) .Row Конец, если Конец с   -  person Ronnie Royston    schedule 14.06.2015


Ответы (9)


Мне так нравится:

ActiveSheet.UsedRange.Rows.Count

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

person Tomamais    schedule 15.06.2011
comment
Если у вас нет данных в строке 1, это даст неправильный ответ - будет указано количество строк от первой до последней ячейки. Если у вас есть данные в ячейках a2: a4, результатом этого уравнения будет 3, а не 4 (при использовании Office 2010). - person Floris; 28.05.2013
comment
Этот метод может быть опасным, поскольку он может возвращать ячейку с цветом, но без данных, или даже ячейку, которая содержала данные, но не была очищена должным образом. - person lcrmorin; 11.07.2013
comment
Этот ответ неверен и должен быть удален. .UsedRange.Rows.Count возвращает количество строк в UsedRange, что не то же самое, что номер строки последней части данных. Итак, если ваши строки 1 и 2 пусты, это вернет неправильный ответ на 2. - person Jean-François Corbett; 16.09.2014
comment
Если вы хотите получить последнюю строку в используемом диапазоне, сделайте это правильно - см. ответ newguy. Прочтите ответ sancho.s, чтобы узнать, что это возвращает и нужна ли вам строка с данными (а не оставшееся форматирование) и / или в конкретном столбце см. мое решение. - person Nickolay; 23.04.2018

Самый безопасный вариант

Lastrow =  Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
Lastcol =  Cells.Find("*", [A1], , , xlByColumns, xlPrevious).Column

Не используйте UsedRange, SpecialCells(xlLastCell) или End(xlUp). Все эти методы могут дать неверные результаты, если вы ранее удалили некоторые строки. Excel по-прежнему считает эти невидимые ячейки.

Эти методы снова будут работать, если вы удалите свои ячейки, сохраните книгу, закроете и снова откроете ее.

person nixda    schedule 18.01.2013
comment
+1 провел небольшое тестирование, и это кажется наиболее надежным, особенно если вы не знаете, в каком столбце находятся данные в последней строке. - person Graham Anderson; 27.09.2013
comment
Это единственный безопасный способ найти последнюю ячейку, содержащую данные. Другие методы не работают со скрытыми строками / столбцами или ячейками без данных, кроме форматирования или ячеек, которые были удалены. - person Charles Williams; 21.10.2013
comment
Однако следует использовать Set в диапазоне и проверить, существует ли этот диапазон. Это предполагает, что данные присутствуют на листе - это не удастся на пустом листе. - person brettdj; 19.12.2013
comment
Итак, если я правильно понимаю, я мог бы использовать переменную lastrow для установки первой строки, чтобы начать вставку новых данных Lastrow = Cells.Find (*, [A1],,, xlByRows, xlPrevious) .Row Например; rnum = Lastrow +1 (Это будет первая пустая ячейка на листе (?)) - person haakonlu; 07.04.2015

Это будет работать независимо от версии Excel (2003, 2007, 2010). В первом листе 65536 строк, а в двух последних - около миллиона строк. Sheet1.Rows.Count возвращает это число в зависимости от версии.

numofrows = Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp).Row

или эквивалент, но короче

numofrows = Sheet1.Cells(Sheet1.Rows.Count,1).End(xlUp)

Это ищет снизу столбца A первую непустую ячейку и получает номер ее строки.

Это также работает, если у вас есть данные, которые идут дальше вниз в других столбцах. Так, например, если вы возьмете данные своего примера и также напишете что-то в ячейке FY4763, приведенное выше все равно вернет 9 (а не 4763, который любой метод, использующий свойство UsedRange, вернет неправильно).

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

Set rngLastCell = Sheet1.Range("A1").Offset(Sheet1.Rows.Count - 1, 0).End(xlUp)

Обратите внимание, что этот метод не работает в некоторых крайних случаях:

  • Последняя строка содержит данные
  • Последняя строка (строки) скрыта или отфильтрована

Так что будьте осторожны, если вы планируете использовать для этих целей строку 1 048 576!

person Jean-François Corbett    schedule 10.06.2011
comment
Это сработало для меня там, где ActiveSheet.UsedRange.Rows.Count не удалось (что я обычно использую). - person thornomad; 13.11.2012
comment
У вас отсутствует .Row в замечательном ответе выше. Новых пользователей может смутить отсутствующее утверждение. numofrows = Sheet1.Cells(Sheet1.Rows.Count,1).End(xlUp) , как набрано, предоставит значение последней использованной ячейки. Sheet1.Cells(Sheet1.Rows.Count, 1).End(xlUp).Row с .Row в конце предоставит номер строки последней ячейки в столбце 1, как и предполагалось. - person equalizer; 10.12.2015

Я сравнил все возможности с длинным тестовым листом:

0,140625 сек для

lastrow = calcws.Cells.Find("*", [A1], , , xlByColumns, xlPrevious).row

0 секунд для

iLastRow = calcws.Cells(rows.count, "a").End(xlUp).row

и

numofrows = calcws.Cells.SpecialCells(xlLastCell).row

0,0078125 сек для

lastrow = calcws.UsedRange.rows.count
Do While 1
    If calcws.Cells(lastrow, 1).Value = "" Then
        lastrow = lastrow - 1
    Else
        Exit Do
    End If
Loop

Думаю, фавориты очевидны ...

person sven    schedule 24.02.2013
comment
+1 - это мой любимый ответ. Не принимать чью-то сторону, а просто показывать некоторые варианты и их относительную эффективность. Должно быть гораздо больше голосов! - person Floris; 05.07.2013
comment
@Floris: Считаете ли вы, что скорость - самый важный критерий, по которому можно судить, какой из вариантов следует отдать предпочтение? Вместо того, что работает надежно? (Потому что не все они возвращают одинаковые результаты при любых обстоятельствах ...) - person Jean-François Corbett; 19.12.2013
comment
@jeanfrancoiscorbett - очевидно, что правильный ответ важнее всего. Я комментировал беспристрастность этого ответа - объективное сравнение скоростей. Мне это понравилось, и я попытался сказать это в своем ответе. Я вижу много причин, по которым что-то может пойти не так (например, когда в последней строке есть значение ...) - person Floris; 19.12.2013
comment
-1 Я не вижу компиляции других кодов как раз как ответ, особенно тот, который подразумевает, что время (для неуказанного теста) более важно, чем фактическая надежность ответа. Наконец, numofrows = calcws.Cells.SpecialCells(xlLastCell).row применяется к листу, а не к столбцу A - person brettdj; 11.01.2014
comment
Действительно, сравнение производительности полезно, но тот факт, что все более быстрые методы при определенных обстоятельствах возвращают неверные результаты, - нет. В частности, 4-й фрагмент ошибочно предполагает, что calcws.UsedRange.rows.count является последней строкой, но если первые несколько строк листа пусты, это предположение не выполняется. - person Nickolay; 20.04.2018

Dim RowNumber As Integer
RowNumber = ActiveSheet.Range("A65536").End(xlUp).Row

В вашем случае он должен вернуть # 9

person Lubor    schedule 01.11.2012
comment
+1, а для Excel 2007 и новее используйте range("A" & activesheet.rows.count).end(xlup).row :) - person Our Man in Bananas; 13.04.2013

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

iLastRow = Cells(Rows.Count, "a").End(xlUp).Row
iLastCol = Cells(i, Columns.Count).End(xlToLeft).Column

Спасибо мудракеру из Мелборна, Австралия

person MonroeGA    schedule 04.01.2013

Они оба будут работать, позволяя Excel определять, когда в последний раз он видит данные.

numofrows = destsheet.UsedRange.SpecialCells(xlLastCell).row

numofrows = destsheet.Cells.SpecialCells(xlLastCell).row
person Hari Seldon    schedule 10.06.2011
comment
Это неверно на нескольких уровнях. Ваше первое предложение, .UsedRange.Rows.count, вернет количество строк в UsedRange, что не то же самое, что номер строки последней части данных. Таким образом, если ваши строки 1 и 2 пусты, это вернет неправильный ответ на 2. Кроме того, сюда входит последняя непустая ячейка на всем листе, а не только в рассматриваемом столбце. Может быть, это то, чего хочет ОП, но я так не думаю; плюс, он действительно подвержен ошибкам, если кто-то случайно напишет что-то в ячейке FY54239. - person Jean-François Corbett; 10.06.2011
comment
Ваше второе предложение, destsheet.SpecialCells(xlLastCell).row даже не компилируется, по крайней мере, в Excel 2003: .SpecialCells не применяется к объекту Sheet. - person Jean-François Corbett; 10.06.2011
comment
@Jean ... На самом деле это destsheet.Cells.SpecialCells(xlLastCell).Row ... Мне определенно плохо, что я не включил это. В первую очередь, .SpecialCells(xlLastCell).Row можно применить и к UsedRange. Я отредактировал свой ответ рабочим кодом. - person Hari Seldon; 10.06.2011

Для большей наглядности хочу добавить наглядный пример и запустив

            openFileDialog1.FileName = "Select File"; 
            openFileDialog1.DefaultExt = ".xls"; 
            openFileDialog1.Filter = "Excel documents (.xls)|*.xls"; 


            DialogResult result = openFileDialog1.ShowDialog();


            if (result==DialogResult.OK)
            {

                string filename = openFileDialog1.FileName;


                Excel.Application xlApp;
                Excel.Workbook xlWorkBook;
                Excel.Worksheet xlWorkSheet;
                object misValue = System.Reflection.Missing.Value;

                xlApp = new Excel.Application();
                xlApp.Visible = false;
                xlApp.DisplayAlerts = false;



                xlWorkBook = xlApp.Workbooks.Open(filename, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

                var numRows = xlWorkSheet.Range["A1"].Offset[xlWorkSheet.Rows.Count - 1, 0].End[Excel.XlDirection.xlUp].Row;

                MessageBox.Show("Number of max row is : "+ numRows.ToString());

                xlWorkBook.Close(true, misValue, misValue);
                xlApp.Quit();

            }
person daniele3004    schedule 20.10.2014

Я предпочитаю использовать свойство CurrentRegion, которое эквивалентно Ctrl- *, которое расширяет текущий диапазон до самого большого непрерывного диапазона с данными. Вы начинаете с ячейки или диапазона, который, как вы знаете, будет содержать данные, а затем расширяете его. Свойство UsedRange иногда возвращает огромные области только потому, что кто-то выполнил форматирование внизу листа.

Dim Liste As Worksheet    
Set Liste = wb.Worksheets("B Leistungen (Liste)")     
Dim longlastrow As Long
longlastrow = Liste.Range(Liste.Cells(4, 1), Liste.Cells(6, 3)).CurrentRegion.Rows.Count
person Andrew Magerman    schedule 21.10.2013
comment
Это не сработает для исходного вопроса, потому что не все данные непрерывны. - person Charles Williams; 21.10.2013
comment
Чарльз, ты так прав. В показанном случае мой метод действительно потерпит неудачу. - person Andrew Magerman; 21.10.2013