zelencov Пользователь Сообщений: 89 |
Добрый день! Кто-нибудь сталкивался с макросами по удалению ячеек по условию. В гугле нахожу макросу по удалению строк по условиям. |
Отдельно ячейку удалить невозможно; можно либо строку, либо столбец, либо просто очистить ячейку. |
|
Kuzmich Пользователь Сообщений: 7998 |
#3 14.08.2018 12:11:08
|
||
zelencov Пользователь Сообщений: 89 |
Kuzmich, спасибо! Можно ли сделать так, чтобы макрос срабатывал когда находишься на другом листе одной и той же книги. |
Kuzmich Пользователь Сообщений: 7998 |
Вам надо, чтобы макрос со всех листов убрал ячейки с яблоками и грушами в столбце А ? |
zelencov Пользователь Сообщений: 89 |
#6 14.08.2018 17:11:25
Только с одного листа. Разобрался. Добавил «Sheets(«Списки»).Select» Изменено: zelencov — 14.08.2018 17:16:57 |
||
Kuzmich Пользователь Сообщений: 7998 |
Так макрос и убирает ячейки с яблоками и грушами в столбце А с одного листа |
zelencov Пользователь Сообщений: 89 |
#8 14.08.2018 17:28:28 Как можно объединить 2 макроса в одном module:
|
||
Kuzmich Пользователь Сообщений: 7998 |
С какого листа вы запускаете макрос Sub Spiski_delete() ? |
zelencov Пользователь Сообщений: 89 |
Кнопки отдельной не выводил. Запускаю через вкладку разработчик — макросы. Запуск произвожу на любом листе — заданные действия проходят там где и требуется. |
Kuzmich Пользователь Сообщений: 7998 |
#11 14.08.2018 17:45:08 Используйте конструкцию With……End With
|
||
_Igor_61 Пользователь Сообщений: 3007 |
Еще вариант по теме, без «Or»: |
zelencov Пользователь Сообщений: 89 |
#13 15.08.2018 12:12:21 Всем спасибо за помощь! Все получилось. |
Хитрости »
28 Май 2011 644785 просмотров
Как удалить строки по условию?
Предположу, что почти каждый сталкивался с ситуацией, когда необходимо удалить только определенные строки: имеется большая таблица и необходимо удалить из неё только те строки, которые содержат какое-то слово (цифру, фразу). Для выполнения подобной задачи можно воспользоваться несколькими способами.
Способ первый:
Использовать встроенное средство Excel — фильтр. Сначала его необходимо «установить» на листе:
- Выделяем таблицу с данными, включая заголовки. Если их нет — то выделяем с самой первой строки таблицы, в которой необходимо удалить данные
- устанавливаем фильтр:
- для Excel 2003: Данные—Фильтр—Автофильтр
- для Excel 2007-2010: вкладка Данные(Data) —Фильтр(Filter)(или вкладка Главная(Home) —Сортировка и фильтр(Sort&Filter) —Фильтр(Filter))
Теперь выбираем условие для фильтра:
- в Excel 2003 надо выбрать Условие и в появившейся форме выбрать непосредственно условие(«равно», «содержит», «начинается с» и т.д.), а напротив значение в соответствии с условием.
- Для 2007-2010 Excel нужно выбрать Текстовые фильтры(Text Filters) и либо сразу выбрать одно из предлагаемых условий, либо нажать Настраиваемый фильтр(Custom Filter) и ввести значения для отбора в форме
После этого удалить отфильтрованные строки. В 2007 Excel могут возникнуть проблемы с удалением отфильтрованных строк, поэтому рекомендую сначала так же прочитать статью: Excel удаляет вместо отфильтрованных строк — все?! Как избежать.
Способ второй:
применить код VBA, который потребует только указания значения, которое необходимо найти в строке и номер столбца, в котором искать значение.
Sub Del_SubStr() Dim sSubStr As String 'искомое слово или фраза(может быть указанием на ячейку) Dim lCol As Long 'номер столбца с просматриваемыми значениями Dim lLastRow As Long, li As Long Dim lMet As Long Dim arr sSubStr = InputBox("Укажите значение, которое необходимо найти в строке", "www.excel-vba.ru", "") If sSubStr = "" Then lMet = 0 Else lMet = 1 lCol = Val(InputBox("Укажите номер столбца, в котором искать указанное значение", "www.excel-vba.ru", 1)) If lCol = 0 Then Exit Sub lLastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count arr = Cells(1, lCol).Resize(lLastRow).Value Application.ScreenUpdating = 0 Dim rr As Range For li = 1 To lLastRow 'цикл с первой строки до конца If -(InStr(arr(li, 1), sSubStr) > 0) = lMet Then If rr Is Nothing Then Set rr = Cells(li, 1) Else Set rr = Union(rr, Cells(li, 1)) End If End If Next li If Not rr Is Nothing Then rr.EntireRow.Delete Application.ScreenUpdating = 1 End Sub
Если значение sSubStr не будет указано, то будут удалены строки, ячейки указанного столбца которых, пустые.
Данный код необходимо поместить в стандартный модуль. Вызвать с листа его можно нажатием клавиш Alt+F8, после чего выбрать Del_SubStr и нажать Выполнить. Если в данном коде в строке
If -(InStr(Cells(li, 1), sSubStr) > 0) = lMet Then
вместо = lMet указать <> lMet, то удаляться будут строки, не содержащие указанное для поиска значение. Иногда тоже удобно.
Но. Данный код просматривает строки на предмет частичного совпадения указанного значения. Например, если Вы укажете текст для поиска «отчет», то будут удалены все строки, в которых встречается это слово(«квартальный отчет», «отчет за месяц» и т.д.). Это не всегда нужно. Поэтому ниже приведен код, который будет удалять только строки, указанные ячейки которых равны конкретно указанному значению:
Sub Del_SubStr() Dim sSubStr As String 'искомое слово или фраза(может быть указанием на ячейку) Dim lCol As Long 'номер столбца с просматриваемыми значениями Dim lLastRow As Long, li As Long Dim arr sSubStr = InputBox("Укажите значение, которое необходимо найти в строке", "www.excel-vba.ru", "") lCol = Val(InputBox("Укажите номер столбца, в котором искать указанное значение", "www.excel-vba.ru", 1)) If lCol = 0 Then Exit Sub lLastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count arr = Cells(1, lCol).Resize(lLastRow).Value Application.ScreenUpdating = 0 Dim rr As Range For li = 1 To lLastRow 'цикл с первой строки до конца If CStr(arr(li, 1)) = sSubStr Then If rr Is Nothing Then Set rr = Cells(li, 1) Else Set rr = Union(rr, Cells(li, 1)) End If End If Next li If Not rr Is Nothing Then rr.EntireRow.Delete Application.ScreenUpdating = 1 End Sub
Здесь так же, как и в случае с предыдущим кодом можно заменить оператор сравнения(Cells(li, lCol) = sSubStr) с равно на неравенство(Cells(li, lCol) <> sSubStr) и тогда удаляться будут строки, значения ячеек которых не равно указанному.
УДАЛЕНИЕ СТРОК НА ОСНОВАНИИ СПИСКА ЗНАЧЕНИЙ(МНОЖЕСТВЕННЫЕ КРИТЕРИИ)
Иногда бывают ситуации, когда необходимо удалить строки не по одному значению, а по нескольким. Например, если строка содержит или Итог или Отчет. Ниже приведен код, при помощи которого можно удалить строки, указав в качестве критерия диапазон значений.
Значения, которые необходимо найти и удалить перечисляются на листе с именем «Лист2». Т.е. указав на «Лист2» в столбце А(начиная с первой строки) несколько значений — они все будут удалены. Если лист называется иначе(скажем «Соответствия») в коде необходимо будет «Лист2» заменить на «Соответствия». Удаление строк происходит на активном в момент запуска кода листе. Это значит, что перед запуском кода надо перейти на тот лист, строки в котором необходимо удалить.
Sub Del_Array_SubStr() Dim sSubStr As String 'искомое слово или фраза Dim lCol As Long 'номер столбца с просматриваемыми значениями Dim lLastRow As Long, li As Long Dim avArr, lr As Long Dim arr lCol = Val(InputBox("Укажите номер столбца, в котором искать указанное значение", "www.excel-vba.ru", 1)) If lCol = 0 Then Exit Sub Application.ScreenUpdating = 0 lLastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count 'заносим в массив значения листа, в котором необходимо удалить строки arr = Cells(1, lCol).Resize(lLastRow).Value 'Получаем с Лист2 значения, которые надо удалить в активном листе With Sheets("Лист2") 'Имя листа с диапазоном значений на удаление avArr = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)) End With 'удаляем Dim rr As Range For lr = 1 To UBound(avArr, 1) sSubStr = avArr(lr, 1) For li = 1 To lLastRow 'цикл с первой строки до конца If CStr(arr(li, 1)) = sSubStr Then If rr Is Nothing Then Set rr = Cells(li, 1) Else Set rr = Union(rr, Cells(li, 1)) End If End If DoEvents Next li DoEvents Next lr If Not rr Is Nothing Then rr.EntireRow.Delete Application.ScreenUpdating = 1 End Sub
Чтобы код выше удалял строки не по точному совпадению слов, а по частичному(например, в ячейке записано «Привет, как дела?», а в списке есть слово «привет» — надо удалить, т.к. есть слово «привет»), то надо строку:
If CStr(arr(li, 1)) = sSubStr Then
заменить на такую:
If InStr(1, arr(li, 1), sSubStr, 1) > 0 Then
УДАЛЕНИЕ ИЗ ЛИСТА СТРОК, КОТОРЫХ НЕТ В СПИСКЕ ЗНАЧЕНИЙ(МНОЖЕСТВЕННЫЕ КРИТЕРИИ)
Т.к. в последнее время стало поступать все больше и больше вопросов как не удалять значения по списку, а наоборот — оставить в таблице только те значения, которые перечислены в списке — решил дополнить статью и таким кодом.
Значения, которые необходимо оставить перечисляются на листе с именем «Лист2». Т.е. указав на «Лист2» в столбце А(начиная с первой строки) несколько значений — после работы кода на листе будут оставлены только те строки, в которых присутствует хоть одно из перечисленных в списке значений. Если лист называется иначе(скажем «Соответствия») в коде необходимо будет «Лист2» заменить на «Соответствия». Удаление строк происходит на активном в момент запуска кода листе. Это значит, что перед запуском кода надо перейти на тот лист, строки в котором необходимо удалить.
В отличие от приведенных выше кодов, данный код ориентирован на то, что значения в списке указаны не полностью. Т.е. если необходимо оставить только те ячейки, в которых встречается слово «активы», то в списке надо указать только это слово. В этом случае если в ячейке будет записана фраза «Нематериальные активы» или «Активы сторонние» — эти ячейки не будут удалены, т.к. в них встречается слово «активы». Регистр букв при этом неважен.
'процедура оставляет в листе только те значения, которые перечислены в списке Sub LeaveOnlyFoundInArray() Dim sSubStr As String 'искомое слово или фраза Dim lCol As Long 'номер столбца с просматриваемыми значениями Dim lLastRow As Long, li As Long Dim avArr, lr As Long Dim arr Dim IsFind As Boolean lCol = Val(InputBox("Укажите номер столбца, в котором искать указанное значение", "www.excel-vba.ru", 1)) If lCol = 0 Then Exit Sub Application.ScreenUpdating = 0 lLastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count 'заносим в массив значения листа, в котором необходимо удалить строки arr = Cells(1, lCol).Resize(lLastRow).Value 'Получаем с Лист2 значения, которые надо удалить в активном листе With Sheets("Лист2") 'Имя листа с диапазоном значений на удаление avArr = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)) End With 'удаляем Dim rr As Range For li = 1 To lLastRow 'цикл с первой строки таблицы до конца IsFind = False For lr = 1 To UBound(avArr, 1) 'цикл по списку значений на удаление sSubStr = avArr(lr, 1) If InStr(1, arr(li, 1), sSubStr, 1) > 0 Then IsFind = True End If DoEvents Next lr 'если значение таблицы не найдено в списке - удаляем строку If Not IsFind Then If rr Is Nothing Then Set rr = Cells(li, 1) Else Set rr = Union(rr, Cells(li, 1)) End If End If DoEvents Next li If Not rr Is Nothing Then rr.EntireRow.Delete Application.ScreenUpdating = 1 End Sub
Чтобы код выше сравнивал значения таблицы со значениями списка по точному совпадению слов, а не по частичному, то надо строку:
If InStr(1, arr(li, 1), sSubStr, 1) > 0 Then
заменить на такую:
If CStr(arr(li, 1)) = sSubStr Then
Для всех приведенных кодов можно строки не удалять, а скрывать. Для этого надо строку:
If Not rr Is Nothing Then rr.EntireRow.Delete
заменить на такую:
If Not rr Is Nothing Then rr.EntireRow.Hidden = True
По умолчанию все коды начинают просмотр строк с первой по последнюю заполненную на листе. И если необходимо удалять строки не с первой или не по последнюю, то надо внести корректировки в эту строку:
For li = 1 To lLastRow 'цикл с первой строки до конца
1 — это первая строка; lLastRow — определяется автоматически кодом и равна номеру последней заполненной строки на листе. Если надо начать удалять строки только с 7-ой строки(например, в первых 6-ти шапка), то код будет выглядеть так:
For li = 7 To lLastRow 'цикл с седьмой строки до конца
А если надо удалять только с 3-ей по 300-ю, то код будет выглядеть так:
For li = 3 To 300 'цикл с третьей строки до трехсотой
Так же см.:
Что такое макрос и где его искать?
Что такое модуль? Какие бывают модули?
Как создать кнопку для вызова макроса на листе
Удаление всех пустых строк в таблице
Удаление пустых столбцов на листе
Установить Быстрый фильтр
Фильтр
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
Getting rid of specific cells could prove challenging if you were to do it manually. In this article, we’re going to show you how to make Excel delete rows with value of your choosing, using VBA. You can remove cells with certain strings or create an input cell where you can enter a value to select which cells to remove.
A VBA code to do this will consist of 2 parts: determining the variables, and deleting the rows that where the condition is met. We present you 2 alternative approaches for both parts.
Variables
The variables are the range that test will be applied and the condition itself. You can choose to determine these variables by entering them in the code or create an input section to let the users do this. Entering a static value into the code is easier if you’re consistently working with same range. On the other hand, if range changes, users will have to update the code every time. Here are both approaches for the range F3:F16 and condition the text set to «No»:
Static variable in the code:
Set condition_range = Range("F3:F16")
condition = "No"
Dynamic variable through user input:
Set condition_range = Application.InputBox(Prompt:="Please select the range that condition will be tested:", Type:=8)
condition = Application.InputBox(Prompt:="Please type the condition text:")
Here, the user entries can be collected with the Application.InputBox control and we must also set the Type argument to 8 to select all ranges. If the Type argument is omitted, the default input type will be Text.
We recommend using an error handling method in your code to handle the case of a user pressing Cancel in the InputBox instead of providing the requested information. Our error handling approach uses 3 types of code blocks:
Error handling part before End Sub:
error_handling:
MsgBox ("Process is canceled.") 'Explanatory message for end-user
End Sub
Move the process to error handling code part:
On Error GoTo error_handling
Reset error handling procedure:
On Error GoTo 0
Rows
You have 2 options to determine the rows to be deleted. You can either perform a loop through the rows and apply a logical condition test, or use the VBA support of the AutoFilter feature to filter the rows that meet the condition. The decision criteria between two approaches will determine whether the data will be kept.
The AutoFilter feature won’t work if your range is defined as an Excel Table. As a result, we suggest you to return your table into a regular range before running AutoFilter code. On the other hand, if your data spans over thousands of rows, looping through rows will require more computer resources and take longer to process. Let’s see code blocks for both approaches:
Looping through rows:
With condition_range
For i = .SpecialCells(xlCellTypeLastCell).Row To .Row Step -1If Cells(i, .Column) = condition Then Rows(i).EntireRow.Delete
Next i
End With
AutoFilter:
condition_range.AutoFilter Field:=1, Criteria1:=condition
Rows(condition_range.EntireRow.Address).Delete Shift:=xlUp
First, you need to add the module into the workbook or the add-in file. Copy and paste the code into the module to run it. The main advantage of the module method is that it allows saving the code in the file, so that it can be used again later. Furthermore, the subroutines in modules can be used by icons in the menu ribbons or keyboard shortcuts. Remember to save your file in either XLSM or XLAM format to save your VBA code.
Delete rows by a static condition with loop
Sub DeleteRowsByStaticCondition_Loop()
'defining variablesDim condition_range As Range
Dim condition As String
Dim i As Integer
'populating variables
Set condition_range = Range("F:F")
condition = "No"
'loop through rows and test the condition
With condition_range
For i = Cells(.SpecialCells(xlCellTypeLastCell).Row, .Column).Row To 1 Step -1
If Cells(i, .Column) = condition Then Rows(i).EntireRow.Delete
Next i
End With
End Sub
Delete rows by a dynamic condition with loop
Sub DeleteRowsByUserCondition_Loop()
'defining variablesDim condition_range As Range
Dim condition As String
Dim i As Integer
'error handling for Cancel buttons of InputBox controls
On Error GoTo error_handling
'populating variables
Set condition_range = Application.InputBox(Prompt:="Please select the range that condition will be tested:", Type:=8)
condition = Application.InputBox(Prompt:="Please type the condition text:")
'reset error handling procedure
On Error GoTo 0
'loop through rows and test the condition
With condition_range
For i = .SpecialCells(xlCellTypeLastCell).Row To .Row Step -1
If Cells(i, .Column) = condition Then Rows(i).EntireRow.Delete
Next i
End With
'exit sub without running error handling codes
Exit Sub
'error handling
error_handling:
MsgBox ("Process is canceled.") 'Explanatory message for end-user
End Sub
Delete rows by a static condition with AutoFilter
Sub DeleteRowsByStaticCondition_AutoFilter()
'defining variablesDim condition_range As Range
Dim condition As String
'populating variables
Set condition_range = Range("$F:$F")
condition = "No"
'applying AutoFilter
condition_range.AutoFilter Field:=1, Criteria1:=condition
'deleting filtered rows, remaining rows will be shifted to up
Rows(condition_range.EntireRow.Address).Delete Shift:=xlUp
'removing AutoFilter
On Error Resume Next
ActiveSheet.condition_range.ShowAllData
'selecting a cell for end-user
condition_range.Cells(1, 1).Select
End Sub
Delete rows by a dynamic condition with AutoFilter
Sub DeleteRowsByUserCondition_AutoFilter()
'defining variablesDim condition_range As Range
Dim condition As String
'populating variables
Set condition_range = Application.InputBox(Prompt:="Please select the range that condition will be tested:", Type:=8)
condition = Application.InputBox(Prompt:="Please type the condition text:")
'applying AutoFilter
condition_range.AutoFilter Field:=1, Criteria1:=condition
'deleting filtered rows, remaining rows will be shifted to up
Rows(condition_range.EntireRow.Address).Delete Shift:=xlUp
'removing AutoFilter
On Error Resume Next
ActiveSheet.condition_range.ShowAllData
'selecting a cell for end-user
condition_range.Cells(1, 1).Select
End Sub
макрос удалит на листе все строки, в которых содержится искомый текст:
(пример — во вложении ConditionalRowsDeleting.xls)
Sub УдалениеСтрокПоУсловию() Dim ra As Range, delra As Range, ТекстДляПоиска As String Application.ScreenUpdating = False ' отключаем обновление экрана ТекстДляПоиска = "Наименование ценности" ' удаляем строки с таким текстом ' перебираем все строки в используемом диапазоне листа For Each ra In ActiveSheet.UsedRange.Rows ' если в строке найден искомый текст If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then ' добавляем строку в диапазон для удаления If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next ' если подходящие строки найдены - удаляем их If Not delra Is Nothing Then delra.EntireRow.Delete End Sub
Чтобы вместо удаления просто скрыть такие строки, замените строку
If Not delra Is Nothing Then delra.EntireRow.Delete
на
If Not delra Is Nothing Then delra.EntireRow.Hidden=TRUE
Расширенная версия этого макроса — с использованием UserForm для ввода искомого значения
Function ПоискСтрокПоУсловию(ByVal ТекстДляПоиска As String, Optional HideOnly As Boolean) As Long ' функция получает в качестве параметра ТекстДляПоиска (можно использовать символы * и ?) ' Если HideOnly = TRUE, то строки, содержащие в ячейках ТекстДляПоиска, скрываются, ' иначе (HideOnly = FALSE - по умолчанию) - удаляются ' Функция возвращает количество удалённых строк Dim ra As Range, delra As Range Application.ScreenUpdating = False ' отключаем обновление экрана ' перебираем все строки в используемом диапазоне листа For Each ra In ActiveSheet.UsedRange.Rows ' если в строке найден искомый текст If Not ra.Find(ТекстДляПоиска, , xlValues, xlPart) Is Nothing Then ' добавляем строку в диапазон для удаления If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next On Error Resume Next: ПоискСтрокПоУсловию = delra.Areas.Count ' количество найденных строк If Not delra Is Nothing Then ' если подходящие строки найдены - скрываем или удаляем их If HideOnly Then delra.EntireRow.Hidden = True Else delra.EntireRow.Delete End If End Function
Ещё один вариант кода, позволяющего выполнять поиск (с последующим удалением или скрытием строк) сразу по нескольким условиям:
Sub УдалениеСтрокПоНесколькимУсловиям() Dim ra As Range, delra As Range Application.ScreenUpdating = False ' отключаем обновление экрана ' ищем и удаляем строки, содержащие заданный текст ' (можно указать сколько угодно значений, и использовать подстановочные знаки) УдалятьСтрокиСТекстом = Array("Наименование *", "Количество", _ "текст?", "цен*сти", "*78*") ' перебираем все строки в используемом диапазоне листа For Each ra In ActiveSheet.UsedRange.Rows ' перебираем все фразы в массиве For Each word In УдалятьСтрокиСТекстом ' если в очередной строке листа найден искомый текст If Not ra.Find(word, , xlValues, xlPart) Is Nothing Then ' добавляем строку в диапазон для удаления If delra Is Nothing Then Set delra = ra Else Set delra = Union(delra, ra) End If Next word Next ' если подходящие строки найдены, то: (оставьте одну из 2 следующих строк) If Not delra Is Nothing Then delra.EntireRow.Hidden = True ' скрываем их If Not delra Is Nothing Then delra.EntireRow.Delete ' удаляем их End Sub
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
Sub DeleteRowsEnhancedSafety() Dim i As Long, n As Long, m As Long, k As Long Dim rng As Range, arr() As Variant, response As VbMsgBoxResult Set rng = Cells(Cells.Rows.Count, 1) 'Формируем массив, состоящий из значений столбцов "A" и "B" 'от первой строки до последней заполненной в столбце "A". If Not IsEmpty(rng) Then Set rng = Range("A:B") Else Set rng = Range(Range("B1"), rng.End(xlUp)) arr = rng 'Формируем из данного массива новый, во втором столбце которого 'нет значений, эквивалентных константе vbNullString. n = UBound(arr) 'Вычислим количество непустых ячеек в диапазоне столбца "B". 'При этом адрес диапазона передается в том же стиле ссылок, 'который выставлен в приложении. В противном случае может 'возникнуть ситуация, когда в приложении используется стиль 'ссылок R1C1, а мы передаем ей адрес в стиле A1. В этом случае 'функция не сможет распознать адрес и вернет ошибку (а ошибки 'со значениями не сравниваются - "Type Mismatch"!) m = n - Evaluate("COUNTBLANK(" & rng.Columns(2).Address(ReferenceStyle:=Application.ReferenceStyle) & ")") 'Альтернативная поправка для предыдущей строки. 'm = n - Application.WorksheetFunction.CountBlank(rng.Columns(2)) 'Учтем случай, когда в столбце "B" есть только пустые ячейки и ячейки с vbNullString. If m = 0 Then response = MsgBox("В столбце ""B"" есть только пустые ячейки и ячейки с vbNullString. Удалить все значения столбцов ""A"" и ""B""?", vbYesNo, "Потверждение операции") If response = vbYes Then Range("A:B").Clear Else MsgBox "Операция отменена пользователем.", , "Информация" Exit Sub End If ReDim arr2(1 To m, 1 To 2) As Variant For i = 1 To n 'Учтем случай, когда столбец "B" содержит коды ошибок (которые несравнимы с vbNullString) If IsError(arr(i, 2)) Then k = k + 1 arr2(k, 1) = arr(i, 1) arr2(k, 2) = arr(i, 2) ElseIf arr(i, 2) <> vbNullString Then k = k + 1 arr2(k, 1) = arr(i, 1) arr2(k, 2) = arr(i, 2) End If Next i 'Очищаем столбцы "A:B" от старых данных. Range("A:B").Clear 'Выгружаем на лист сформированный массив. Cells(1).Resize(m, 2) = arr2 End Sub |