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