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