Как запретить запись бизнес-процесса в 1С при несовпадении итогов в табличных частях

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки бизнес-логики в 1С часто возникает задача контроля целостности данных. Типичный пример: сумма по табличной части Продукция должна строго соответствовать сумме по табличной части Оплата. Если пользователь нарушает это правило, система должна заблокировать запись и наглядно сообщить об ошибке. Рассмотрим, как правильно реализовать такую проверку, какие обработчики событий использовать и как избежать распространенных ошибок при настройке реквизитов.

Выбор места для проверки: Модуль объекта против Модуля формы

Прежде всего, разберем, где именно стоит писать код проверки. Программисты часто начинают писать код в процедуре ПриЗаписиНаСервере модуля формы, однако это не самое удачное место для жестких ограничений. Проанализируем два основных варианта:

  1. ПередЗаписью (в модуле объекта): Это наиболее надежное место. Проверка сработает всегда: и при записи из формы, и при программном создании объекта, и при загрузке данных. Если мы установим Отказ = Истина, транзакция записи будет отменена.
  2. ОбработкаПроверкиЗаполнения (в модуле объекта): Это специализированный стандартный механизм платформы. Он запускается перед записью (если включена проверка) и позволяет не просто выдать текст, а подсветить конкретное поле, в котором допущена ошибка.

Рассмотрим реализацию через ПередЗаписью в модуле объекта, так как это дает полный контроль над логикой.

Реализация проверки в процедуре ПередЗаписью

Для того чтобы не дать записать объект, нам необходимо рассчитать итоги по колонкам и сравнить их. Если они не равны, мы устанавливаем параметр Отказ в значение Истина и выводим сообщение пользователю.

Проанализируем пример кода:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Получаем итоги по табличным частям
    ИтогСуммаПродукция = Продукция.Итог("Сумма");
    ИтогСуммаОплата = Оплата.Итог("Сумма");
    
    // Сравниваем значения
    Если ИтогСуммаПродукция <> ИтогСуммаОплата Тогда
        
        Отказ = Истина; // Блокируем запись
        
        // Формируем понятное сообщение для пользователя
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Ошибка! Сумма по продукции (" + ИтогСуммаПродукция + 
                          ") не совпадает с суммой оплаты (" + ИтогСуммаОплата + ").";
        Сообщение.Сообщить();
        
    КонецЕсли;

КонецПроцедуры

Важный нюанс: При сравнении чисел с плавающей точкой (копейки) иногда могут возникать микроскопические погрешности. Профессиональным подходом считается проверка разницы с учетом точности. Разберем, как это сделать:


Если Абс(ИтогСуммаПродукция - ИтогСуммаОплата) > 0.01 Тогда
    // Сообщаем об ошибке, так как разница больше одной копейки
КонецЕсли;

Использование механизма ОбработкаПроверкиЗаполнения

Если мы хотим, чтобы 1С сама управляла выводом ошибок в стандартном стиле, лучше использовать событие ОбработкаПроверкиЗаполнения. Этот метод позволяет привязать ошибку к конкретной таблице на форме.

Выясним, как это выглядит на практике:


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    
    ИтогПродукция = Продукция.Итог("Сумма");
    ИтогОплата = Оплата.Итог("Сумма");
    
    Если ИтогПродукция <> ИтогОплата Тогда
        
        Отказ = Истина;
        
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Суммы в таблицах Продукция и Оплата должны быть равны!";
        Сообщение.Поле = "Объект.Оплата"; // Подсветит таблицу Оплата
        Сообщение.УстановитьДанные(ЭтотОбъект);
        Сообщение.Сообщить();
        
    КонецЕсли;
    
КонецПроцедуры

Решение проблемы с "фантомными" ошибками заполнения

Иногда программисты сталкиваются с ситуацией, когда реквизит был удален или его проверка была отключена, но система все равно выдает ошибку: "Поле 'Желаемая дата получения' не заполнено". Это происходит потому, что настройки проверки могут храниться в нескольких местах.

Проанализируем шаги для исправления этой ситуации:

  1. Свойства реквизита в объекте: Нужно открыть дерево метаданных (например, Бизнес-процесс), найти реквизит и проверить свойство Проверка заполнения. Оно должно иметь значение Не проверять.
  2. Программная проверка: Проверьте модуль объекта, процедуру ОбработкаПроверкиЗаполнения. Возможно, этот реквизит добавляется в массив ПроверяемыеРеквизиты принудительно кодом.
  3. Кэш конфигурации: Если реквизит восстановлен, а ошибка осталась, возможно, дело в кэше платформы. Попробуйте обновить конфигурацию базы данных или запустить сеанс с очисткой кэша.

Улучшение пользовательского интерфейса (UX)

Чтобы пользователь не получал ошибку только в момент нажатия кнопки "Записать", мы можем использовать Условное оформление формы. Рассмотрим этот прием подробнее:

Мы можем настроить форму так, чтобы поле с итогом подсвечивалось красным цветом сразу, как только суммы перестают совпадать. Для этого в свойствах формы находим "Условное оформление", создаем новое правило: если Объект.Продукция.ИтогСумма (созданный как реквизит формы для визуализации) не равен Объект.Оплата.ИтогСумма, то цвет текста итогов становится красным. Это отличный способ профилактики ошибок до того, как сработает жесткая блокировка записи.

Таким образом, комбинируя надежную проверку в ПередЗаписью модуля объекта и визуальные подсказки на форме, мы создаем стабильную и удобную систему контроля данных в 1С.

← На главную