Я пытался решить эту проблему с помощью макросов VBA, но у меня ничего не получается.
Мой набор данных выглядит следующим образом:
A B C D E F G H
21 X
22 X
23 X
24 X X
25 X X
26 X X X X
Мне нужен макрос, который, учитывая диапазон, будет проверять определенные столбцы на наличие пустых ячеек и удалять всю строку.
Например, в наборе данных выше...
A21:H26
A
, B
и C
)Это должно означать, что только строка 26 не будет удалена, поскольку она содержит значения во всех указанных столбцах.
Я пробовал такой код, но, похоже, он удаляет строки без какой-либо реальной рифмы или причины, которую я могу понять:
Sub DeleteEmptyRowsInRange()
myarray = Range("A21:H30")
For r = 1 To UBound(myarray)
For c = 1 To UBound(myarray, 2)
If c = 4 Or c = 6 Or c = 13 Then
If Trim(Cells(r + 1, c)) = "" Then rows(r).EntireRow.Delete
End If
Next c
Next r
End Sub
заранее спасибо
Я пробовал несколько разных подходов @BigBen, но Excel вышел из строя, и я потерял последнюю попытку. Я добавил тот, который пробовал, используя функцию UBound
Золотое правило при удалении — выполнять цикл назад, чтобы избежать пропуска строк.
Платиновое правило — использовать Union
и удалять после цикла :-)
:) @BigBen - не уверен, что поставил бы это выше золотого правила, но я не эксперт.
После удаления строк диапазон ячеек смещается вверх. Поэтому рекомендуемый подход — либо удалить строки в обратном порядке, либо собрать все ненужные диапазоны с помощью функции Union
.
Sub DeleteEmptyRowsInRange()
Dim myArray, r As Long, c, delRng As Range
myArray = Range("A21:H26").Value
For r = 1 To UBound(myArray)
For Each c In Array(1, 2, 3) ' Col A, B, C
If Len(myArray(r, c)) = 0 Then
If delRng Is Nothing Then
Set delRng = Cells(20 + r, 1)
Else
Set delRng = Application.Union(delRng, Cells(20 + r, 1))
End If
End If
Next c
Next r
If Not delRng Is Nothing Then
delRng.EntireRow.Delete
End If
End Sub
Sub DeleteRowsWithEmptyColumns()
' Define constants.
Const RANGE_ADDRESS As String = "A21:M30"
Dim EMPTY_COLUMNS() As Variant: EMPTY_COLUMNS = VBA.Array(4, 6, 13)
' Reference the objects and return the values from the range in an array.
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim rg As Range: Set rg = ws.Range(RANGE_ADDRESS)
Dim Data() As Variant: Data = rg.Value
' Validate the numbers in the Empty-columns array.
If Application.Max(EMPTY_COLUMNS) < 1 Then
MsgBox """EMPTY-COLUMNS"" contains a number less than 1!", vbExclamation
Exit Sub
End If
If Application.Max(EMPTY_COLUMNS) > UBound(Data, 2) Then
MsgBox """EMPTY-COLUMNS"" contains a too large number!", vbExclamation
Exit Sub
End If
' Declare additional variables.
Dim urg As Range, r As Long, c As Long, WasEmptyColumnFound As Boolean
' Loop through the rows of the array and check if any columns is empty.
' If it is, combine the whole row range into a unioned range.
For r = 1 To UBound(Data, 1)
For c = 0 To UBound(EMPTY_COLUMNS)
If IsEmpty(Data(r, EMPTY_COLUMNS(c))) Then ' is empty
'If Len(CStr(Data(r, EMPTY_COLUMNS(c)))) = 0 Then ' is blank
If WasEmptyColumnFound Then
Set urg = Union(urg, rg.Rows(r))
Else
Set urg = rg.Rows(r)
WasEmptyColumnFound = True
End If
Exit For ' next row
End If
Next c
Next r
' Delete rows with empty columns.
If WasEmptyColumnFound Then urg.Delete Shift:=xlShiftUp
' Inform.
If WasEmptyColumnFound Then
MsgBox "Rows with empty columns deleted.", vbInformation
Else
MsgBox "No rows with empty columns found!", vbExclamation
End If
End Sub
Спасибо за ваш ответ и ваши усилия, но я уже использовал и принял другой ответ. +1 хотя
Должно быть выполнимо с помощью цикла и
WorksheetFunction.CountBlank
илиWorksheetFunction.CountA
, в зависимости от вашей логики. Можете ли вы поделиться своей попыткой?