При разработке и доработке документов в 1С часто возникает задача условной проверки данных. Например, требование сделать реквизит табличной части обязательным для заполнения только при выполнении определенного условия в этой же строке (скажем, если заполнено поле ВремяНачала, то должно быть обязательно заполнено поле Получил).
В этой статье мы разберем типовые ошибки, которые совершают разработчики при попытке реализовать такую проверку, и проанализируем правильные способы решения задачи.
Разберем ситуации, с которыми часто сталкиваются начинающие программисты 1С при попытке проверить реквизиты табличной части:
ЗначениеЗаполнено(). Если написать ЗначениеЗаполнено("ВремяНачала"), то функция проверит заполнение текстовой строки "ВремяНачала", а не самого реквизита. Так как строка не пустая, функция всегда будет возвращать Истина.ТекСтрока.ВремяНачала = Истина вернет Ложь, если реквизит имеет тип Дата, СправочникСсылка или любой другой, отличный от Булево.Для того чтобы выполнить проверку каждой строки табличной части в зависимости от значений ее реквизитов, необходимо перебрать строки табличной части и применить функцию ЗначениеЗаполнено() непосредственно к свойствам текущей строки.
Рассмотрим пример кода, который помещается в модуль объекта в событие ПередЗаписью или специальную процедуру проверки перед проведением:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Для Каждого ТекСтрока Из ТехнологическиеОперации Цикл
// Проверяем: если ВремяНачала заполнено, а Получил не заполнено
Если ЗначениеЗаполнено(ТекСтрока.ВремяНачала) И Не ЗначениеЗаполнено(ТекСтрока.Получил) Тогда
Сообщить("В строке № " + ТекСтрока.НомерСтроки + " не заполнен реквизит 'Получил'!");
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Разберем подробнее, как работает этот код:
Для Каждого ... Из по всем строкам табличной части ТехнологическиеОперации.ТекСтрока.ВремяНачала и ТекСтрока.Получил.ЗначениеЗаполнено() корректно проверяет заполнение для любых типов данных (пустая дата, незаполненная ссылка, пустая строка и т. д.).Отказ = Истина, блокируя запись или проведение документа.Если разработка ведется на управляемых формах или с использованием библиотеки стандартных подсистем (БСП), вместо обычной процедуры Сообщить() рекомендуется использовать объект СообщениеПользователю. Это позволит не просто вывести текст ошибки, но и подсветить конкретную ячейку в табличной части.
Посмотрим на пример реализации в событии ОбработкаПроверкиЗаполнения модуля объекта:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Для Индекс = 0 По ТехнологическиеОперации.Количество() - 1 Цикл
ТекСтрока = ТехнологическиеОперации[Индекс];
Если ЗначениеЗаполнено(ТекСтрока.ВремяНачала) И Не ЗначениеЗаполнено(ТекСтрока.Получил) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не заполнен реквизит 'Получил' в строке " + (Индекс + 1);
Сообщение.Поле = "Объект.ТехнологическиеОперации[" + Индекс + "].Получил";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
При таком подходе пользователь сможет нажать на сообщение об ошибке в окне программы, и курсор автоматически перейдет к незаполненной ячейке табличной части.