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

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

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

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

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

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

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

Что такое предопределенный элемент и зачем он нужен

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

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

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

Способ 1. Функция ПредопределенноеЗначение()

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

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

Покупатель = ПредопределенноеЗначение("Справочник.Контрагенты.РозничныйПокупатель");

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

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

Способ 2. Менеджер справочника: ПолучитьСсылку и поиск по имени

Обращение через Справочники.ИмяСправочника

До появления ПредопределенноеЗначение() использовался синтаксис через менеджер справочника — он до сих пор встречается в старом коде и работает:

ВалютаРубль = Справочники.Валюты.Рубль;

// или в старых конфигурациях:

ВалютаРубль = Справочники.Валюты.ПолучитьСсылку(Новый УникальныйИдентификатор("..."));

Обращение Справочники.Валюты.Рубль — это обращение к предопределенному элементу по имени через менеджер. Оно работает только на сервере и в толстом клиенте, на тонком клиенте менеджеры справочников недоступны. Если код должен выполняться на клиенте, используйте ПредопределенноеЗначение().

Проверка существования элемента в базе

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

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

Если СсылкаРубль = Неопределено Тогда

ВызватьИсключение "Предопределенный элемент ""Рубль"" не описан в конфигурации";

КонецЕсли;

Если СсылкаРубль.Пустая() Тогда

ВызватьИсключение "Предопределенный элемент ""Рубль"" отсутствует в базе данных";

КонецЕсли;

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

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

Что вернула функция
Норма

Ссылка на элемент, не Неопределено и не пустая ссылка

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

Неопределено — элемента нет в метаданных; пустая ссылка — элемента нет в данных

Значение в отладчике
Норма

Тип «СправочникСсылка.ИмяСправочника», при разворачивании видны реквизиты

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

Ошибка при обращении к реквизитам — ссылка битая

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

Код продолжает работать, так как обращение идёт по имени метаданных

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

Поиск по наименованию перестал находить элемент

Способ 3. Обращение в запросе

В запросах предопределенные элементы получают через функцию языка запросов ЗНАЧЕНИЕ(). Это позволяет сравнивать поля с предопределенным элементом прямо в тексте запроса, без передачи параметра:

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

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

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Валюта = ЗНАЧЕНИЕ(Справочник.Валюты.Рубль)";

Альтернатива — передать ссылку параметром: Запрос.УстановитьПараметр("Валюта", ПредопределенноеЗначение("Справочник.Валюты.Рубль")). Оба варианта корректны. Параметр удобнее, когда одно и то же значение используется в нескольких условиях или запрос динамически меняется. ЗНАЧЕНИЕ() нагляднее для фиксированных условий, но жёстко привязывает запрос к имени элемента — при переименовании в конфигураторе запрос перестанет компилироваться.

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

Особенности режимов: тонкий клиент, внешние соединения, обмены

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

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

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

Первая и самая распространённая ошибка — поиск предопределенного элемента по наименованию: Справочники.Контрагенты.НайтиПоНаименованию("Розничный покупатель"). Пока никто не переименовал элемент, код работает, создавая ложное ощущение надёжности. После переименования поиск возвращает пустую ссылку, и документы начинают проводиться с пустым контрагентом или падают с ошибкой.

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

Третья ошибка — попытка получить реквизиты элемента через точку от ПредопределенноеЗначение() в клиентском коде. Обращение ПредопределенноеЗначение("Справочник.Валюты.Рубль").Наименование на тонком клиенте приведёт к серверному вызову на каждое обращение к реквизиту. Если нужны реквизиты, получите их на сервере одним запросом.

Типичные ошибки
01
Поиск по наименованию через НайтиПоНаименованию — ломается при переименовании элемента пользователем
02
Опечатка в строке ПредопределенноеЗначение — не выявляется компилятором, возвращает Неопределено в рантайме
03
Обращение Справочники.Имя.Элемент на тонком клиенте — ошибка компиляции, менеджеры доступны только на сервере
04
Чтение реквизитов через точку от ссылки на клиенте — серия серверных вызовов и резкое падение производительности
05
Отсутствие проверки на Неопределено — пустые значения молча попадают в документы и регистры

Практические рекомендации по организации кода

Хорошая практика — централизовать обращения к предопределенным элементам в общем модуле. Например, создать модуль «ПредопределенныеЗначения» с функциями вида:

Функция ВалютаРубль() Экспорт

Возврат ПредопределенноеЗначение("Справочник.Валюты.Рубль");

КонецФункции;

Функция РозничныйПокупатель() Экспорт

Возврат ПредопределенноеЗначение("Справочник.Контрагенты.РозничныйПокупатель");

КонецФункции;

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

Порядок действий при добавлении обращения к предопределенному элементу
  1. 1
    Откройте конфигуратор и найдите нужный элемент в ветке «Предопределенные» справочника — запомните точное имя
  2. 2
    В коде используйте ПредопределенноеЗначение("Справочник.ИмяСправочника.ИмяЭлемента")
  3. 3
    Добавьте проверку результата на Неопределено и на пустую ссылку
  4. 4
    Если обращений несколько — вынесите получение ссылки в функцию общего модуля
  5. 5
    Протестируйте: выполните код, проверьте в отладчике тип и значение ссылки, затем переименуйте элемент в пользовательском режиме и убедитесь, что код по-прежнему работает

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

Чем отличается имя предопределенного элемента от его наименования?

Имя задаётся разработчиком в конфигураторе, видно только там и используется в коде. Наименование — пользовательское поле, которое можно редактировать в режиме предприятия. Программное обращение идёт по имени, поэтому переименование элемента пользователем не ломает код.

Что вернёт ПредопределенноеЗначение(), если элемента нет в базе?

Если элемент описан в метаданных, но отсутствует в данных, функция вернёт ссылку, которая может оказаться пустой или «битой» — проверяйте методом Пустая(). Если элемента нет в метаданных (опечатка в имени), вернётся Неопределено. Это разные ситуации, и обрабатывать их нужно по-разному.

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

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

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

Используйте конструкцию языка запросов ЗНАЧЕНИЕ(Справочник.ИмяСправочника.ИмяЭлемента) прямо в тексте запроса либо передайте ссылку, полученную через ПредопределенноеЗначение(), параметром запроса. Оба варианта равнозначны по результату.

Почему поиск по наименованию находит элемент, но это считается ошибкой?

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

Что делать, если предопределенный элемент случайно удалили в пользовательском режиме?

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

Итог

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

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