Как получить и прочитать проводки налогового учета при проведении документа в 1С:УПП 1.3?

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

Разработчики при кастомизации типовых конфигураций (особенно таких сложных, как 1С:Управление производственным предприятием ред. 1.3) часто сталкиваются с неочевидным поведением платформы «1С:Предприятие 8». Одна из классических проблем — попытка получить только что сформированные движения (например, проводки налогового или бухгалтерского учета) в подписке на событие ОбработкаПроведения.

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

Выясняем причину: почему движения кажутся «пустыми»?

Для начала проанализируем ситуацию, с которой столкнулся автор темы. При отладке подписки на событие проведения документа (например, «Реализация товаров и услуг») обращение к коллекции движений напрямую через источник:


// Этот код вернет пустое количество записей, если движения уже записаны в СУБД
КоличествоПроводок = Источник.Движения.Налоговый.Количество();

показывает, что коллекция пуста. Тем не менее, после завершения проведения документа все проводки налогового учета (НУ) успешно отображаются в интерфейсе программы и регистрируются в базе данных.

Дело в особенностях жизненного цикла транзакции проведения документа в платформе 1С:

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

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

Решение проблемы: как правильно прочитать проводки

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

Способ 1. Создание отдельного объекта набора записей (решение автора темы)

Этот способ является наиболее надежным и безопасным. Мы создаем независимый объект набора записей регистра бухгалтерии, устанавливаем отбор по нашему документу-регистратору и считываем данные из базы данных. Посмотрим на пример кода:


// Создаем пустой набор записей регистра бухгалтерии "Налоговый"
ПроводкиНУ = РегистрыБухгалтерии.Налоговый.СоздатьНаборЗаписей();

// Устанавливаем жесткий отбор по регистратору (текущему документу)
ПроводкиНУ.Отбор.Регистратор.Установить(Источник.Ссылка);

// Считываем данные из базы данных в рамках текущей транзакции
ПроводкиНУ.Прочитать();

// Теперь мы можем работать с проводками налогового учета
Для Каждого Проводка Из ПроводкиНУ Цикл
    // Выполняем анализ или обработку проводки
    Сообщить("Счет Дт: " + Проводка.СчетДт + ", Счет Кт: " + Проводка.СчетКт + ", Сумма НУ: " + Проводка.Сумма);
КонецЦикла;

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

Способ 2. Использование метода Прочитать() непосредственно у коллекции документа

Рассмотрим более лаконичный способ, который избавляет нас от необходимости вручную создавать новый объект набора записей. Мы можем заставить саму коллекцию движений внутри источника перечитать данные из базы:


// Принудительно считываем движения из СУБД в существующую коллекцию документа
Источник.Движения.Налоговый.Прочитать();

// Проверяем, появились ли записи
Если Источник.Движения.Налоговый.Количество() > 0 Тогда
    Для Каждого Движение Из Источник.Движения.Налоговый Цикл
        // Ваши действия с проводками налогового учета
    КонецЦикла;
КонецЕсли;

Этот способ удобен тем, что мы продолжаем работать со штатной коллекцией документа Источник.Движения.

Архитектурные нюансы УПП 1.3: Партионный учет против РАУЗ

При работе с движениями налогового и бухгалтерского учета в конфигурации УПП 1.3 критически важно понимать, в каком режиме учета затрат работает информационная база. От этого напрямую зависит, в какой момент и какими механизмами формируются проводки.

Вариант А: Использование партионного учета

Если в учетной политике организации включен традиционный партионный учет:

В этом режиме при проведении документа проводки НУ генерируются сразу же, и их можно прочитать методами, описанными выше.

Вариант Б: Использование РАУЗ (Расширенная аналитика учета затрат)

Если в системе используется режим РАУЗ, логика кардинально меняется:

Важное предупреждение: Если у вас включен режим РАУЗ, попытка прочитать проводки по себестоимости в налоговом учете сразу после проведения реализации не принесет никаких результатов, так как этих проводок физически еще не существует в базе данных.

Опасности модификации проводок в подписках на проведение

Если перед вами стоит задача не просто проанализировать, а изменить или дописать проводки налогового учета, использовать для этого подписку на событие ОбработкаПроведения крайне не рекомендуется по следующим причинам:

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

Если вам гарантированно нужно вмешаться в процесс формирования проводок, рассмотрите альтернативное и более надежное решение — перехват записи в модуле набора записей самого регистра бухгалтерии («Налоговый» или «Хозрасчетный») в предопределенном обработчике ПередЗаписью(). Пример такой реализации:


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

Используя этот подход, вы всегда будете работать с финальным и полным набором проводок, который документ подготовил к записи в базу данных, независимо от того, партионный учет используется в системе или РАУЗ.

← На главную