Как проверить наличие программно добавленного реквизита в управляемой форме 1С

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

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

Метод 1: Проверка через коллекцию описаний реквизитов

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

Рассмотрим пример функции, которая возвращает булево значение в зависимости от наличия реквизита:


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

Преимущества этого метода:

  1. Он работает непосредственно с метаданными формы в памяти сервера.
  2. Игнорируются экспортные переменные модуля формы, которые не являются реквизитами.
  3. Метод безопасен и не вызывает исключений.

Важный нюанс: Метод ПолучитьРеквизиты() доступен только в серверном контексте. Если вам нужно выполнить проверку на клиенте, придется организовать вызов серверной функции.

Метод 2: Использование структуры и функции ЗаполнитьЗначенияСвойств

Существует более компактный, хотя и несколько «хитрый» способ проверки, основанный на механизме отражения свойств объектов. В 1С управляемая форма может выступать источником данных для метода ЗаполнитьЗначенияСвойств. Разберем этот прием подробнее.

Суть метода заключается в создании «зонда» — структуры, в которой ключ совпадает с именем искомого реквизита, а значением является уникальный идентификатор. Если после выполнения команды ЗаполнитьЗначенияСвойств значение в структуре изменилось, значит, реквизит на форме существует и его значение было скопировано.


&НаСервере
Функция ПроверитьНаличиеРеквизитаЧерезСтруктуру(ИмяПараметра)
    
    Маркер = Новый УникальныйИдентификатор;
    СтруктураЗонд = Новый Структура(ИмяПараметра, Маркер);
    
    // Пытаемся заполнить структуру из свойств формы
    ЗаполнитьЗначенияСвойств(СтруктураЗонд, ЭтаФорма);
    
    // Если значение ключа осталось равно Маркеру, значит реквизит не найден
    Если СтруктураЗонд[ИмяПараметра] = Маркер Тогда
        Возврат Ложь;
    Иначе
        Возврат Истина;
    КонецЕсли;
    
КонецФункции

Этот способ часто выбирают за лаконичность. Однако стоит помнить, что он может среагировать на экспортную переменную модуля формы, если её имя совпадает с ИмяПараметра, так как ЗаполнитьЗначенияСвойств видит все доступные свойства объекта.

Метод 3: Оптимизация через использование Параметров формы

Выясним причину, по которой нам вообще требуется создавать динамические реквизиты. Если основная цель — хранение данных, переданных при открытии формы, то правильнее будет использовать стандартный механизм параметров. Рассмотрим альтернативный подход, который избавляет от необходимости динамического изменения схемы формы.

В конфигураторе можно заранее добавить параметр в список параметров формы. Но даже если параметр не описан в метаданных, его можно передать в структуре при вызове ОткрытьФорму. Чтобы данные «жили» внутри формы, мы можем поступить так:

  1. Создать в форме один фиксированный реквизит с типом Произвольный (назовем его ДополнительныеДанные).
  2. В процедуре ПриСозданииНаСервере помещать туда структуру со всеми нужными значениями.

В этом случае проверка наличия данных сводится к простой работе со структурой:


Если ЭтаФорма.ДополнительныеДанные.Свойство("МойПараметр") Тогда
    // Действие с параметром
КонецЕсли;

Этот путь гораздо производительнее, так как вызов метода ИзменитьРеквизиты() — это очень «тяжелая» операция для платформы. Она заставляет сервер полностью пересобрать контекст формы и отправить его на клиент, что вызывает мерцание интерфейса и задержки.

Почему не стоит использовать Попытка...Исключение?

Проанализируем ситуацию с использованием перехвата ошибок. Многие разработчики используют такой код:


Попытка
    Значение = ЭтаФорма.МойРеквизит;
Исключение
    // Реквизита нет
КонецПопытки;

Мы крайне не рекомендуем такой подход по следующим причинам:

Отличие реквизитов от элементов формы

Часто начинающие программисты путают понятия реквизит (данные) и элемент (визуальное поле на форме). Если ваша задача — проверить, выведено ли на экран поле ввода, созданное программно, то проверка выполняется через коллекцию элементов, и она доступна как на сервере, так и на клиенте:


Если ЭтаФорма.Элементы.Найти("ИмяПоляВвода") <> Неопределено Тогда
    // Элемент существует
КонецЕсли;

Помните, что наличие элемента не гарантирует наличие реквизита с тем же именем, так как элемент может быть связан с путем к данным вида Объект.ИмяРеквизита.

Резюме

Мы рассмотрели несколько способов проверки. Подведем итог:

← На главную