В практике сопровождения и разработки конфигураций на платформе 1С:Предприятие периодически возникает неприятная коллизия: документ получает статус «Проведен» (признак Проведен = Истина), однако в регистрах накопления, бухгалтерии или сведений нет ни одной связанной записи. Ситуация критична тем, что система считает операцию завершенной, но в управленческих и регламентированных отчетах данные не отражаются. Разберем по шагам причины такого поведения платформы и конфигурации, выясним, почему визуальные клиентские проверки опасны, и научимся реализовывать надежный серверный контроль формирования движений.
Проанализируем типовые технические и логические предпосылки, из-за которых документ может остаться пустым по регистрам:
Попытка ... Исключение. Если в алгоритме проведения или подписке на событие допущена ошибка, перехваченная конструкцией Исключение, и при этом разработчик не установил флаг Отказ = Истина, платформа не прерывает операцию. В соответствии со свойством документа «Удаление движений» старые записи удаляются в начале транзакции, а новые не создаются. В результате транзакция успешно фиксируется, оставляя документ проведенным, но пустым.ТоварыВРезервеНаСкладах жестко зависят от комбинации реквизитов: вида операции, признака размещения/резервирования, статуса документа и способа списания. Если хотя бы один реквизит в строке табличной части или шапке заполнен нетиповым значением или очищен, условие выборки данных для движений возвращает пустой результат.Проведен = Истина, но вызывают метод Записать(РежимЗаписиДокумента.Запись) вместо РежимЗаписиДокумента.Проведение. В этом случае документ помечается проведенным, но процедура ОбработкаПроведения платформой даже не вызывается.Распространенной ошибкой начинающих разработчиков является попытка встроить проверку движений в события формы документа, например, в ПослеЗаписи:
Если ЭтотОбъект.Движения.ТоварыВРезервеНаСкладах.Количество() = 0 Тогда
Предупреждение("Нет движений");
КонецЕсли;
Рассмотрим, почему данный подход считается грубой архитектурной ошибкой:
Предупреждение просто выводит модальное или блокирующее окно на экран пользователя, но транзакция проведения к моменту выполнения события ПослеЗаписи уже зафиксирована в базе данных. Документ остается проведенным.Предупреждение, Вопрос, ОткрытьФорму) на стороне сервера, в сеансах без интерфейса или при фоновом групповом перепроведении документов система выбросит критическое исключение, и весь фоновый процесс аварийно завершится.Правильное место для валидации результатов проведения — процедура ОбработкаПроведения модуля самого документа либо специализированная подписка на событие ОбработкаПроведения. Контроль должен выполняться после того, как все движения сформированы и подготовлены к записи.
Для прерывания транзакции используется стандартный параметр Отказ = Истина. Для вывода информации пользователю следует применять платформенный объект СообщениеПользователю, который полностью безопасен для серверного контекста и фоновых заданий. Разберем практический пример:
// В модуле объекта документа "ЗаказПокупателя"
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// 1. Формирование движений по регистрам документа
// Движения.ТоварыВРезервеНаСкладах.Записывать = Истина;
// ... Выполнение типовых запросов и заполнение наборов записей ...
// Если используется явная запись наборов в коде:
Движения.ТоварыВРезервеНаСкладах.Записать();
// 2. Контроль наличия движений
Если Движения.ТоварыВРезервеНаСкладах.Количество() = 0 Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Документ не сформировал движений по резервам товаров! Проведение отменено.";
Сообщение.Поле = "Товары";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
КонецЕсли;
КонецПроцедуры
Посмотрим на особенности этого решения:
Отказ = Истина инициирует полный откат текущей транзакции. Документ не получит статус проведенного и не сохранит некорректное состояние.СообщениеПользователю корректно накапливает сообщения в контексте сервера и передает их на клиент при завершении вызова, не вызывая сбоев при пакетной обработке или регламентных заданиях.УстановитьДанные и свойства Поле подсвечивает проблемную табличную часть или реквизит непосредственно в форме документа.Если разовое непроведение или отсутствие движений повторяется спонтанно, выполним комплекс диагностических мероприятий:
%AppData%\1C\1Cv8 и %LocalAppData%\1C\1Cv8), а при клиент-серверном варианте выполним регламентный перезапуск службы сервера 1С:Предприятия с очисткой сеансовых данных.Транзакция.Начало, Транзакция.Отмена и сообщения об ошибках от имени фоновых процессов и интеграционных учетных записей.