Почему при добавлении проводки в Закрытие месяца удаляются типовые движения и как это исправить?

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

При доработке алгоритмов проведения документов разработчики нередко сталкиваются с ситуацией, когда добавление собственной проводки в коллекцию Движения.Хозрасчетный приводит к полной очистке всех типовых проводок документа. Особенно ярко данное поведение проявляется в регламентных операциях конфигурации «Бухгалтерия предприятия» при закрытии счетов затрат (20, 23, 25, 26). Разберем по шагам, почему возникает эта ошибка и какие существуют корректные способы добавления движений в регламентные документы.

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

Проанализируем ситуацию, возникающую при стандартном обращении к коллекции движений. В типовых документах проведения проводки формируются непосредственно в объекте Движения.Хозрасчетный. Как только мы обращаемся к методу Добавить(), платформа неявно выставляет свойство Движения.Хозрасчетный.Записывать = Истина. При завершении транзакции проведения платформа автоматически выполняет запись набора с режимом замещения по умолчанию (Замещать = Истина).

В регламентных операциях закрытия месяца логика формирования проводок устроена значительно сложнее, чем в обычных первичных документах:

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

Способ 1. Использование подписки на событие проведения

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

Рассмотрим порядок реализации данного решения:

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

Посмотрим на пример программного кода в общем модуле подписки:


Процедура ДобавитьДвиженияПриПроведении(Источник, Отказ, РежимПроведения) Экспорт

    // Проверяем вид регламентной операции, чтобы код срабатывал только для закрытия счетов затрат
    Если Источник.ВидОперации <> Перечисления.ВидыРегламентныхОпераций.ЗакрытиеСчетов20_23_25_26 Тогда
        Возврат;
    КонецЕсли;

    // Считываем движения, уже сформированные типовым кодом
    НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Регистратор.Установить(Источник.Ссылка);
    НаборЗаписей.Прочитать();

    // Добавляем требуемую проводку
    НоваяЗапись = НаборЗаписей.Добавить();
    НоваяЗапись.Период = Источник.Дата;
    НоваяЗапись.Регистратор = Источник.Ссылка;
    НоваяЗапись.Организация = Источник.Организация;
    
    НоваяЗапись.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("41.01");
    НоваяЗапись.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01");
    
    НоваяЗапись.Сумма = 1000;
    НоваяЗапись.Содержание = "Корректировка стоимости (кастомная)";

    // Записываем обновленный набор целиком с замещением
    НаборЗаписей.Записать(Истина);

    // Отключаем повторную автозапись стандартного набора движений документа
    Источник.Движения.Хозрасчетный.Записывать = Ложь;

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

Способ 2. Управление записью без замещения в модуле документа

Если внесение изменений производится непосредственно внутри модуля документа или типового общего модуля процедуры ЗакрытиеСчетов20_23_25_26, необходимо корректно управлять флагами записи набора. Разберем по шагам, как предотвратить удаление существующих проводок:

  1. Формируем проводку в объекте Движения.Хозрасчетный.
  2. Вызываем принудительную запись с параметром Ложь (без замещения существующих записей).
  3. Обязательно сбрасываем признак автоматической записи платформой, чтобы избежать перезаписи при выходе из процедуры.

Посмотрим на пример реализации:


// Создаем движение непосредственно перед завершением процедуры закрытия
Движение = Движения.Хозрасчетный.Добавить();
Движение.Период = ЭтотОбъект.Дата;
Движение.Организация = ЭтотОбъект.Организация;
Движение.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("41.01");
Движение.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01");
Движение.Сумма = СуммаПроводки;

// Записываем порцию проводок в базу данных БЕЗ замещения ранее записанных
Движения.Хозрасчетный.Записать(Ложь);

// Запрещаем платформе автоматически перезаписывать набор при выходе из процедуры
Движения.Хозрасчетный.Записывать = Ложь;

Альтернативные методические решения

Внесение прямых проводок вида Дт 41.01 Кт 20.01 в процедуру закрытия счетов несет серьезные риски: может нарушиться порядок распределения прямых расходов, возникнуть зависшее сальдо по счету 20 или образоваться неверная база для расчета в следующих месяцах. Рассмотрим типовые альтернативы, исключающие вмешательство в программный код закрытия:

  1. Документ «Операция (бухгалтерский и налоговый учет)». Наиболее безопасный путь для отражения нетиповой проводки. Ручная операция вводится концом месяца, не затрагивает типовой механизм закрытия и легко контролируется главным бухгалтером.
  2. Документ «Корректировка записей регистров». Позволяет дополнить движения по регистру бухгалтерии без изменения типовых процедур расчета и проведения.
  3. Отражение через документы выпуска. Операция выпуска из производства на склад товаров штатно отражается документами Отчет производства за смену или Акт об оказании производственных услуг, после чего регламентная процедура закрытия месяца автоматически скорректирует их стоимость до фактической себестоимости.
← На главную