Страницы: 1
RSS
Удалить целиком те строки, у которых внутри выделенного диапазона стоят только пустые ячейки
 
Выделяете нужный диапазон и запускаете макрос. Задача - удалить целиком те строки, у которых внутри выделенного диапазона стоят только пустые ячейки  
Sub Удалить_пустые()  
Dim RB As Long, CB As Long, RS As Long, CS As Long, I As Long  
Application.ScreenUpdating = False  
Application.Calculation = xlCalculationManual  
RB = Selection.Cells(1, 1).Row  
CB = Selection.Cells(1, 1).Column  
RS = Selection.Rows.Count  
CS = Selection.Columns.Count  
For I = 1 To RS  
Range(Cells(RB + RS - I, CB), Cells(RB + RS - I, CB + CS - 1)).Select  
If Selection.Text = "" Then ActiveCell.EntireRow.Delete  
Next I  
Application.Calculation = xlCalculationAutomatic  
Application.ScreenUpdating = True  
End Sub  
 
Я написал макрос, который в выделенном диапазонепроверяет одна за другой все строки и удаляет те строки, в которых внутри выделенного диапазона имеются только пустые ячейки.  
Причём удаляется вся строка EXCEL, даже если в этой строке есть данные за пределами выделенного диапазона (потому что задача так и стоит)  
 
Посмотрите код макроса пожалуйста, и напишите если там есть явные ошибки или недостатки, которые могут привести к неправильному результату.
 
Вы в Вашем коде проверяете пустоту ВСЕХ ячеек строки, но на самом деле в Вашем задании явно указано что надо удалить только те значения, в которых не указана цена и остаток - бишь надо проверять только колонки C и D  
Плюс зачем городить огород с перебором строк: Вы определили первую строку выделения (RB), определили количество строк выделения (RS) - вот и шагайте от RB к RB+RS. Хотите проверять колонки снизу вверх - шагайте от RB+RS к RB с шагом -1.  
У меня заработал такой код:  
Sub Óäàëèòü_ïóñòûå()  
   Dim RB As Long, CB As Long, RS As Long, CS As Long, I As Long  
     
   Application.ScreenUpdating = True  
   Application.Calculation = xlCalculationManual  
   RB = Selection.Cells(1, 1).Row  
   CB = Selection.Cells(1, 1).Column  
   RS = Selection.Rows.Count  
   CS = Selection.Columns.Count  
   For I = RB To RB + RS  
       If Range(Cells(I, 3), Cells(I, 4)).Text = "" Then Range(Cells(I, 3), Cells(I, 4)).EntireRow.Delete  
   Next I  
   Application.Calculation = xlCalculationAutomatic  
Application.ScreenUpdating = True  
End Sub
 
If IsEmpty(Selection.Cells(3)) And IsEmpty(Selection.Cells(4)) Then ActiveCell.EntireRow.Delete
 
а это что за ерунда?  
If Range(Cells(I, 3), Cells(I, 4)).Text = "" ...  
 
что это, по-вашему, должно вернуть?
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Это не ерунда.  
Рекомендую проверить.  
А также на isEmpty и isNull
 
Андрей, перед тем как писать, я в своем файле внес в A1 "а", в B1 "б"  
 
в окне Immediate получил:  
? [a1].text ==> а
? [b1].text ==> б
? [a1:b1].text ==> Null
 
вот, решил спросить - что за ерунда? :)
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
оказывается! :))  
 
если в [a1] и [b1] будет одинаковый текст, то
? [a1:b1]
его и вернет  
 
честно говоря, не знал.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Если строк много, я бы отбирал автофильтром.
Я сам - дурнее всякого примера! ...
 
Да можно и через анализ массива данных Selection  
Public Sub DeleteRowWithEmptyCell()  
   Dim vData As Variant, sAddress As String  
   Dim rOffset As Long, isBlank As Boolean  
   Dim iCol As Long, iRow As Long  
   If TypeOf Selection Is Range Then  
       If Selection.Rows.Count < 2 Then Exit Sub  
       sAddress = "": vData = Selection.Value  
       rOffset = Selection.Row - 1  
       For iRow = 1 To UBound(vData, 1)  
           isBlank = True  
           For iCol = 1 To UBound(vData, 2)  
               If Not IsEmpty(vData(iRow, iCol)) Then  
                   isBlank = False: Exit For  
               End If  
           Next iCol  
           If isBlank Then  
               If sAddress = "" Then  
                   sAddress = "A" & CStr(iRow + rOffset)  
               Else  
                   sAddress = sAddress & ",A" & CStr(iRow + rOffset)  
               End If  
           End If  
       Next iRow  
       If sAddress <> "" Then ActiveSheet.Range(sAddress).EntireRow.Delete  
   End If  
End Sub
 
>> Таблица взята условно, на самом деле приходится работать с таблицами, с большим количеством строк и столбцов  
   
Если длина строки sAddress > 256 - вывалится с ошибкой.
Я сам - дурнее всякого примера! ...
 
Ну и удалять строки вот так нельзя:  
 
For I = RB To RB + RS  
If Range(Cells(I, 3), Cells(I, 4)).Text = "" Then Range(Cells(I, 3), Cells(I, 4)).EntireRow.Delete  
Next I  
 
Нужно или идти снизу вверх, или после удаления корректировать индекс - проще идти снизу.
 
Sub www()  
   With [a5].CurrentRegion
       .AutoFilter 3, "=": .AutoFilter 4, "="  
       .Offset(1).SpecialCells(12).EntireRow.Delete  
       .AutoFilter  
   End With  
End Sub
Я сам - дурнее всякого примера! ...
 
спасибо  
всем
 
Сначала ставите фильтр на шапку таблицы.  
Потом выделяете нужные  столбцы  
Запускаете макрос  
 
Sub УП()  
Dim ФильНач As Long, ФильКол As Long, ВыдНач As Long, ВыдКол As Long, I As Long  
Application.ScreenUpdating = False  
Application.Calculation = xlCalculationManual  
ВыдНач = Selection.Cells(1, 1).Column  
ВыдКол = Selection.Columns.Count  
With ActiveSheet.AutoFilter.Range  
ФильНач = .Cells(1, 1).Column  
ФильКол = .Columns.Count  
If ВыдНач < ФильНач Or ВыдНач + ВыдКол > ФильНач + ФильКол Then  
MsgBox ("Выделенные столбцы выходят за пределы фильтруемых столбцов !")  
Exit Sub  
End If  
.Select  
For I = (ВыдНач - ФильНач + 1) To (ВыдНач + ВыдКол - ФильНач)  
Selection.AutoFilter I, "="  
Next  
Selection.Offset(1).SpecialCells(12).EntireRow.Delete  
Selection.AutoFilter  
End With  
Application.Calculation = xlCalculationAutomatic  
Application.ScreenUpdating = True  
End Sub  
 
В охваченном фильтром диапазоне удаляются целиком строки, у которых внутри выделенных столбцов имеются только пустые ячейки.  
 
При этом:  
Без разницы, именно в каком месте листа расположена таблица  
Без разницы, именно в каком месте вы будете выделять нужные столбцы, можно даже выделять не целые столбцы, а ячейки или диапазон. Можно выделять ячейки над фильтруемым диапазоном, под фильтруемым диапазоном, или внутри фильтруемого диапазона  
Макрос не связан строго ни с одной ячейкой или диапазоном.  
 
Быстродействие по сравнению с первоначальным вариантом сильно ощутимо, так как первоначальный вариант удалял нужные строки по одному, а этот макрос удаляет все нужные строки одним скопом (с помощью фильтра)  
 
НО:  
- Когда выделяете ячейки, чтобы показать макросу по каким столбцам надо проверять пустоту ячеек, нельзя выделять несмежные ячейки.  
- Если вы запустите макрос не поставив фильтр на шапку таблицы, то он не будет работать.  
 
Нужно, чтобы когда пользователь запустит макрос не поставив фильтр на шапку таблицы, ему выдало бы соответствующее сообщение и Exit Sub. Не могу пока это осуществить (Не знаю как проверить поставлен ли фильтр или нет)  
 
СПАСИБО ВСЕМ
 
If ActiveSheet.AutoFilterMode=False Then Exit Sub
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
о спасибо большое
Страницы: 1
Читают тему
Наверх