Как программно скорректировать субконто в движениях документа при его проведении?

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает задача изменить или дополнить аналитику (субконто) в бухгалтерских проводках непосредственно в момент проведения документа. Например, нам может потребоваться программно заполнить субконто «Партии» ссылкой на сам документ или подставить нужный договор в зависимости от условий. Рассмотрим, как это сделать правильно, избегая типичных ошибок новичков.

Анализ типичной ошибки: почему нельзя создавать новый набор записей?

Часто начинающие разработчики пытаются использовать метод РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей() внутри процедуры ОбработкаПроведения. Проанализируем, почему этот подход не является оптимальным:

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

Правильный путь — работа с коллекцией Движения текущего объекта.

Решение: корректировка через коллекцию Движения

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


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    
    // ... здесь находится основной код формирования проводок ...

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

    // Указываем платформе, что движения нужно записать
    Движения.Хозрасчетный.Записывать = Истина;

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

В данном примере мы анализируем каждую проводку. Если дебет счета соответствует счету Товары на складах, мы находим субконто Партии и записываем в него ссылку на текущий документ. Это стандартный прием для реализации упрощенного партионного учета.

Разбор важных нюансов при работе с субконто

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

1. Использование флага Записывать вместо метода Записать()

В коде выше мы использовали Движения.Хозрасчетный.Записывать = Истина;. Это предпочтительный способ. Платформа самостоятельно произведет запись всех движений в конце транзакции проведения. Если же вызвать метод Движения.Хозрасчетный.Записать() вручную, а после этого в коде возникнет ошибка и установится флаг Отказ = Истина, может возникнуть ситуация некорректного состояния данных или избыточной нагрузки на сервер БД.

2. Проверка наличия субконто на счете

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


ВидСубкПартии = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Партии;

Если Запись.СчетДт.ВидыСубконто.Найти(ВидСубкПартии) <> Неопределено Тогда
    Запись.СубконтоДт[ВидСубкПартии] = ЭтотОбъект.Ссылка;
КонецЕсли;

3. Метод Вставить() для инициализации субконто

Если вы не уверены, инициализировано ли субконто в записи, лучше использовать метод Вставить(). Он работает по принципу: если ключ (вид субконто) существует — значение обновится, если нет — добавится новая запись в коллекцию значений субконто для текущей строки проводки.

Запись.СубконтоДт.Вставить(ВидСубкПартии, ЭтотОбъект.Ссылка);

Методологические рекомендации

Выясним причину, по которой иногда корректировка в конце процедуры — не самый лучший вариант. Если документ сложный и формирует тысячи проводок, повторный цикл по всей коллекции Движения.Хозрасчетный может замедлить работу.

Посмотрим на альтернативные подходы:

Таким образом, мы разобрали наиболее корректный и производительный способ изменения аналитики проводок. Используя коллекцию Движения и устанавливая флаг Записывать, вы гарантируете целостность данных и соответствие стандартам разработки 1С.

← На главную