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