При разработке управляемых форм в 1С:Предприятии 8.3 программисты часто сталкиваются с ситуацией, когда программное изменение свойства Видимость не срабатывает или вызывает исключение «Поле объекта не обнаружено». Разберем основные причины такого поведения и рассмотрим правильные варианты реализации логики видимости элементов.
Проанализируем две ключевые проблемы, из-за которых условие отображения элементов формы не выполняется:
ВалютаДокумента) имеет ссылочный тип СправочникСсылка.Валюты, прямое сравнение со строкой ВалютаДокумента = "EUR*" всегда возвращает значение Ложь. Ссылка и строка — это разные типы, даже если в пользовательском интерфейсе представление ссылки полностью совпадает с текстом.СправочникСсылка содержит только идентификатор и строковое представление. При попытке обратиться к реквизитам связанных объектов через точку (например, Объект.Рейс.НомерРейса.Международный) в клиентском контексте платформа выдает ошибку «Поле объекта не обнаружено», так как неявные обращения к базе данных с клиента запрещены.Наиболее производительным и архитектурно правильным подходом является настройка видимости элементов формы в серверном обработчике ПриСозданииНаСервере. На сервере доступны все реквизиты объектов и возможность чтения данных по ссылке без дополнительных вызовов.
Посмотрим на пример правильной проверки значения реквизита на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наименование валюты и цепочку реквизитов на сервере
Если Объект.ВалютаДокумента.Наименование = "EUR*" И Объект.Рейс.НомерРейса.Международный Тогда
Элементы.СуммаВсегоРуб.Видимость = Истина;
Иначе
Элементы.СуммаВсегоРуб.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
Разберем подробнее: обращение через точку к реквизитам Объект.Рейс.НомерРейса.Международный на сервере выполняется платформой в рамках прямого запроса к СУБД, что исключает ошибки контекста выполнения.
Если состояние формы должно меняться на лету при выборе пользователем значений в полях (например, при смене валюты или рейса), выделим логику управления видимостью в отдельную процедуру.
Рассмотрим реализацию через обработчик изменения на клиенте с вызовом серверного контекста без контекста формы (для минимизации объема передаваемых данных):
&НаКлиенте
Процедура ВалютаДокументаПриИзменении(Элемент)
ОбновитьВидимостьЭлементов();
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьВидимостьЭлементов()
// Получаем необходимые признаки за один серверный вызов
ДанныеФормы = ПолучитьПараметрыВидимостиНаСервере(Объект.ВалютаДокумента, Объект.Рейс);
Элементы.СуммаВсегоРуб.Видимость = (ДанныеФормы.ЭтоЕвро И ДанныеФормы.Международный);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьПараметрыВидимостиНаСервере(Знач СсылкаВалюта, Знач СсылкаРейс)
Результат = Новый Структура;
Результат.Вставить("ЭтоЕвро", Ложь);
Результат.Вставить("Международный", Ложь);
Если ЗначениеЗаполнено(СсылкаВалюта) Тогда
Результат.ЭтоЕвро = (СсылкаВалюта.Наименование = "EUR*");
КонецЕсли;
Если ЗначениеЗаполнено(СсылкаРейс) Тогда
Результат.Международный = СсылкаРейс.НомерРейса.Международный;
КонецЕсли;
Возврат Результат;
КонецФункции
Если в конфигурации используется Библиотека стандартных подсистем (БСП), выясним причину отказаться от ручных функций чтения реквизитов. С помощью общего модуля ОбщегоНазначения можно безопасно и быстро считывать реквизиты ссылок:
&НаСервере
Процедура УстановитьВидимостьПоБСП()
// Получаем наименование валюты через БСП
ИмяВалюты = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.ВалютаДокумента, "Наименование");
// Считываем реквизит связанного справочника
ПризнакМеждународный = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.Рейс.НомерРейса, "Международный");
Элементы.СуммаВсегоРуб.Видимость = (ИмяВалюты = "EUR*" И ПризнакМеждународный = Истина);
КонецПроцедуры
Строка(ВалютаДокумента) = "EUR*" как постоянное решение. Данный способ является ненадежным временным решением (костылем), так как изменение формата представления валюты или языка интерфейса нарушит работу условия.НайтиПоНаименованию. Если в справочнике валют изменится наименование или появятся скрытые пробелы, код перестанет работать. Рекомендуется выполнять привязку к предопределенным элементам, кодам Общероссийского классификатора валют (ОКВ) или перечислениям.