Страница 2 из 5

Re: Проверка на заполнение.

Добавлено: 06 июл 2007, 01:06
Asya
Aent, спасибо

Код: Выделить всё

Private Sub Worksheet_Change(ByVal Target As Range)
flag = 0
If Target.Row <> 1 Then
  For j = 1 To 7 Step 3
  If Cells(Target.Row - 1, j) = "" Then
  flag = 1
  End If
  Next j
 If flag = 1 Then
 Application.EnableEvents = False
 Target.Value = ""
 Application.EnableEvents = True
 MsgBox ("Заполните ячейки в столбцах 1 4 7 ")
 End If
End If
End Sub
Вот так все ок :) (цикл с шагом, чтобы не писать лишних строк)

Re: Проверка на заполнение.

Добавлено: 06 июл 2007, 01:23
Asya
Сообщения наперегонки :) )))))) Но цикл лучше с шагом :) ))

Re: Проверка на заполнение.

Добавлено: 06 июл 2007, 20:17
Aent
&quot писал(а):Но цикл лучше с шагом
А почему бы вместо цикла не написать

Код: Выделить всё

k = target.row - 1
if Len(cells(k,1)) = 0 or Len(cells(k,4)) = 0 or Len(cells(k,7)) = 0 then 
     Application.EnableEvents = False
     Target.ClearContents
     Application.EnableEvents = True
     MsgBox "Заполните ячейки в столбцах 1 4 7 " 'Скобки не нужны! Здесь это оператор а не функция!
end if
короче, быстрее ;) и прозрачнее.

Re: Проверка на заполнение.

Добавлено: 06 июл 2007, 23:47
Asya
Да, так вообще супер :) ) Краткость сестра таланта.
И чего Вы сразу все это не предложили, даете нам возможность подумать самостоятельно? :p

Re: Проверка на заполнение.

Добавлено: 07 июл 2007, 00:40
Aent
&quot писал(а):даете нам возможность подумать самостоятельно?
Именно так ;)
А то топики будут слишком короткими :)

Re: Проверка на заполнение.

Добавлено: 08 июл 2007, 16:30
AlexZZZ
&quot писал(а):А то топики будут слишком короткими
Не волнуйтесь, Aent, не будут :) На самом деле, в моей задаче есть ещё одно условие: Если в строке заполнена ячейка 9 (например, сумма платежа), то должна обязательно заполнена ячейка 8 (назначение платежа) и 10 (валюта). Правда, имея перед глазами такой замечательный пример, тут я сам допёр, что нужно добавить.

Код: Выделить всё

Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
k = Target.Row - 1
If Len(Cells(k, 1)) = 0 Or Len(Cells(k, 4)) = 0 Or Len(Cells(k, 7)) = 0 Then
     Target.ClearContents
MsgBox "Заполните ячейки в столбцах 1 4 7 " 
End If
If Len(Cells(k, 9)) <> 0 And (Len(Cells(k, 8)) = 0 Or Len(Cells(k, 10)) = 0) Then
     Target.ClearContents
     MsgBox "Заполните ячейки в столбцах 8 и 10"
End If
Application.EnableEvents = True
End Sub
Вроде. проще уже некуда, но если будут предложения по оптимизации кода, буду благодарен! С познавательной целью это очень полезно.
P.S.: А Вы, Asya, оказывается, не только умница, но ещё и красавица! ;)

Re: Проверка на заполнение.

Добавлено: 08 июл 2007, 17:01
Aent
1.Отключать обработку событий достаточно один раз при входе в процедуру.
Cоответственно, включаем - перед выходом.
2.Кроме того, приведённый вами код срабатывает при изменении любой ячейки.
Наверное это не лучшее решение....
Рекомендую проверять Target.column для принятия решения о дальнейших проверках....

Re: Проверка на заполнение.

Добавлено: 08 июл 2007, 17:20
AlexZZZ
&quot писал(а):Отключать обработку событий достаточно один раз при входе в процедуру.
Спасибо за замечание, поправил!
&quot писал(а):Кроме того, приведённый вами код срабатывает при изменении любой ячейки
В данном случае это как раз хорошо, чтобы пользователь не оставлял пустых строк, а заполнял их последовательно.
Правда, ошибку нашёл в своей логике: забыл скобки поставить:

Код: Выделить всё

If Len(Cells(k, 9)) <> 0 And (Len(Cells(k, 8)) = 0 Or Len(Cells(k, 10)) = 0) Then
Сейчас отредактирую.

Re: Проверка на заполнение.

Добавлено: 08 июл 2007, 19:27
Aent
&quot писал(а):В данном случае это как раз хорошо, чтобы пользователь не оставлял пустых строк, а заполнял их последовательно
Я имел в виду что обработчик будет вызываться при заполнении ячеек в 8 и 10 и т.п колонках.
Это не эффективно.
Условие можно переписать так

Код: Выделить всё

if Len(Cells(k,9)) > 0 And Len(Cells(k,8)) *Len(Cells(k,10)) = 0 then

Re: Проверка на заполнение.

Добавлено: 08 июл 2007, 20:58
AlexZZZ
&quot писал(а):Я имел в виду что обработчик будет вызываться при заполнении ячеек в 8 и 10 и т.п колонках.
Ваша строчка изящнее, но разве логически это не тоже самое? Или Вы имеете в виду код до того как я исправил ошибку со скобками?

Решил ещё сделать кнопку проверки правильности заполнения последней записи (по маркеру - непустой ячейке второго столбца), но кнопка почему-то работает только, если находится на "листе1". А мне нужно, чтобы кнопка находилась на "листе2", а проверяла "лист1"! Помогите, пожалуйста, найти ошибку в логике!

Код: Выделить всё

Private Sub CommandButton1_Click()
Application.EnableEvents = False
Worksheets("Лист1").Select
Dim r, k As Integer
For r = 2 To 200 ' проверим первые 200 строк
k = r - 1

' находим строку с пустой ячейкой второго столбца и непустой ячейкой предыдущей строки того же столбца
If Len(Cells(r, 2)) = 0 And Len(Cells(k, 2)) <> 0 Then

'в предыдущей строке проверяем условие на заполнение ячеек
If Len(Cells(k, 1)) = 0 Or Len(Cells(k, 4)) = 0 Or Len(Cells(k, 7)) = 0 Then
   MsgBox "Заполните ячейки в столбцах 1 4 7 " & "в строке " & k
   GoTo lblEnd: 'конец процедуры
   End If
if Len(Cells(k,9)) > 0 And Len(Cells(k,8)) *Len(Cells(k,10)) = 0  Then
     MsgBox "Заполните ячейки в столбцах 8 и 10 " & "в строке " & k
    GoTo lblEnd: 'конец процедуры
End If
End If
Next

lblMessage: ' если ни одно из условий не верно
MsgBox "Всё заполнено верно!"
lblEnd:
Application.EnableEvents = True
End Sub