Как программно заполнить новый непредопределенный вид субконто в 1С:Бухгалтерия 3.0 и устранить ошибку «Поле объекта не обнаружено»

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

При сопровождении и кастомизации типовых конфигураций «1С:Предприятие 8», в частности «Бухгалтерии предприятия 3.0», разработчики часто сталкиваются с ситуацией, когда после очередного обновления системы затертыми оказываются уникальные доработки. Одной из типичных проблем является потеря статуса предопределенного элемента у добавленного ранее вида субконто. В метаданных (конфигурации) этот элемент исчезает, но в самой информационной базе (таблице данных) он остается как обычный, созданный пользователем («непредопределенный») элемент Плана видов характеристик (ПВХ) ВидыСубконтоТиповые.

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

Поле объекта не обнаружено (МойВидСубконто)

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

Выясняем причину: почему возникает ошибка «Поле объекта не обнаружено»

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

Когда вид субконто описан в конфигураторе как предопределенный элемент ПВХ ВидыСубконтоТиповые (например, с именем МойВидСубконто), платформа динамически добавляет соответствующее свойство в объект коллекции. Мы можем написать интуитивно понятный код:

НоваяСтрока.СубконтоДт.МойВидСубконто = Ссылка;

Как только элемент теряет статус предопределенного (например, затирается обновлением и превращается в обычный элемент справочника/ПВХ), платформа больше не сопоставляет имя метаданных с динамическим свойством коллекции. Свойство МойВидСубконто исчезает, и при попытке обращения к нему система генерирует исключение Поле объекта не обнаружено.

Рассмотрим, как решить эту проблему программно, если субконто должно остаться пользовательским (непредопределенным), а также разберем алгоритм полного восстановления структуры данных.

Способ 1. Обращение к коллекции через квадратные скобки (по ссылке)

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

Рассмотрим пример реализации такого подхода по шагам:


// 1. Находим нужный вид субконто по наименованию или коду в базе данных
ВидСубк = ПланыВидовХарактеристик.ВидыСубконтоТиповые.НайтиПоНаименованию("Мой вид субконто");

// 2. Обязательно проверяем, найден ли элемент в информационной базе
Если ЗначениеЗаполнено(ВидСубк) Тогда
    // 3. Заполняем субконто напрямую по ссылке-ключу
    НоваяСтрока.СубконтоДт[ВидСубк] = Ссылка;
КонецЕсли;

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

Способ 2. Использование стандартных функций БСП (рекомендуемый код)

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

Проанализируем правильное использование этой функции в коде проведения документа:


// Находим ссылку на наш вид субконто (например, по коду или иным стабильным признакам)
ВидСубк = ПланыВидовХарактеристик.ВидыСубконтоТиповые.НайтиПоКоду("00001");

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

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

  1. Метод автоматически проверяет, назначен ли вообще данный вид субконто на указанном счете дебета (кредита). Если на счете нет такого субконто, программа не выдаст ошибку, а корректно пропустит операцию.
  2. Выполняется автоматическая проверка типов значений: система не позволит записать неподходящий тип данных в субконто, предотвращая логические ошибки в базе данных.
  3. Код остается чистым, понятным и полностью соответствует стандартам разработки фирмы «1С».

Способ 3. Восстановление предопределенности элемента без потери исторических данных

Если в вашем программном коде во множестве мест уже используется прямое обращение вида СубконтоДт.МойВидСубконто, переписывать везде логику может быть слишком трудозатратно и рискованно. Лучшим решением будет восстановление связи («склеивание») существующего пользовательского элемента в базе данных с конфигурацией, то есть возвращение ему статуса предопределенного элемента.

В платформе «1С:Предприятие 8.3» связь элементов базы данных с метаданными конфигуратора определяется специальным системным реквизитом ИмяПредопределенныхДанных. Разберем по шагам алгоритм восстановления этой связи:

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

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

// Шаг Б. Находим наш старый заполненный элемент (например, по наименованию)
СтарыйЭлементСсылка = ПланыВидовХарактеристик.ВидыСубконтоТиповые.НайтиПоНаименованию("Мой вид субконто");
Если ЗначениеЗаполнено(СтарыйЭлементСсылка) Тогда
    СтарыйОбъект = СтарыйЭлементСсылка.ПолучитьОбъект();
    
    // Привязываем старый элемент к предопределенному имени из метаданных конфигурации
    СтарыйОбъект.ИмяПредопределенныхДанных = "МойВидСубконто";
    СтарыйОбъект.Записать();
    
    Сообщить("Связь успешно восстановлена! Элемент снова стал предопределенным.");
КонецЕсли;

После успешного выполнения данного скрипта старый вид субконто вернет себе иконку предопределенного элемента (значок с желтой точкой). Все существующие проводки в регистре бухгалтерии останутся в целости и сохранности (так как внутренний уникальный идентификатор UUID элемента ПВХ не менялся), а старый программный код вида НоваяСтрока.СубконтоДт.МойВидСубконто = Ссылка; снова заработает без ошибок.

Возможные риски при восстановлении предопределенных субконто

Проанализируем возможные побочные эффекты, которые могут возникнуть при проведении подобных манипуляций в рабочей базе данных:

← На главную