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