2013-03-14 2 views
1

Я работал над макросом, чтобы очистить форму, сгенерированную и скопированную в Excel. Я все выясняю до последнего этапа, когда мне нужно удалить строки, содержащие экстраординарные формулы. Пример:VBA Excel - Есть ли способ удалить строки на основе критериев в двух столбцах?

400000 | Smith, John| 2.4 | 5.66| =C1+D1 
400001 | Q, Suzy | 4.6 | 5.47| =C2+D2 
400002 | Schmoe, Joe| 3.8 | 0.14| =C3+D3 
Blank |    |  |  | #VALUE 
Blank |    |  |  | #VALUE 

Есть ли формула для сравнения столбца «A» на колонке «E» и иметь его удалить все строки без значения в «A», но значение в «E»?

Я пробовал формулу базовой петли, идущую исключительно пустым столбцом «А», который работал навсегда, удаляя строки под информацией, которую я хочу сохранить, и нашел формулу, касающуюся фильтров на этом веб-сайте (от brettdj), но я не знал, как отредактировать его, чтобы правильно захватить то, что мне нужно.

Это то, что я от brettdj:

Sub QuickKill() 
Dim rng1 As Range, rng2 As Range, rng3 As Range 
Set rng1 = Cells.Find("*", , xlValues, , xlByColumns, xlPrevious) 
Set rng2 = Cells.Find("*", , xlValues, , xlByRows, xlPrevious) 
Set rng3 = Range(Cells(rng2.Row, rng1.Column), Cells(1, rng1.Column)) 
Application.ScreenUpdating = False 
Rows(1).Insert 
With rng3.Offset(-1, 1).Resize(rng3.Rows.Count + 1, 1) 
    .FormulaR1C1 = "=OR(RC1="",RC1<>"")" 
    .AutoFilter Field:=2, Criteria1:="TRUE" 
    .EntireRow.Delete 
    On Error Resume Next 
    'in case all rows have been deleted 
    .EntireColumn.Delete 
    On Error GoTo 0 
End With 
Application.ScreenUpdating = True 

Некоторые другая информация:

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

Число строк, заполненных 40 #### 's изменений, поэтому я не могу просто указать строку 4 удаления макросов.

У меня нет обширных знаний о макросах (очевидно), поэтому подробные объяснения того, как работают определенные части, будут оценены. Заранее благодарим за любую помощь.

+0

Хорошо, эта формула ** FormulaR1C1 = "= OR (RC1 =" ", RC1 <>" ")" ** возвращает TRUE из A1 = "" или A1 <> "" –

+0

Я добавил ответ, ниже которого использует трюк SpecialCells, чтобы найти все строки, которые вы хотите удалить ... НО, это зависит от того, как вы получите формулу для проверки, следует ли удалить строку! –

ответ

2

да есть способ, который не нужен цикл

ваша формула (в таблице Excel) будет что-то вроде этого:

=IF(AND(A:A="",E:E<>""),"DELETE THIS ROW","LEAVE THIS ROW") 

сейчас, можно получить, что формула чтобы поместить ошибку в строки, где я тестирую, возвращает True. Причина, по которой мы это сделаем, - это функция Excel под названием SpecialCells.

В Excel выберите любую пустую ячейку, и в типе формулы бар

=NA() 

Далее, нажмите F5 или CTRL + G (Перейти ... на меню Edit), затем нажмите Специальная кнопка, чтобы отобразить диалог SpecialCells.

В этом диалоговом окне нажмите радио рядом с «Формулы» и снизу, снимите флажки, чтобы выбрать только Ошибки. Теперь нажмите OK

Excel должен был выбрать все ячейки на листе с ошибкой (# N/A).

ниже код использует этот трюк, создав формулу в столбце Н, положит # N/A во всех строках, которые вы хотите удалить, затем вызвать SpecialCells, чтобы найти строки, и ясно (удалить) их ...

Sub clearCells() 
    ' 
    Dim sFormula As String 
    ' 
    ' this formula put's an error if the test returns true, 
    ' so we can use SpecialCells function to highlight the 
    ' rows to be deleted! 
sFormula = "=IF(AND(A:A="""",E:E<>""""),NA(),"""")" 
' 
' put a formula into column H, to find the rows that ned to be deleted... 
Range("H5:H" & Range("E65536").End(xlUp).Row).Formula = sFormula 
' 
Stop ' next line clears multiple rows, could also delete the entire row! 
' now clear the cells returned by SpecialCells ... 
Range("H5:H" & Range("E65536").End(xlUp).Row).SpecialCells(xlCellTypeFormulas, xlErrors).Offset(0, -7).Clear ' ' EntireRow .Delete shift:=xlup 
' 
' clean up the formula 
Range("H5:H" & Range("E65536").End(xlUp).Row).Clear ' 
    End Sub 

копия паста, что и пошагова с помощью F8 ...

, то мы можем помочь вам некоторые более ...

Надеется, что поможет вам начать работу

Кстати, это также возможно, с петлей, если вы действительно хотите один :)

Филипп

+0

+1 для беззаботного пути;). Это умно. – Sam

+0

Спасибо, Филипп! Это работает отлично, единственная проблема, с которой я столкнулся, заключалась в том, что во время тестирования мои формулы в столбце «E» на самом деле не имели значений, поэтому все они были #value! который отбросил вашу формулу. Как только я убедился, что у формулы есть фактические ответы, все щелкнуло. Он также бежал очень быстро, что было фантастическим. Я ценю специфику, которую вы дали. Это было очень полезно! – user2170801

+0

спасибо, можете ли вы выбрать ответ? –

1

Я не знаю, почему использование петель было сделано плохо, Филипп. Вот простой макрос, который проходит через каждую строку и удаляет строки, где Column A пуст, и Column E имеет некоторое значение.

Он делает предположение, что ваш код находится на Sheet 1. Я прокомментировал код, чтобы вам было легче следовать. Если вы не хотите рассматривать строки 1-5 для удаления, тогда установите значение For loop в 6, как говорится в коде в коде.

Обратите внимание, что удаление происходит снизу вверх, потому что при удалении строки число totalRows изменяется в цикле. Чтобы избежать цикла из отсутствующих строк, я просто перешел в обратном порядке.

КОД

Public Sub DeleteWhereEmpty() 
    Dim colARowCount As Integer 
    Dim colERowCount As Integer 
    Dim totalRows As Integer 
    Dim currentRow As Integer 
    Dim colA As Integer 
    Dim colE As Integer 
    Dim colACurrentValue As String 
    Dim colECurrentValue As String 

    colA = 1 
    colE = 5 
    colARowCount = Sheet1.Cells(Rows.Count, colA).End(xlUp).Row 
    colERowCount = Sheet1.Cells(Rows.Count, colE).End(xlUp).Row 

    'set total number of rows to look at 
    totalRows = colARowCount 
    If colARowCount < colERowCount Then 
     totalRows = colERowCount 'E has more rows, so use it 
    End If 

    'to stop deleting at row 5, replace 'To 1' with 'To 6' 
    For currentRow = totalRows To 1 Step -1 
     colACurrentValue = Cells(currentRow, colA).Value 
     colECurrentValue = Cells(currentRow, colE).Text 

     'if A is empty and E has data in it, delete the row 
     If colACurrentValue = "" Or IsEmpty(colACurrentValue) _ 
      And Len(colECurrentValue) > 0 Then 
      Cells(currentRow, colA).EntireRow.Delete 
     End If 
    Next 
End Sub 

ПЕРЕД

enter image description here

ПОСЛЕ

enter image description here

+1

Я использую петли все время, за исключением случаев, когда они не нужны ... –

+0

Спасибо за версию цикла, Сэм. Он работал отлично, несмотря на то, что формулы, не имеющие правильных ответов на них в колонке «E», были проблемой, с которой я столкнулся с тестированием Филиппа, хотя для завершения потребовалось немного времени. На всякий случай я сохраню обе версии на своем листе. Большое вам спасибо за вашу помощь! – user2170801

Смежные вопросы