При разработке или доработке документов в конфигурациях 1С (особенно в типовых решениях на обычных формах, таких как УПП, УТ 10.3 или КА 1.1) разработчики часто сталкиваются с ситуацией: код проведения выполняется без ошибок, алгоритм расчета сумм отрабатывает корректно, но в самом регистре накопления движения не появляются. Разберем по шагам, почему возникает эта проблема и как ее правильно устранить.
Рассмотрим типовую схему, при которой движения формируются через выгрузку колонок и обращение к экспортным процедурам модуля набора записей регистра (например, ВыполнитьПриход()). В документе вызывается следующий код:
НаборДвижений = Движения.РасчетыСКонтрагентами;
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
СуммаВзаиморасчетов = СуммаВзаиморасчетовДляЗакрытия + ...;
СуммаУпр = СуммаУпрДляЗакрытия + ...;
Если СуммаВзаиморасчетов <> 0 ИЛИ СуммаУпр <> 0 Тогда
СтрокаДвижений = ТаблицаДвижений.Добавить();
СтрокаДвижений.РасчетыВозврат = Перечисления.РасчетыВозврат.Расчеты;
СтрокаДвижений.ДоговорКонтрагента = СтруктураШапкиДокумента.ДоговорКонтрагента;
СтрокаДвижений.Контрагент = СтруктураШапкиДокумента.Контрагент;
СтрокаДвижений.Организация = СтруктураШапкиДокумента.Организация;
СтрокаДвижений.Сделка = ЗаказПокупателя;
СтрокаДвижений.СуммаВзаиморасчетов = СуммаВзаиморасчетов;
СтрокаДвижений.СуммаУпр = СуммаУпр;
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
Движения.РасчетыСКонтрагентами.ВыполнитьПриход();
КонецЕсли;
При отладке видно, что таблица мТаблицаДвижений заполнена всеми необходимыми данными, а сам документ добавлен в список регистраторов регистра накопления. Однако после завершения проведения база данных остаётся без новых записей.
Платформа 1С при завершении транзакции проведения документа записывает только те наборы движений, у которых свойство Записывать установлено в значение Истина.
В приведенном алгоритме заполняется промежуточная переменная мТаблицаДвижений, а сама коллекция записей набора формируется уже внутри сервисной процедуры ОбщегоНазначения.ВыполнитьДвижениеПоРегистру(). Поскольку прямого обращения к методам коллекций (таким как Добавить()) в тексте самого модуля документа не происходило, платформа не установила признак модифицированности набора автоматическим образом.
Для исправления ситуации необходимо явно установить свойство Записывать = Истина в процедуре модуля набора записей регистра:
// Процедура в модуле набора записей регистра накопления
Процедура ВыполнитьПриход() Экспорт
ЭтотОбъект.Записывать = Истина;
ОбщегоНазначения.ВыполнитьДвижениеПоРегистру(ЭтотОбъект, ВидДвиженияНакопления.Приход);
КонецПроцедуры
После присвоения ЭтотОбъект.Записывать = Истина платформа получает сигнал о том, что данный набор необходимо сохранить в физическую таблицу базы данных при успешном завершении проведения.
Выясним, почему одинаковый код может работать для одного документа (например, Заказ покупателя) и не работать для вновь созданного документа (например, Изменение заказа покупателя).
Ответ кроется в свойствах метаданных конкретного документа в конфигураторе:
Записывать был явным образом взведен в коде.Если в новом документе свойство установлено в значение Записывать выбранные, а в коде проведения отсутствует строчка Движения.РасчетыСКонтрагентами.Записывать = Истина (или аналог внутри экспортной процедуры), движения записаны не будут.
Разберем основные правила, которые помогут избежать ошибок при формировании движений в регистрах накопления и сведений:
Движения.РасчетыСКонтрагентами.Записывать = Истина;
Движение = Движения.РасчетыСКонтрагентами.ДобавитьПриход();
Движение.Период = Дата;
Движение.Контрагент = Контрагент;
мТаблицаДвижений), обязательно убедитесь, что в экспортных процедурах (ВыполнитьПриход() / ВыполнитьРасход()) прописана установка ЭтотОбъект.Записывать = Истина.Движения.Записать() после выполнения записи автоматически сбрасывает флаг Записывать в Ложь для всех наборов. Если после этого в код добавляются новые движения, флаг потребуется установить повторно.