Разработка и Конфигурация · 8 мин
Как проверить наличие реквизита у справочника в 1С
Как проверить, есть ли реквизит у справочника в 1С: методы Найти(), метаданные, проверка в запросе и в конфигураторе. Примеры кода и разбор типичных ошибок.
Проверка существования реквизита у справочника — типовая задача при разработке универсальных механизмов, обменов данными и обработок, которые должны работать с разными конфигурациями. Если обратиться к несуществующему реквизиту напрямую, платформа выдаст ошибку «Поле объекта не обнаружено», и выполнение кода прервётся.
В 1С есть несколько способов проверки: через метод Найти() коллекции реквизитов метаданных, через попытку обращения с обработкой исключения, а также визуально — в конфигураторе. Выбор зависит от контекста: пишете вы код на встроенном языке, формируете запрос или просто изучаете структуру конфигурации.
Ниже разобраны все рабочие варианты с примерами кода, ограничения каждого подхода и типичные ошибки, которые приводят к ложным результатам проверки.
Проверка реквизита через метаданные в коде
Основной и рекомендуемый способ — обращение к коллекции реквизитов через объект метаданных справочника. Метод Найти() возвращает объект описания реквизита, если он существует, и Неопределено, если реквизита нет.
МетаСпр = Метаданные.Справочники.Номенклатура;
Если МетаСпр.Реквизиты.Найти("Артикул") <> Неопределено Тогда
Сообщить("Реквизит существует");
Иначе
Сообщить("Реквизит отсутствует");
КонецЕсли;
Такой подход работает на сервере и на толстом клиенте, не требует получения данных из базы и выполняется мгновенно, поскольку метаданные уже загружены в память. Это стандартный приём при написании универсальных обработок.
Обратите внимание: метод Найти() чувствителен к регистру только частично — платформа обычно находит реквизит независимо от регистра букв, но полагаться на это не стоит. Используйте точное имя, как оно задано в конфигураторе.
Функция ЕстьРеквизитСправочника(ИмяСправочника, ИмяРеквизита)
МетаОбъект = Метаданные.Справочники.Найти(ИмяСправочника);
Если МетаОбъект = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Возврат МетаОбъект.Реквизиты.Найти(ИмяРеквизита) <> Неопределено;
КонецФункцииУниверсальная функция проверки для любого объекта
Если проверка нужна не только для справочников, но и для документов или других объектов, удобно написать универсальную функцию, принимающую объект метаданных или ссылку. Это особенно полезно в механизмах обмена, где состав реквизитов может отличаться между базами.
Функция ЕстьРеквизит(ИмяРеквизита, ОбъектМетаданных)
Возврат ОбъектМетаданных.Реквизиты.Найти(ИмяРеквизита) <> Неопределено;
КонецФункции;
// Вызов:
ЕстьРеквизит("Комментарий", Метаданные.Справочники.Контрагенты);
Для проверки по ссылке на элемент справочника сначала получите метаданные через метод Метаданные() объекта: ЭлементСправочника.Метаданные().Реквизиты.Найти("Имя"). Это удобно, когда тип объекта заранее неизвестен.
Проверка в конфигураторе без написания кода
Когда нужно просто узнать, есть ли реквизит, достаточно конфигуратора. Откройте конфигурацию, найдите нужный справочник в дереве объектов и раскройте ветку «Реквизиты» — там перечислены все добавленные разработчиком реквизиты.
Альтернативный путь — двойной щелчок по справочнику откроет окно редактирования объекта, где на закладке «Данные» показаны длина кода, наименования и полный список реквизитов с типами.
Если конфигурация на поддержке и закрыта от изменений, просмотр структуры всё равно доступен. Для типовых конфигураций также можно воспользоваться поиском по метаданным: меню «Правка — Найти» с поиском по имени реквизита.
- 1Откройте конфигуратор и загрузите конфигурацию базы
- 2В дереве конфигурации раскройте ветку «Справочники»
- 3Найдите нужный справочник и раскройте его ветку «Реквизиты»
- 4Проверьте наличие нужного имени в списке
- 5Если реквизита нет — проверьте, не является ли он стандартным или общим реквизитом
Проверка наличия поля в запросе
В тексте запроса обращение к несуществующему реквизиту вызовет ошибку ещё на этапе выполнения Запрос.Выполнить(). Чтобы построить динамический запрос с учётом состава реквизитов, сначала выполните проверку через метаданные, а затем сформируйте текст запроса.
ТекстЗапроса = "ВЫБРАТЬ Ссылка";
Если Метаданные.Справочники.Номенклатура.Реквизиты.Найти("Артикул") <> Неопределено Тогда
ТекстЗапроса = ТекстЗапроса + ", Артикул";
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + " ИЗ Справочник.Номенклатура";
Такой подход используется в универсальных отчётах и обработках выгрузки, где заранее неизвестно, присутствует ли реквизит в конкретной конфигурации заказчика.
Типичные ошибки при проверке реквизитов
Самая частая ошибка — поиск стандартного реквизита (Код, Наименование) в коллекции Реквизиты. Проверка вернёт Неопределено, хотя поле у объекта есть. Для стандартных реквизитов используйте коллекцию СтандартныеРеквизиты или обращайтесь к ним напрямую.
Вторая ошибка — путаница между реквизитами справочника и реквизитами табличной части. У табличной части своя коллекция: Метаданные.Справочники.Имя.ТабличныеЧасти.ИмяТЧ.Реквизиты.
Третья ошибка — обращение к реквизиту через точку у объекта без проверки в универсальном коде. Если обработка запускается на конфигурации, где реквизит удалён или переименован, код упадёт с ошибкой. Всегда проверяйте наличие через метаданные перед обращением.
Ограничения и нюансы
Общие реквизиты конфигурации не отображаются в коллекции Реквизиты конкретного справочника. Чтобы проверить, входит ли справочник в состав общего реквизита, нужно анализировать свойство Состав объекта метаданных общего реквизита.
На тонком клиенте доступ к метаданным ограничен — прямая работа с коллекциями метаданных возможна только в серверном контексте. Если проверка нужна на клиенте, выполните её в серверной процедуре и верните результат.
Также учитывайте функциональные опции: реквизит может существовать в метаданных, но быть отключённым функциональной опцией. Проверка через Найти() вернёт объект реквизита, однако в интерфейсе и при некоторых сценариях он будет недоступен. Для проверки доступности используйте метод ПолучитьФункциональнуюОпцию или свойства объекта метаданных.
Как проверить результат
Возвращён объект описания реквизита (не Неопределено)
Неопределено — реквизита нет либо он стандартный или общий
Значение читается без ошибки
Ошибка «Поле объекта не обнаружено»
Поле видно и доступно для редактирования
Поле скрыто функциональной опцией или правами
Частые вопросы
Как проверить наличие стандартного реквизита, например «Владелец»?
Стандартные реквизиты находятся в коллекции СтандартныеРеквизиты объекта метаданных. Однако проще проверить свойства самого справочника: например, наличие владельца определяется через Метаданные.Справочники.Имя.Владельцы — если коллекция пуста, справочник не подчинённый.
Можно ли проверить реквизит, зная только имя справочника строкой?
Да. Сначала получите объект метаданных по имени: Метаданные.Справочники.Найти(ИмяСправочника). Если вернулось Неопределено — самого справочника нет. Затем проверьте реквизит через Реквизиты.Найти(ИмяРеквизита).
Почему Найти() не находит реквизит, который виден в конфигураторе?
Скорее всего, это общий реквизит конфигурации или стандартный реквизит. Общие реквизиты не входят в коллекцию Реквизиты объекта — проверяйте ветку «Общие реквизиты» в дереве конфигурации и её свойство «Состав».
Как проверить наличие реквизита в табличной части справочника?
Обратитесь к метаданным табличной части: Метаданные.Справочники.Имя.ТабличныеЧасти.Найти(ИмяТЧ), а затем у найденного объекта — Реквизиты.Найти(ИмяРеквизита). Проверяйте оба уровня, чтобы избежать ошибки при отсутствии самой табличной части.
Работает ли проверка через метаданные на тонком клиенте?
Нет, на тонком клиенте доступ к метаданным ограничен. Выполняйте проверку в серверной процедуре (с директивой &НаСервере или &НаСервереБезКонтекста) и возвращайте на клиент булево значение.
Что важно запомнить
Наличие реквизита у справочника проверяется через Метаданные.Справочники.Имя.Реквизиты.Найти(ИмяРеквизита): Неопределено означает отсутствие. Стандартные и общие реквизиты в эту коллекцию не входят и проверяются отдельно. В универсальном коде всегда проверяйте реквизит перед обращением к нему.