Как программно проверить существование реквизита управляемой формы по его имени?

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

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

Способ 1. Использование блока «Попытка — Исключение»

Это самый простой и очевидный метод, который первым приходит в голову разработчикам. Суть заключается в попытке прямого обращения к реквизиту через контекст формы ЭтотОбъект (или ЭтаФорма). Если реквизит отсутствует, система вызовет исключение, которое мы перехватим.

Рассмотрим пример реализации:


ИскомыйРеквизит = Неопределено;
Попытка
    // Пытаемся обратиться к реквизиту по имени через индексатор
    ИскомыйРеквизит = ЭтотОбъект["ИмяРеквизита"];
    ЕстьРеквизит = Истина;
Исключение
    // Если возникла ошибка — реквизита не существует
    ЕстьРеквизит = Ложь;
КонецПопытки;

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

Способ 2. Использование метода «ПолучитьРеквизиты» на сервере

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

Разберем, как это работает программно:


&НаСервере
Функция ПроверитьНаличиеРеквизитаНаСервере(ИмяПоиска)
    
    МассивРеквизитов = ПолучитьРеквизиты();
    Для Каждого Реквизит Из МассивРеквизитов Цикл
        Если Реквизит.Имя = ИмяПоиска Тогда
            Возврат Истина;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Ложь;
    
КонецФункции

Этот способ считается наиболее «чистым» с точки зрения архитектуры платформы. Объект РеквизитФормы содержит не только имя, но и метаданные: ТипЗначения, Путь и признак того, является ли реквизит колонкой таблицы. Однако помните, что метод ПолучитьРеквизиты() доступен только на сервере. Если вам нужна проверка на клиенте, придется либо делать вызов сервера, либо кэшировать список имен в отдельную переменную (например, в структуру) при создании формы.

Способ 3. Универсальный «хак» через «ЗаполнитьЗначенияСвойств»

Существует очень интересный и производительный способ, который работает и на клиенте, и на сервере без использования тяжелых исключений. Он основан на поведении функции ЗаполнитьЗначенияСвойств. Мы создаем структуру с искомым именем и заполняем её данными из формы.

Рассмотрим этот алгоритм подробнее:

  1. Создаем уникальный маркер (например, УникальныйИдентификатор), который точно не может быть значением реквизита.
  2. Создаем структуру, где ключ — это имя искомого реквизита, а значение — наш маркер.
  3. Выполняем ЗаполнитьЗначенияСвойств(Структура, ЭтаФорма).
  4. Если значение в структуре изменилось — значит, реквизит в форме есть и его значение скопировалось. Если осталось прежним (маркером) — реквизита нет.

Пример кода:


ЗначениеПоУмолчанию = Новый УникальныйИдентификатор;
СтруктураСвойств = Новый Структура("ИмяПроверяемогоРеквизита", ЗначениеПоУмолчанию);

// Копируем данные из формы в структуру по именам полей
ЗаполнитьЗначенияСвойств(СтруктураСвойств, ЭтаФорма);

Если СтруктураСвойств["ИмяПроверяемогоРеквизита"] = ЗначениеПоУмолчанию Тогда
    // Значение не изменилось, реквизит не найден
    ЕстьРеквизит = Ложь;
Иначе
    // Реквизит существует (даже если он пустой, маркер затрется)
    ЕстьРеквизит = Истина;
КонецЕсли;

Этот метод работает быстрее, чем «Попытка — Исключение», так как не задействует механизм обработки ошибок платформы.

Способ 4. Использование функций Библиотеки Стандартных Подсистем (БСП)

Если ваша конфигурация построена на базе БСП (что верно для большинства современных решений, таких как ERP, УТ 11 или БП 3.0), разработчики уже позаботились об универсальной функции. Рекомендуем использовать программный интерфейс общего назначения.

Пример использования функции БСП:


Результат = ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ЭтаФорма, "ИмяРеквизита");

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

Нюансы проверки в Табличных Частях и коллекциях

Выясним причину, почему стандартные методы иногда не срабатывают для колонок таблиц. Если реквизит является частью ДанныеФормыКоллекция (например, колонка программно созданной Таблицы Значений), то проверка через ЭтаФорма["Имя"] может не вернуть результат.

В этом случае проанализируем ситуацию с элементами формы. Если ваша цель — проверить, отображается ли колонка визуально, лучше использовать поиск по коллекции элементов:


ИскомыйЭлемент = ЭтаФорма.Элементы.Найти("ИмяЭлементаКолонки");
Если ИскомыйЭлемент <> Неопределено Тогда
    // Колонка отображена на форме
КонецЕсли;

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

Резюме и рекомендации

Подведем итог нашему анализу:

Выбор конкретного метода зависит от архитектуры вашей обработки, но использование универсальных функций БСП или способа со структурами является наиболее стабильным решением для современных версий платформы 1С.

← На главную