Как настроить видимость элементов управляемой формы в зависимости от реквизитов объекта и ссылочных данных в 1С?

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

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

Причины возникновения ошибок при проверке условий

Проанализируем две ключевые проблемы, из-за которых условие отображения элементов формы не выполняется:

  1. Сравнение несовместимых типов данных. Если реквизит (например, ВалютаДокумента) имеет ссылочный тип СправочникСсылка.Валюты, прямое сравнение со строкой ВалютаДокумента = "EUR*" всегда возвращает значение Ложь. Ссылка и строка — это разные типы, даже если в пользовательском интерфейсе представление ссылки полностью совпадает с текстом.
  2. Попытка разыменования ссылочных полей на клиенте. На тонком клиенте объект СправочникСсылка содержит только идентификатор и строковое представление. При попытке обратиться к реквизитам связанных объектов через точку (например, Объект.Рейс.НомерРейса.Международный) в клиентском контексте платформа выдает ошибку «Поле объекта не обнаружено», так как неявные обращения к базе данных с клиента запрещены.

Вариант 1. Управление видимостью на сервере при инициализации формы

Наиболее производительным и архитектурно правильным подходом является настройка видимости элементов формы в серверном обработчике ПриСозданииНаСервере. На сервере доступны все реквизиты объектов и возможность чтения данных по ссылке без дополнительных вызовов.

Посмотрим на пример правильной проверки значения реквизита на сервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем наименование валюты и цепочку реквизитов на сервере
    Если Объект.ВалютаДокумента.Наименование = "EUR*" И Объект.Рейс.НомерРейса.Международный Тогда
        Элементы.СуммаВсегоРуб.Видимость = Истина;
    Иначе
        Элементы.СуммаВсегоРуб.Видимость = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Разберем подробнее: обращение через точку к реквизитам Объект.Рейс.НомерРейса.Международный на сервере выполняется платформой в рамках прямого запроса к СУБД, что исключает ошибки контекста выполнения.

Вариант 2. Динамическое управление видимостью при изменении данных

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

Рассмотрим реализацию через обработчик изменения на клиенте с вызовом серверного контекста без контекста формы (для минимизации объема передаваемых данных):


&НаКлиенте
Процедура ВалютаДокументаПриИзменении(Элемент)
    ОбновитьВидимостьЭлементов();
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьВидимостьЭлементов()
    // Получаем необходимые признаки за один серверный вызов
    ДанныеФормы = ПолучитьПараметрыВидимостиНаСервере(Объект.ВалютаДокумента, Объект.Рейс);
    
    Элементы.СуммаВсегоРуб.Видимость = (ДанныеФормы.ЭтоЕвро И ДанныеФормы.Международный);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьПараметрыВидимостиНаСервере(Знач СсылкаВалюта, Знач СсылкаРейс)
    Результат = Новый Структура;
    Результат.Вставить("ЭтоЕвро", Ложь);
    Результат.Вставить("Международный", Ложь);
    
    Если ЗначениеЗаполнено(СсылкаВалюта) Тогда
        Результат.ЭтоЕвро = (СсылкаВалюта.Наименование = "EUR*");
    КонецЕсли;
    
    Если ЗначениеЗаполнено(СсылкаРейс) Тогда
        Результат.Международный = СсылкаРейс.НомерРейса.Международный;
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

Вариант 3. Использование функций БСП для пакетного чтения реквизитов

Если в конфигурации используется Библиотека стандартных подсистем (БСП), выясним причину отказаться от ручных функций чтения реквизитов. С помощью общего модуля ОбщегоНазначения можно безопасно и быстро считывать реквизиты ссылок:


&НаСервере
Процедура УстановитьВидимостьПоБСП()
    
    // Получаем наименование валюты через БСП
    ИмяВалюты = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.ВалютаДокумента, "Наименование");
    
    // Считываем реквизит связанного справочника
    ПризнакМеждународный = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.Рейс.НомерРейса, "Международный");
    
    Элементы.СуммаВсегоРуб.Видимость = (ИмяВалюты = "EUR*" И ПризнакМеждународный = Истина);
    
КонецПроцедуры

Рекомендации и правила надежного кода

  1. Не выполняйте строковое приведение ссылок на клиенте вида Строка(ВалютаДокумента) = "EUR*" как постоянное решение. Данный способ является ненадежным временным решением (костылем), так как изменение формата представления валюты или языка интерфейса нарушит работу условия.
  2. Избегайте поиска по строковому наименованию через НайтиПоНаименованию. Если в справочнике валют изменится наименование или появятся скрытые пробелы, код перестанет работать. Рекомендуется выполнять привязку к предопределенным элементам, кодам Общероссийского классификатора валют (ОКВ) или перечислениям.
  3. Не вызывайте сервер многократно из клиентских событий. Обращение к серверу несколько раз подряд (отдельно за валютой, отдельно за рейсом) снижает производительность системы при открытии формы. Все необходимые данные следует собирать в единую структуру за один серверный вызов.
← На главную