Как правильно добавить дополнительные движения по регистру при проведении документа в 1С

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

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

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

Почему ручной набор записей не сохраняется при проведении

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

Проанализируем ситуацию и поймем, что происходит в этот момент на стороне платформы:

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

Кроме того, если добавление записей происходит до вызова типовых общих модулей списания (например, УправлениеДенежнымиСредствами.ПровестиСписаниеДенежныхСредствУпр), типовой код может полностью очистить коллекцию Движения перед формированием собственных записей.

Решение 1: Прямое добавление строк в коллекцию Движения

Наиболее корректный способ — заполнять встроенную коллекцию Движения документа строго после выполнения типовых процедур и механизмов проведения. Явно вызывать метод Записать() у регистра или набора записей при этом не требуется.

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


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

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

Важные правила при работе с коллекцией Движения:

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

Решение 2: Передача данных в структуру таблиц платежей

В типовых решениях 1С (таких как Управление торговлей 10.3, Комплексная автоматизация или Управление производственным предприятием) проведение документов по кассе строится на выгрузке таблиц платежей в промежуточные структуры.

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

← На главную