Как программно заполнить субконто в проводках регистра бухгалтерии 1С?

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

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

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

Выясняем причину: почему субконто сбрасывается в "Неопределено"?

Для начала разберем природу субконто в платформе 1С. В регистре бухгалтерии субконто представляют собой коллекцию значений с составным типом данных, определяемым планом видов характеристик (обычно это ВидыСубконтоХозрасчетные).

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

Аналогичные тройки колонок существуют и для кредитовой стороны (ВидСубконтоКт1, СубконтоКт1 и т.д.).

Главная ошибка начинающих разработчиков заключается в попытке заполнить только значение аналитики, например, написать ЗаписьБУ.СубконтоКт2 = СсылкаНаДоговор. Поскольку колонка ВидСубконтоКт2 остается пустой, платформа не знает, к какому типу из сотен возможных в характеристике нужно привести записываемое значение. Происходит конфликт типов, и платформа сбрасывает значение колонки в дефолтное состояние — Неопределено.

Ниже мы подробно рассмотрим четыре практических способа решения этой задачи.

Способ 1. Явное заполнение видов и значений субконто в таблице значений (Решение автора темы)

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

Рассмотрим пример кода, к которому пришел автор темы в ходе обсуждения:


Процедура КЗ_ОтражениеСписаниеОС(ДокументСсылка, ТаблицаПроводок)
    Для каждого ЗаписьБУ из ТаблицаПроводок Цикл
        
        ЗапросОС = Новый Запрос;
        ЗапросОС.Текст = 
            "ВЫБРАТЬ
            |	МестонахождениеОССрезПоследних.ОсновноеСредство КАК ОсновноеСредство,
            |	МестонахождениеОССрезПоследних.Арендатор КАК Арендатор
            |ИЗ
            |	РегистрСведений.МестонахождениеОС.СрезПоследних(, ) КАК МестонахождениеОССрезПоследних
            |ГДЕ
            |	МестонахождениеОССрезПоследних.ОсновноеСредство = &ОсновноеСредство";
            
        ЗапросОС.УстановитьПараметр("ОсновноеСредство", ЗаписьБУ.СубконтоДт1);
        РезультатОС = ЗапросОС.Выполнить().Выбрать();
        
        Если РезультатОС.Следующий() Тогда
            Если ЗаписьБУ.SчетКт = ПланыСчетов.Хозрасчетный.ПрочиеДоходныеВложения Тогда
                
                // Сначала указываем вид субконто для первой позиции Кт
                ЗаписьБУ.ВидСубконтоКт1 = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты;
                // Затем записываем само значение
                ЗаписьБУ.СубконтоКт1 = РезультатОС.Арендатор;
                
                // Повторяем операцию для второй позиции субконто Кт
                ЗаписьБУ.ВидСубконтоКт2 = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОсновныеСредства;
                ЗаписьБУ.СубконтоКт2 = РезультатОС.ОсновноеСредство;
                
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
КонецПроцедуры

Важное предупреждение: Данный способ полностью рабочий, однако он имеет существенный архитектурный минус — жесткое кодирование индексов субконто (1 и 2). Если в конфигураторе на счете ПрочиеДоходныеВложения поменяется порядок субконто (например, «Основные средства» станут первыми, а «Контрагенты» вторыми), этот код начнет записывать некорректные данные или вызовет ошибку проведения. Ниже мы разберем, как сделать код более гибким.

Способ 2. Заполнение субконто напрямую в Наборе Записей (Рекомендуемый платформенный подход)

Если вы работаете не с плоской промежуточной таблицей значений, а непосредственно с коллекцией движений документа (объектом типа РегистрБухгалтерииНаборЗаписей), то обращение к субконто происходит гораздо проще и безопаснее.

В наборе записей субконто хранятся в виде коллекции СубконтоДт и СубконтоКт. Обращаться к ним можно напрямую по ключу — объекту плана видов характеристик. При этом платформа сама определит нужный порядковый номер субконто на счете.

Проанализируем пример кода:


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

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

Способ 3. Использование типовых функций БСП

Если вы ведете разработку в типовой конфигурации 1С (например, 1С:Бухгалтерия предприятия, ERP или Комплексная автоматизация), то изобретать велосипед не нужно. В составе Библиотеки Стандартных Подсистем (БСП) уже есть готовые общие модули для работы с субконто.

Чаще всего используется метод БухгалтерскийУчет.УстановитьСубконто(). Разберем синтаксис его вызова:


// Метод сам проверит наличие вида субконто на счете и корректно заполнит значение
БухгалтерскийУчет.УстановитьСубконто(
    ЗаписьБУ.СчетКт, 
    ЗаписьБУ.СубконтоКт, 
    ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты, 
    СсылкаНаАрендатора
);

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

Способ 4. Динамическое определение индексов в Таблице Значений

Что делать, если вам всё-таки крайне необходимо работать именно с таблицей значений (например, в универсальном модуле обмена данными), но вы хотите избежать жесткого кодирования индексов СубконтоКт1, СубконтоКт2?

Решение — динамический обход видов субконто конкретного счета. Напишем универсальный алгоритм:


Если ЗаписьБУ.СчетКт = ПланыСчетов.Хозрасчетный.ПрочиеДоходныеВложения Тогда
    
    // Перебираем виды субконто, которые прикреплены к счету в пользовательском режиме или конфигураторе
    Для Каждого СтрокаСубконто Из ЗаписьБУ.СчетКт.ВидыСубконто Цикл
        
        Индекс = СтрокаСубконто.НомерСтроки; // Получаем реальный индекс (1, 2 или 3)
        ТекущийВидСубконто = СтрокаСубконто.ВидСубконто;
        
        // Динамически определяем имя колонки по индексу
        ИмяКолонкиВида = "ВидСубконтоКт" + Индекс;
        ИмяКолонкиЗначения = "СубконтоКт" + Индекс;
        
        Если ТекущийВидСубконто = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты Тогда
            ЗаписьБУ[ИмяКолонкиВида] = ТекущийВидСубконто;
            ЗаписьБУ[ИмяКолонкиЗначения] = СсылкаНаАрендатора;
            
        ИначеЕсли ТекущийВидСубконто = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.ОсновныеСредства Тогда
            ЗаписьБУ[ИмяКолонкиВида] = ТекущийВидСубконто;
            ЗаписьБУ[ИмяКолонкиЗначения] = СсылкаНаОС;
        КонецЕсли;
        
    КонецЦикла;
    
КонецЕсли;

Этот способ объединяет в себе гибкость работы с плоской таблицей значений и безопасность динамического определения индексов метаданных.

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

← На главную