Как проверить наличие предопределённого элемента в 1С без использования исключений

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает необходимость программно получить ссылку на предопределённый элемент справочника, перечисления или другого объекта метаданных. Однако стандартное обращение через точку или менеджер объекта может привести к фатальной ошибке, если элемент отсутствует. Рассмотрим наиболее эффективные и безопасные способы проверки наличия предопределённых данных, разберем их внутренние механизмы и выясним, какой метод лучше использовать в зависимости от версии платформы и используемых библиотек.

Использование стандартной функции ПредопределенноеЗначение

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


// Получение ссылки на перечисление
ЮрФизЛицо = ПредопределенноеЗначение("Перечисление.ЮридическоеФизическоеЛицо.ЮридическоеЛицо");

// Получение ссылки на предопределенный элемент справочника
ОсновнойСклад = ПредопределенноеЗначение("Справочник.Склады.Центральный");

Давайте проанализируем, почему этот метод предпочтительнее прямого обращения к менеджеру объекта (например, Перечисления.ЮридическоеФизическоеЛицо.ЮридическоеЛицо). Во-первых, эта функция доступна на клиенте (тонкий, веб-клиент), где менеджеры объектов недоступны. Во-вторых, платформа кэширует результат выполнения функции при первом обращении. Это означает, что повторные вызовы не будут инициировать серверные вызовы, что положительно сказывается на производительности.

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

Безопасный метод с использованием БСП

Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП) версии 2.1.4 и выше, разработчики 1С настоятельно рекомендуют использовать функции общих модулей. Это самый "чистый" и безопасный способ, так как он не вызывает исключений при отсутствии данных. Для изучения доступных функций подсистем можно использовать справочник по методам БСП с примерами использования.

Разберем использование функций модуля ОбщегоНазначения:


// На сервере или в толстом клиенте
СсылкаНаЭлемент = ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.СтатьиЗатрат.Аренда");

// На клиенте
СсылкаНаЭлемент = ОбщегоНазначенияКлиент.ПредопределенныйЭлемент("ПланВидовРасчета.Начисления.Оклад");

Если СсылкаНаЭлемент = Неопределено Тогда
    // Обработка ситуации, когда элемент не найден
    Сообщить("Предопределенный элемент не найден в системе!");
КонецЕсли;

Проанализируем преимущества этого подхода:

  1. Отсутствие Runtime Error: В отличие от платформенных методов, функция БСП вернет Неопределено, если путь к элементу указан неверно или самого элемента не существует.
  2. Универсальность: Вам не нужно писать конструкции Попытка...Исключение.
  3. Интеллектуальное кэширование: БСП самостоятельно управляет кэшем на клиенте, минимизируя количество обращений к серверу.

Проверка наличия элемента через запрос

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

Рассмотрим способ проверки через запрос к базе данных:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Склады.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.Склады КАК Склады
    |ГДЕ
    |	Склады.ИмяПредопределенныхДанных = &ИмяЭлемента";

Запрос.УстановитьПараметр("ИмяЭлемента", "Центральный");
РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Пустой() Тогда
    // Элемента физически нет в таблице базы данных
КонецЕсли;

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

Проверка через метаданные (наличие в конфигурации)

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


ИмяСправочника = "Склады";
ИмяЭлемента = "Центральный";

МетаданныеОбъекта = Метаданные.Справочники[ИмяСправочника];
ЭлементМетаданных = МетаданныеОбъекта.Предопределенные.Найти(ИмяЭлемента);

Если ЭлементМетаданных <> Неопределено Тогда
    // Элемент описан в конфигурации
КонецЕсли;

Этот способ работает максимально быстро, так как не требует обращения к таблицам БД. Мы проверяем только структуру метаданных, которая уже загружена в память приложения.

Особенности работы в расширениях конфигурации

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

При использовании ПредопределенноеЗначение("Справочник.Номенклатура.Услуга") проверка происходит на этапе выполнения (Runtime). Это позволяет писать более гибкий код, который "выживет" после обновления основной конфигурации, даже если структура предопределенных данных изменилась. Вы сможете программно обработать ошибку или отсутствие значения, сохранив работоспособность системы.

Проблема "битых" связей

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

Чтобы проверить "здоровье" предопределенного элемента, выполните следующую проверку:


СсылкаНаЭлемент = Справочники.Склады.Центральный;
Если ЗначениеЗаполнено(СсылкаНаЭлемент) И СсылкаНаЭлемент.Метаданные().ИмяПредопределенныхДанных <> "" Тогда
    // Ссылка корректна и связана с метаданными
КонецЕсли;

Подведение итогов

Подводя итог, можно выделить следующие рекомендации по выбору метода:

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

← На главную