В практике разработки на платформе 1С:Предприятие 8 часто возникает задача изменить или дополнить аналитику (субконто) в бухгалтерских проводках непосредственно в момент проведения документа. Например, нам может потребоваться программно заполнить субконто «Партии» ссылкой на сам документ или подставить нужный договор в зависимости от условий. Рассмотрим, как это сделать правильно, избегая типичных ошибок новичков.
Часто начинающие разработчики пытаются использовать метод РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей() внутри процедуры ОбработкаПроведения. Проанализируем, почему этот подход не является оптимальным:
Движения. Создание отдельного набора записей приводит к лишним обращениям к базе данных.Набор.Записать() внутри транзакции проведения может вызвать конфликты блокировок или привести к тому, что изменения не будут согласованы с основной логикой проведения.Правильный путь — работа с коллекцией Движения текущего объекта.
Разберем основной алгоритм действий. Вместо того чтобы перечитывать данные из базы, мы обратимся к уже сформированным в памяти (или частично записанным) движениям документа. Посмотрим на пример кода, который обычно размещается в самом конце процедуры ОбработкаПроведения:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// ... здесь находится основной код формирования проводок ...
// Переходим к корректировке созданных движений
Для каждого Запись Из Движения.Хозрасчетный Цикл
// Проверяем, соответствует ли счет Дт или Кт нашему условию
Если Запись.СчетДт = ПланыСчетов.Хозрасчетный.ТоварыНаСкладах Тогда
// Устанавливаем субконто по виду характеристики
ВидСубкПартии = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Партии;
Запись.СубконтоДт[ВидСубкПартии] = ЭтотОбъект.Ссылка;
КонецЕсли;
КонецЦикла;
// Указываем платформе, что движения нужно записать
Движения.Хозрасчетный.Записывать = Истина;
КонецПроцедуры
В данном примере мы анализируем каждую проводку. Если дебет счета соответствует счету Товары на складах, мы находим субконто Партии и записываем в него ссылку на текущий документ. Это стандартный прием для реализации упрощенного партионного учета.
Рассмотрим подробнее несколько критически важных моментов, которые позволят сделать ваш код более отказоустойчивым.
1. Использование флага Записывать вместо метода Записать()
В коде выше мы использовали Движения.Хозрасчетный.Записывать = Истина;. Это предпочтительный способ. Платформа самостоятельно произведет запись всех движений в конце транзакции проведения. Если же вызвать метод Движения.Хозрасчетный.Записать() вручную, а после этого в коде возникнет ошибка и установится флаг Отказ = Истина, может возникнуть ситуация некорректного состояния данных или избыточной нагрузки на сервер БД.
2. Проверка наличия субконто на счете
Перед тем как обращаться к субконто по индексу, рекомендуется убедиться, что у данного счета вообще есть такой вид субконто. В противном случае система может выдать ошибку, если счет будет изменен в настройках учетной политики. Проанализируем безопасный вариант:
ВидСубкПартии = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Партии;
Если Запись.СчетДт.ВидыСубконто.Найти(ВидСубкПартии) <> Неопределено Тогда
Запись.СубконтоДт[ВидСубкПартии] = ЭтотОбъект.Ссылка;
КонецЕсли;
3. Метод Вставить() для инициализации субконто
Если вы не уверены, инициализировано ли субконто в записи, лучше использовать метод Вставить(). Он работает по принципу: если ключ (вид субконто) существует — значение обновится, если нет — добавится новая запись в коллекцию значений субконто для текущей строки проводки.
Запись.СубконтоДт.Вставить(ВидСубкПартии, ЭтотОбъект.Ссылка);
Выясним причину, по которой иногда корректировка в конце процедуры — не самый лучший вариант. Если документ сложный и формирует тысячи проводок, повторный цикл по всей коллекции Движения.Хозрасчетный может замедлить работу.
Посмотрим на альтернативные подходы:
Запись = Движения.Хозрасчетный.Добавить();.ОбработкаПроведения с аннотацией &После. Это позволит сохранить возможность легкого обновления программы.ЭтотОбъект.Ссылка при первом проведении нового документа уже существует, так как запись объекта в базу происходит непосредственно перед вызовом обработчика проведения в рамках одной транзакции. Однако, если вы работаете с какими-то специфическими внешними объектами, всегда проверяйте ссылку на Пустая().Таким образом, мы разобрали наиболее корректный и производительный способ изменения аналитики проводок. Используя коллекцию Движения и устанавливая флаг Записывать, вы гарантируете целостность данных и соответствие стандартам разработки 1С.