Как исправить ошибку «Поле объекта недоступно для записи (СубконтоДт)» при программном создании проводок в 1С?

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

При программном формировании проводок в регистре бухгалтерии разработчики нередко сталкиваются с исключением вида: «Поле объекта недоступно для записи (СубконтоДт)» (или аналогично для СубконтоКт). Разберем причины возникновения этой ситуации и выясним, как правильно заполнять аналитику счета в коде 1С.

Рассмотрим типовой ошибочный фрагмент кода, приводящий к сбою:


Набор = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(НовДок.Ссылка);
Набор.Прочитать();

НовДвижение = Набор.Добавить();
ЗаполнитьЗначенияСвойств(НовДвижение, Строка);
НовДвижение.СубконтоДт = Строка.СубконтоДт1; // Здесь возникает ошибка
НовДвижение.ВидСубконтоДт = Строка.ВидСубконтоДт1;

Почему возникает ошибка

Проанализируем архитектуру регистра бухгалтерии в платформе 1С:Предприятие:

  1. Тип свойства: Свойства СубконтоДт и СубконтоКт у строки набора записей регистра бухгалтерии имеют тип СубконтоЗаписиРегистраБухгалтерии. Это не простое поле для хранения значения, а отдельная коллекция (объект), ссылка на которую доступна только для чтения. При попытке выполнить прямое присвоение НовДвижение.СубконтоДт = Значение платформа выдает ошибку доступа.
  2. Зависимость от счета: Коллекция субконто формируется динамически на основании видов субконто, привязанных к счету. Поэтому перед заполнением аналитики обязательно должны быть заполнены поля СчетДт или СчетКт. Если счет не указан, состав доступных субконто пуст.
  3. Несуществующие свойства: Поля вида ВидСубконтоДт отсутствуют у строки движения регистра. Вид субконто выступает ключом или индексом в самой коллекции СубконтоДт.

Способ 1. Заполнение по виду субконто через квадратные скобки

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

Посмотрим на пример правильного заполнения проводки:


НовДвижение = Набор.Добавить();
НовДвижение.Период = ДатаПроводки;
НовДвижение.Регистратор = ДокументСсылка;
НовДвижение.Организация = ОрганизацияСсылка;

// Сначала обязательно указываем счета учета
НовДвижение.СчетДт = ПланыСчетов.Хозрасчетный.РасчетыСПоставщиками;
НовДвижение.СчетКт = ПланыСчетов.Хозрасчетный.РасчетныеСчета;

// Заполняем субконто по дебету
ВидСубконтоКонтрагенты = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Контрагенты;
ВидСубконтоДоговоры = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Договоры;

НовДвижение.СубконтоДт[ВидСубконтоКонтрагенты] = КонтрагентСсылка;
НовДвижение.СубконтоДт[ВидСубконтоДоговоры] = ДоговорСсылка;

// Заполняем субконто по кредиту
ВидСубконтоБанкСчета = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.БанковскиеСчета;
НовДвижение.СубконтоКт[ВидСубконтоБанкСчета] = БанковскийСчетСсылка;

НовДвижение.Сумма = СуммаПроводки;

Способ 2. Использование метода Вставить() коллекции субконто

Коллекция СубконтоЗаписиРегистраБухгалтерии предоставляет встроенный метод Вставить(). Первым параметром передается вид субконто, а вторым — устанавливаемое значение.

Разберем пример:


НовДвижение.СчетДт = СчетУчета;
НовДвижение.СубконтоДт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура, НоменклатураСсылка);
НовДвижение.СубконтоДт.Вставить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады, СкладСсылка);

Способ 3. Заполнение субконто по порядковому номеру на счете

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

Посмотрим на пример:


НовДвижение.СчетДт = СчетУчета;

// Вариант с обращением по номеру субконто (1, 2 или 3)
НовДвижение.СубконтоДт[1] = ЗначениеПервогоСубконто;

// Универсальный вариант с получением вида субконто из строки счета
Если НовДвижение.СчетДт.ВидыСубконто.Количество() > 0 Тогда
    ВидПервогоСубконто = НовДвижение.СчетДт.ВидыСубконто[0].ВидСубконто;
    НовДвижение.СубконтоДт[ВидПервогоСубконто] = ЗначениеПервогоСубконто;
КонецЕсли;

Способ 4. Использование типовых процедур общего назначения

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

Использование типовых методов предпочтительно, поскольку внутри них выполняется проверка соответствия типа счета и наличия указанного вида субконто на счете:


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

Особенности учета по подразделениям и специфика работы с документами

Обратим внимание на две важные детали при работе с регистрами бухгалтерии:

  1. Подразделения как измерения: В ряде конфигураций (например, УТП, УПП, ERP) аналитика по подразделениям может быть вынесена из субконто в отдельные измерения регистра бухгалтерии (например, ПодразделениеДт, ПодразделениеКт или ПодразделениеОрганизации). Если на счете нет вида субконто «Подразделения», запись значения в субконто не сработает — необходимо заполнять напрямую измерение строки: НовДвижение.ПодразделениеДт = ПодразделениеСсылка;.
  2. Запись движений документа «Операция»: Если проводки создаются для ручной бухгалтерской операции, запись через отдельный набор записей регистра может привести к рассинхронизации данных формы документа и регистра. Надежнее получать объект самого документа и заполнять его коллекцию Движения.Хозрасчетный:

ДокОбъект = НовДок.ПолучитьОбъект();
ДвиженияХозрасчетный = ДокОбъект.Движения.Хозрасчетный;

НовДвижение = ДвиженияХозрасчетный.Добавить();
НовДвижение.Период = ДокОбъект.Дата;
НовДвижение.Организация = ДокОбъект.Организация;
НовДвижение.СчетДт = СчетДтСсылка;
НовДвижение.СчетКт = СчетКтСсылка;

НовДвижение.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура] = НоменклатураСсылка;
НовДвижение.Сумма = СуммаОперации;

ДвиженияХозрасчетный.Записать();
ДокОбъект.Записать();
← На главную