При разработке на платформе 1С:Предприятие начинающие разработчики часто сталкиваются с ситуацией, когда логика, успешно работающая в интерфейсе, «игнорируется» системой при выполнении групповых операций. Давайте разберем, почему процедура ПередЗаписью в модуле формы не подходит для автоматического пересчета табличных частей при групповом перепроведении, и как реализовать это решение правильно.
Основная проблема заключается в архитектурном разделении клиентской и серверной логики. Когда вы открываете документ в режиме Предприятие, работает модуль формы. Все процедуры, написанные в нем, привязаны к интерактивному взаимодействию пользователя с элементами интерфейса (кнопки, поля ввода, изменение данных в табличной части).
Когда вы запускаете групповое перепроведение (например, через обработку «Проведение документов» или групповую обработку справочников и документов), система работает с объектами базы данных напрямую. В этот момент формы документов не открываются, следовательно, модули форм не инициализируются, и код внутри них физически не может быть выполнен. Это не ошибка платформы, а принцип работы серверного контекста.
Для того чтобы пересчет выполнялся всегда — и при ручном проведении пользователем, и при пакетных операциях, — логику необходимо перенести из модуля формы в модуль объекта. Рассмотрим два основных пути реализации:
Это самое надежное место для изменения данных документа перед его сохранением в базу. В модуле объекта вам уже не доступны элементы формы, такие как Элементы.ТабличнаяЧасть.ТекущиеДанные. Вместо этого вы работаете напрямую с коллекцией объекта.
Разберем пример реализации:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем, нужно ли выполнять пересчет
Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
Для Каждого СтрокаТЧ Из ЭтотОбъект.Товары Цикл
// Выполняем расчет себестоимости или иного показателя
СтрокаТЧ.СуммаСебестоимости = СтрокаТЧ.Количество * СтрокаТЧ.ЦенаЗакупки;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Важные рекомендации:
РежимЗаписи, чтобы пересчет происходил только в нужных случаях.Если данные, которые вы хотите пересчитать, нужны исключительно для формирования проводок или движений по регистрам, лучше не менять исходные данные в табличной части, а рассчитать их «на лету» в ОбработкаПроведения.
Это считается более «чистым» решением, так как не меняет состояние объекта в базе данных, а лишь формирует актуальный результат для движений. Такой подход избавляет от проблемы рассинхронизации, когда данные в табличной части документа остаются «старой версией», а в регистрах уже другие цифры.
Проанализируем архитектурную сторону вопроса. Хранение себестоимости или других расчетных показателей прямо в табличной части документа (в реквизитах ТЧ) — это критически уязвимое место. Если изменится первичный документ, по которому рассчитывалась стоимость, значение в текущем документе останется старым. В итоге данные в отчетах будут недостоверными до тех пор, пока вы принудительно не перепроведете все документы за период.
Как сделать лучше:
регистры накопления для хранения себестоимости.запросы или вычисляемые поля, которые берут данные из регистров в момент открытия документа.Подводя итог: всегда помните, что любой код, влияющий на структуру данных или расчеты, должен располагаться в серверных модулях (модуле объекта или модуле менеджера), а не в модуле формы, если вы хотите обеспечить стабильность работы системы при любых способах проведения документов.