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