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

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

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

Проблема контекста: почему Метаданные не работают на клиенте

Прежде всего, проанализируем ситуацию, с которой сталкиваются многие разработчики. Попытка обратиться к свойству Метаданные из клиентской процедуры приведет к ошибке, так как этот объект доступен исключительно на стороне сервера. Аналогично, метод формы ПолучитьРеквизиты(), возвращающий массив описаний реквизитов, также является серверным.

Если нам нужно выполнить проверку именно на стороне клиента (например, чтобы избежать лишнего контекстного вызова сервера ради одной проверки), у нас остается не так много вариантов. Основная сложность заключается в том, что коллекция реквизитов формы на клиенте не представлена как явный объект, который можно перебрать циклом Для Каждого.

Способ 1: Использование конструкции Попытка — Исключение

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

Рассмотрим пример реализации универсальной функции, которую можно разместить в клиентском общем модуле или непосредственно в модуле формы:


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

Важный нюанс: обращение к реквизиту через квадратные скобки Форма["ИмяРеквизита"] позволяет динамически передавать строку с именем. Это делает код гибким и пригодным для универсальных алгоритмов.

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

Если ваша конфигурация построена на базе БСП, то писать свои "костыли" не обязательно. Разработчики фирмы "1С" уже предусмотрели стандартные методы для таких проверок. В общем модуле ОбщегоНазначенияКлиент существует готовая функция.

Проанализируем её использование:


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

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

Способ 3: Отличие реквизитов от элементов формы

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

Разберем, как проверить наличие элемента управления на клиенте:


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

Метод Найти() коллекции элементов формы прекрасно работает на клиенте и возвращает Неопределено, если объект не найден, что позволяет избежать прерывания выполнения кода. Для практического изучения работы с элементами интерфейса подойдёт пример динамического добавления и удаления элементов формы.

Ловушка экспортных переменных: на что стоит обратить внимание

Существует критически важный нюанс, который был упомянут в обсуждении темы. Если в модуле формы объявлена переменная с ключевым словом Экспорт в разделе описания переменных, то при обращении Форма["ИмяПеременной"] на клиенте она будет вести себя точно так же, как реквизит формы.

Выясним причину этого поведения: платформа 1С включает экспортные переменные модуля в состав свойств объекта формы, доступных извне. Это означает, что метод через Попытку или функцию БСП вернет Истина и для реального реквизита, и для экспортной переменной, и даже для команд формы.

Как быть, если нужно отличить именно реквизит?

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

Программно созданные реквизиты

Рассмотрим ситуацию, когда реквизиты добавляются на форму динамически в процедуре ПриСозданииНаСервере или через команду. Поскольку они создаются на сервере, после передачи контекста на клиент они становятся частью объекта формы. Проверка через Попытку для них будет работать корректно. Для упрощения такой доработки подойдёт конструктор для программной модификации форм.

Однако помните: на клиенте вы не сможете узнать Тип программно созданного реквизита, если он еще не заполнен значением. Функция ТипЗнч() вернет тип текущего значения, но не описание типов из метаданных.

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

Подводя итог нашему анализу, выделим основные правила проверки реквизитов на клиенте:

  1. Для быстрой проверки "существует ли свойство" без ухода на сервер используйте Попытка...Исключение или ОбщегоНазначенияКлиент.ЕстьСвойствоОбъекта().
  2. Если вам важно визуальное наличие поля на форме — всегда используйте Элементы.Найти().
  3. Если необходимо получить детальную информацию о реквизите (его составной тип, является ли он основным реквизитом и т.д.) — используйте серверную процедуру и метод ПолучитьРеквизиты().
  4. Будьте осторожны с именованием: экспортные переменные модуля формы могут "маскироваться" под реквизиты при проверке через клиентский контекст.

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

← На главную