К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как в 1С получить имя предопределенного элемента

Способы получить имя предопределенного элемента в 1С: методы ПолучитьИмяПредопределенного, НайтиПоИмени, запросы. Примеры кода, ошибки и проверка результата.

Предопределенные элементы создаются в конфигураторе и часто используются в коде как точки отсчёта: валюта по умолчанию, основная организация, служебные группы. Чтобы обратиться к такому элементу из встроенного языка, разработчику нужно его имя — или, наоборот, по имеющемуся имени получить ссылку. Обе задачи решаются штатными методами платформы, но у каждого способа есть ограничения и тонкости.

Основной инструмент — метод ПолучитьИмяПредопределенного(), доступный у объекта типа «Ссылка» для справочников, планов видов характеристик, планов счетов и планов видов расчёта. Он возвращает имя, заданное в конфигураторе, а для обычных (непредопределенных) элементов — пустую строку. Важно не путать это имя с наименованием элемента: наименование может менять пользователь, а имя предопределенного элемента жёстко зафиксировано в метаданных.

Что такое предопределенный элемент и чем имя отличается от наименования

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

У предопределенного элемента есть два «имени». Наименование — обычный реквизит, который пользователь может редактировать. Имя предопределенного — технический идентификатор из конфигуратора, недоступный для изменения в режиме предприятия. Именно второе используется в программном коде, потому что оно стабильно: даже если бухгалтер переименует «Основную организацию» в «ООО Ромашка», код продолжит работать.

Как получить имя предопределенного элемента по ссылке

Если у вас уже есть ссылка на элемент, имя получается одним вызовом:

ИмяЭлемента = СсылкаНаЭлемент.ПолучитьИмяПредопределенного();

Если ПустаяСтрока(ИмяЭлемента) Тогда

// Элемент не предопределенный

КонецЕсли;

Метод работает на клиенте и на сервере, не требует обращения к базе данных поверх уже полученной ссылки в части самого вызова — платформа сама получает нужные данные. Однако учитывайте: если ссылка получена в результате запроса, вызов метода для каждой строки результата может привести к множеству обращений к СУБД. В циклах по большим выборкам это заметно замедляет выполнение.

Для пустой ссылки метод вернёт пустую строку, поэтому отдельная проверка на Ссылки.Пустая() перед вызовом не обязательна, но полезна для читаемости кода.

Как получить имя через запрос

Когда нужно получить имена сразу для множества элементов, эффективнее использовать запрос с виртуальным представлением. У таблиц справочников и планов есть поле Предопределенный, но само имя напрямую в таблице не хранится — его придётся сопоставлять через функцию ПРЕДСТАВЛЕНИЕ либо получать ссылки и вызывать метод построчно. На практике чаще применяют другой подход: выбирают только предопределенные элементы и обрабатывают их по одному.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Предопределенный";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Имя = Выборка.Ссылка.ПолучитьИмяПредопределенного();

КонецЦикла;

Такой вариант оправдан, когда предопределенных элементов немного — обычно их единицы или десятки, и построчные вызовы не создают проблем с производительностью.

Как по имени получить ссылку: обратная задача

Чаще всего на практике нужна обратная операция — по известному имени получить ссылку. Самый надёжный способ в современных версиях платформы:

Ссылка = ПредопределенноеЗначение("Справочник.Валюты.USD");

Функция ПредопределенноеЗначение() работает быстро, так как использует кэш, и вызывает исключение, если элемент с таким именем не существует в метаданных. Это одновременно и плюс (ошибка обнаруживается сразу), и минус (нужно быть уверенным в наличии элемента).

Альтернатива — метод менеджера объекта:

Ссылка = Справочники.Валюты.НайтиПоИмени("USD");

Метод НайтиПоИмени() выполняет обращение к базе и возвращает пустую ссылку, если элемент не найден, — без исключения. Он подходит, когда имя формируется динамически и заранее неизвестно, существует ли такой предопределенный элемент.

Сравнение способов

ПредопределенноеЗначение()

Быстрый вызов через кэш, но генерирует исключение при отсутствии элемента в метаданных. Подходит для фиксированных имён в коде.

НайтиПоИмени()

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

ПолучитьИмяПредопределенного()

Обратная операция: получение имени по ссылке. Для массовой обработки требует аккуратности из-за обращений к СУБД.

Особенности для разных объектов метаданных

Описанные методы работают для четырёх типов объектов: справочников, планов видов характеристик, планов счетов и планов видов расчёта. Строка для ПредопределенноеЗначение() строится по шаблону «ТипОбъекта.ИмяОбъекта.ИмяЭлемента», например ПланСчетов.Хозрасчетный.Материалы.

Для перечислений механика другая: значения перечислений всегда «предопределены» по своей природе, и к ним обращаются напрямую — Перечисления.СтавкиНДС.НДС20, без дополнительных функций. Документы, регистры и задачи предопределенных элементов не имеют вовсе.

Типичные ошибки и как их избежать

Самая частая ошибка — поиск предопределенного элемента по наименованию через НайтиПоНаименованию(). Такой код ломается, как только пользователь переименует элемент, а при наличии дублей может вернуть вообще другой объект. Для предопределенных элементов всегда используйте имя из конфигуратора.

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

Типичные ошибки
01
Поиск по наименованию вместо имени — код перестаёт работать после переименования элемента пользователем
02
Удаление предопределенного элемента из конфигуратора без поиска обращений к нему в коде — исключения в рабочей базе
03
Вызов ПолучитьИмяПредопределенного() в цикле по большой выборке — лишние обращения к СУБД и падение производительности
04
Ожидание, что метод вернёт наименование: для обычных элементов он возвращает пустую строку, а не представление

Как проверить результат и где посмотреть имена в конфигураторе

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

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

Контрольные точки

Как проверить результат

Возвращаемое значение ПолучитьИмяПредопределенного()
Норма

Строка с именем из конфигуратора

Тревожный признак

Пустая строка у элемента, который должен быть предопределенным

Вызов ПредопределенноеЗначение()
Норма

Возвращается заполненная ссылка

Тревожный признак

Исключение — имени нет в метаданных

Поведение после обновления конфигурации
Норма

Элемент появился в базе со специальной пиктограммой

Тревожный признак

Элемента нет в списке — обновление БД не завершено

Часто задаваемые вопросы

Чем ПолучитьИмяПредопределенного отличается от реквизита ИмяПредопределенныхДанных?

Метод ПолучитьИмяПредопределенного() вызывается у ссылки и возвращает имя, опираясь на служебные данные платформы. Поле ИмяПредопределенныхДанных существовало в таблицах базы в старых версиях и в современных режимах совместимости может быть недоступно или не рекомендовано к прямому использованию. Опирайтесь на штатный метод — он стабилен между релизами платформы.

Можно ли получить имя предопределенного элемента на толстом клиенте без вызова сервера?

Да, метод ПолучитьИмяПредопределенного() доступен на клиенте, однако фактическое получение данных может инициировать серверный вызов неявно. В управляемом приложении при массовом использовании лучше получать имена на сервере и передавать на клиент готовую структуру.

Что вернёт ПредопределенноеЗначение, если элемент есть в конфигураторе, но удалён в базе?

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

Как перебрать все предопределенные элементы конкретного справочника?

Через метаданные: коллекция Метаданные.Справочники.ИмяСправочника.ПолучитьИменаПредопределенных() вернёт список имён, заданных в конфигураторе. Это серверный метод, он не обращается к данным базы и подходит для построения соответствий имён и ссылок.

Работает ли НайтиПоИмени для планов счетов и планов видов расчёта?

Да, метод доступен для всех объектов, поддерживающих предопределенные элементы: справочников, планов видов характеристик, планов счетов и планов видов расчёта. Синтаксис одинаков — вызов через менеджер объекта, например ПланыСчетов.Хозрасчетный.НайтиПоИмени("Материалы").

Почему код с ПредопределенноеЗначение падает после обновления конфигурации поставщика?

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

Итог

Что важно запомнить

Имя предопределенного элемента получают методом ПолучитьИмяПредопределенного() у ссылки, а ссылку по имени — через ПредопределенноеЗначение() или НайтиПоИмени(). Используйте имя из конфигуратора вместо наименования, избегайте вызовов в циклах по большим выборкам и проверяйте обращения к именам после обновления конфигурации.