Я заполнил B2: GQ244 формулами, скопировал диапазон и вставил по значению перед сортировкой столбца диапазона за столбцом. Все ячейки в B8:GQ244 были пустыми. Затем я хотел объединить непустые ячейки столбец за столбцом, начиная со строки 2. Для этого мне нужно было найти последнюю непустую ячейку в каждом столбце.
По какой-то причине и End(xlUp), и End(xlDown) дали строку 244, которая была пустой. Я не могу понять, почему. Я думал, что файл может быть поврежден. Итак, я безрезультатно скопировал два листа и модуль во вновь созданную книгу. Любое объяснение, почему и End(xlUp), и End(xlDown) дали строку 244?
.Range("B2:GQ244").Formula = "=IF(ISERROR(FIND( B$1,Sheet9!$H34)),"""",Sheet9!$I34)"
'paste by value to get rid of formulae
.Range("B2:GQ244").Copy
.Range("B2").PasteSpecial Paste:=xlPasteValues
'sort by column
Dim last_row As Long
Dim j As Long
For i = 2 To 200 Step 1
Range(.Cells(2, i), .Cells(245, i)).Sort key1:=.Cells(2, i), order1:=xlAscending
Next i
For i = 2 To 200 Step 1
last_row = .Cells(65536, i).End(xlUp).Row
last_row = .Cells(1, i).End(xlDown).Row
@Variatus да, но после вставки по значению все формулы исчезли.
Да, формулы заменяются созданными ими значениями. Я объяснил это в моем официальном ответе ниже.
Я не могу подтвердить ваши выводы. Имея пустой ActiveSheet и пустой Sheet9, приведенный ниже код заполнил ActiveSheet нулями B2:GQ244. Затем он считывает последнюю строку xlUp как 244 и xlDown как 2. Оба этих значения соответствуют ожидаемым. Возможно, у вас есть настройка, подавляющая отображение нулей. Однако, как объяснялось в моем комментарии выше, ячейка, которая выглядит пустой, не обязательно является пустой, и это также применимо к ячейке, содержащей NullString, вставленную вашей формулой, даже если формула была впоследствии удалена, оставив нулевую строку на своем месте.
Sub Examine()
Dim last_row As Long
Dim i As Long
With ActiveSheet
.Range("B2:GQ244").Formula = "=IF(ISERROR(FIND( B$1,Sheet9!$H34)),"""",Sheet9!$I34)"
'paste by value to get rid of formulae
.Range("B2:GQ244").Copy
.Range("B2").PasteSpecial Paste:=xlPasteValues
'sort by column
For i = 2 To 200 Step 1
Range(.Cells(2, i), .Cells(245, i)).Sort Key1:=.Cells(2, i), Order1:=xlAscending
last_row = .Cells(.Rows.Count, i).End(xlUp).Row
Debug.Print last_row ' returns 244
last_row = .Cells(1, i).End(xlDown).Row
Debug.Print last_row ' returns 2
Next i
End With
End Sub
Таким образом, остается единственная загадка, почему .Cells(1, i).End(xlDown).Row
дает вам значение 244. Это не так. Поэтому решение должно быть в проведении вашего теста, а не в его результате. Сравните свой метод тестирования с тем, который я использовал выше.
Странно, что код заполнил ячейки нулями. Разве ячейки не должны содержать нуль, учитывая, что формула вставляет "" (пустую строку)? Я проверил File/Options/Advanced и подтвердил, что должны отображаться нули. Я также ввел «=B243=0» в B246 и получил ЛОЖЬ, подтверждая, что пустые ячейки не содержат нуля. Интересно, что если бы я изменил формулу, чтобы заполнить vbNullString вместо «»», все ранее пустые ячейки теперь были нулями. Результат сортировки также отличается. При «»» после сортировки числа начинались со 2-й строки и вниз. С vbNullString числа были внизу.
Если B1 ничего не содержит, функция НАЙТИ будет успешной, и результат, импортированный из Sheet9, будет равен нулю, если указанная ячейка также пуста. Если B1 имеет содержимое, это значение может не быть найдено на Sheet9, что приведет к ошибке FIND, которую формула преобразует в «». Обратите внимание, что "" = NullString. Результат сортировки может отличаться в зависимости от того, сортируете ли вы формулы или значения.
Я только что запустил ваш код на своем листе и получил два числа — 244, 244. Это точно то же самое, что дал мой код.
Это потому, что в вашем тесте B1 не пуст. Имейте в виду, что xlDown просматривает заданную ячейку вниз, тогда как xlUp просматривает заданную ячейку вверх. Поэтому в случае xlDown результат должен быть таким же, как и для xlUp, если перед концом столбца нет пустых ячеек.
Спасибо за объяснение, но это восходит к моему первоначальному вопросу. Что такого особенного в строке 244? B3 вниз до конца столбца все пустые. На самом деле все столбцы со 2 по 199, начиная с строки 10 и ниже, пусты, а End(xlUp) и End(xlDown) дают 244.
B244 — последняя непустая (используемая) ячейка в столбце B. Пожалуйста, поймите, что Excel предназначен для отображения вещей в ячейках, которых там нет. В этом случае то, что отображается, является нулевой строкой, и вы пытаетесь утверждать, что ее не может быть, потому что она не существует и не видна. Это потому, что ваша собственная формула поместила это туда. Это не видно, потому что пустые строки невидимы. Код, который мы обсуждаем, доказывает оба факта.
Спасибо. Теперь это начинает обретать смысл. Есть ли способ удалить нулевые строки или различать ячейки, содержащие нулевую строку, и те, которые пусты?
Приведенный ниже код удалит все нулевые строки в нижней части столбцов, а также те, которые содержат нули.
Sub ClearBlankCells()
' 146
Dim Rng As Range ' working range
Dim R As Long ' intermediate: row
Dim C As Long ' loop counter: columns
Application.ScreenUpdating = False
With ActiveSheet
With .Range("B2:GQ244")
.Formula = "=IF(ISERROR(FIND( B$1,Sheet9!$H34)),"""",Sheet9!$I34)"
' replace formulas with their values
.Copy
.PasteSpecial Paste:=xlPasteValues
End With
Application.CutCopyMode = False
For C = 2 To 200 Step 1
Set Rng = .Columns(C)
R = Application.Evaluate("SUMPRODUCT((" & Rng.Address & "<>"""")*(" & _
Rng.Address & "<>0)*1)")
If R > 0 Then
Set Rng = Range(.Cells(R + 1, C), .Cells(Rows.Count, C))
Rng.ClearContents
End If
' sort by column
' Range(.Cells(2, C), .Cells(245, C)).Sort Key1:=.Cells(2, C), Order1:=xlAscending
Next C
End With
Application.ScreenUpdating = True
End Sub
Обратите внимание, что в блок данных над нижней частью каждого столбца, включая заголовок, нельзя включать пробелы или нули.
Сортировка должна быть выполнена после того, как такие ячейки будут удалены, но я оставил инструкции сортировки затемненными, потому что это неправильно либо синтаксически, либо по идее. Если вам нужно отсортировать каждый столбец, синтаксис неверен, потому что синтаксис сортирует весь лист. С другой стороны, если вы хотите отсортировать весь лист, вам не нужно делать это в цикле 200 раз.
Код работает очень медленно, что приводит к двум наблюдениям.
Поэтому должны быть гораздо лучшие способы добиться того, чего вы хотите.
Спасибо за ответ. Мне нужно отсортировать столбец по отдельности. B1:GQ1 содержат имена, а строки после них содержат нулевой номер страницы. Я сортирую столбцы по отдельности, чтобы увидеть, какое имя появляется на каких страницах. Это индекс для публикации. Возможно, есть лучший способ сделать это, но я не предвижу, что буду делать эту работу снова в будущем. Так что, пока у меня есть рабочий метод, все в порядке. Если мне нужно сделать это много раз, я буду исследовать, как сделать это лучше.
Ячейка, содержащая формулу, не пуста. Он просто ничего не отображает, но содержит формулу.