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