2016-12-22 2 views
0

У меня возникли трудности с применением команды If, которую я хочу выполнить для всех строк выбранного диапазона. До сих пор я получил это:VBA - Создать цикл для набора активных ячеек с командой If

Dim x As Integer 

    NumRows = Range("J2", Range("J2").End(xlDown)).Rows.Count 

    Range("J2").Select 

    For x = 1 To NumRows 
    If ActiveCell.Value = "9995" Then 
    ActiveCell.Offset(0, 7).Value = ActiveCell.Offset(0, 3).Value 
    Else: ActiveCell.EntireRow.Delete 
    End If 
    ActiveCell.Offset(1, 0).Select 
    Next 

Это, кажется, нет никакой проблемы, выбирая диапазон ячеек от J2 до конца списка данных. У него также нет проблем с поиском ячеек в этом диапазоне, которые содержат «9995», и выполнение команды для копирования данных 3 ячейки вправо от ячейки «9995» и вставки ее в 7 ячеек справа от ячейки «9995». Он даже удаляет всю строку, где значение активной ячейки не является «9995» (это именно то, что я хочу), но только в некоторых случаях. Он оставляет несколько строк, для которых значение активной ячейки не «9995», и я не могу понять, почему.

Может ли кто-нибудь помочь?

Спасибо!

+0

Вы должны иметь в виду, что после удаления строки следующая строка вниз становится активной ячейкой. После удаления команда 'ActiveCell.Offset (1, 0) .Select' выполняется, что означает, что она пропускает строку, так как эта строка уже была выбрана после удаления. –

+0

Следствие комментария Мистера 832 состоит в том, что при удалении лучше удалять петлю назад. – SJR

+0

Спасибо за ввод, оба. Я буду помнить об этом в будущем. – Alex

ответ

1

Здесь есть одна основная проблема и несколько мелких проблем.

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

Незначительные проблемы включают в себя избегая выбор (или ActiveCell) где это возможно, с указанием рабочего листа, к которому относится любой Range, используя Long, а не Integer, и используя Option Explicit (всегда хорошая идея).

Собирает все вместе, попробуйте вместо этого:

Option Explicit 

Sub test() 
    Dim x As Long 
    Dim firstRow As Long 
    firstRow = 2 
    Dim lastRow As Long 
    With ActiveSheet 
     lastRow = .Range("J2").End(xlDown).Row 
     For x = lastRow To firstRow Step -1 
      If .Range("J" & x).Value = "9995" Then 
       .Range("J" & x).Offset(0, 7).Value = .Range("J" & x).Offset(0, 3).Value 
      Else 
       .Range("J" & x).EntireRow.Delete 
      End If 
     Next 
    End With 
End Sub 

Также стоит отметить, что этот код предполагает, что данные начинаются по строке 2, и не имеют никаких пробелов в столбце J. Если какой-либо из них неправда, это не сработает правильно, поэтому вы можете переосмыслить, как вы определяете numRows.

+0

Большое спасибо bobajob. Это дало мне несколько новых концепций, о которых нужно думать. Я все еще изучаю много основ, так что это отличная помощь. – Alex

+0

Единственная проблема с этим заключается в том, что команда не применяется к нижней строке, когда она закончена. Я пытаюсь понять, почему это возможно. Я предполагаю, что это как-то связано с линией. Для x = numRows To 2 Step -1. – Alex

+0

А, думаю, я взломал его. Я подчиняюсь In For x = numRows + 1 To 2 Step -1, и это похоже на трюк. В очередной раз благодарим за помощь! – Alex

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

  • Нет связанных вопросов^_^