2014-09-19 2 views
0

Код:Event Handler - Cell не Обновление непредвиденным

Private Sub Worksheet_change(ByVal target As Range) 
Application.ScreenUpdating = False 
Application.EnableEvents = False 

Dim cell 

For Each cell In Me.UsedRange.Columns("E").Cells 
    If cell.Text = "Cu" And cell.offset(0, -1) = "WR229" Then 
     MsgBox "Cu not permitted for WR229 or larger waveguide", vbOKOnly, "Cu Alert" 
     cell = "Al" 
    End If 
Next cell 

Application.ScreenUpdating = True 
Application.EnableEvents = True 
End Sub 

Проблема заключается в том, что при выполнении условия клетка не получает сброс к значению «Аль». Почему нет?

+0

Вы пытались поместить точку останова на начало цикла и пошаговое выполнение кода? – paulroho

ответ

1

Одна из возможных причин, по которой код OP может быть сбой, если UsedRange не начинается в столбце A. Это произойдет, если в столбце A нет данных и никакого форматирования.

Почему? Потому что .Columns.Rows и .Cells, если на то пошло) относительный до указанного диапазона. Например, если UsedRange равен B2:Z10, то Me.UsedRange.Columns("E") будет относиться к диапазону F2:F10.

Другая проблема в коде OP заключается в том, что она будет работать для любых изменений ячеек, в том числе в столбце A. Это вызовет ошибку, потому что смещение -1 из столбца A недействительно.

Итак, как исправить это? Как ответил jbarker2160, вы должны воспользоваться параметром Target, который сообщает вам, какие ячейки были изменены. Однако этот ответ оставляет несколько проблем.

  • Мы хотим, чтобы проверить колонке E = «Си» и Колонна D для «WR229», но мы не знаем, какой из них будет введен первый
  • Мы должны учитывать возможность того, что несколько ячеек сразу изменился, например, из-за копирования/вставки
  • мы должны обработать возможные ошибки и не отпуска События отключены
  • код Ор является чувствительно к регистру. Т.е. «CU» будет приниматься, когда «Cu» - нет. Это желаемое поведение? (Если это , удалить UCase$() «S из приведенной ниже коды)
  • Неявных в коде ОРА является то, что существует целый ряд больше волноводов, которые запрещены для Cu. Это остается нерассмотренным в коде ниже.

Этот код решает вышеуказанные проблемы

Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim rw As Range 

    On Error GoTo EH 
    Application.ScreenUpdating = False 
    Application.EnableEvents = False 

    For Each rw In Application.Intersect(_ 
     Target.EntireRow, Me.UsedRange.EntireRow.Columns("D:E")).Rows 

     If UCase$(rw.Cells(1, 2)) = "CU" And UCase$(rw.Cells(1, 1)) = "WR229" Then 
      MsgBox "Cu not permitted for WR229 or larger waveguide", _ 
       vbOKOnly, "Cu Alert" 
      rw.Cells(1, 2) = "Al" 
     End If 
    Next 
EH: 
    Application.ScreenUpdating = True 
    Application.EnableEvents = True 
End Sub 
+0

Еще лучшее решение. Я не знал, что EnableEvents может быть ложным. Спасибо, Крис. – jmaz

0

Изменить эту строку:

cell = "Al" 

Для этого:

cell.Value = "Al" 
1

Код

Private Sub Worksheet_change(ByVal target As Range) 
Application.ScreenUpdating = False 
Application.EnableEvents = False 

If target = "Cu" And target.offset(0, -1) = "WR229" Then 
    MsgBox "Cu not permitted for WR229 or larger waveguide", vbOKOnly, "Cu Alert" 
    target = "Al" 
End If 

Application.ScreenUpdating = True 
Application.EnableEvents = True 
End Sub 

Объяснение

Поскольку вы делаете этот цикл для каждого изменения, вы дон не нужно зацикливаться Всю колонку и использование target обойдется, используя свойство Value.

+0

Ответ aphoria был полезен, и это идет дальше. Спасибо, что помогли мне с лучшей практикой кодирования. – jmaz

+0

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

+0

Я отметил ответ Криса Нильсенса наиболее полезным. – jmaz