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