Как динамически изменить форму выбора реквизита в 1С:УФ в зависимости от условий?

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

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

Наш читатель столкнулся с задачей: необходимо, чтобы по субботам для поля "Сотрудники" открывалась другая форма выбора – "ФормаВыбораСуббота". При этом стандартный реквизит формы элемента Элементы.Сотрудники.ФормаВыбора оказался недоступен для прямого программного изменения. Мы выясним, какие методы платформы позволяют решить эту задачу наиболее корректно и универсально.

Основное решение: процедура ОбработкаПолученияФормы в модуле менеджера

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

Давайте посмотрим на синтаксис этой процедуры:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    // Ваш код здесь
КонецПроцедуры

Разберем параметры этой процедуры, чтобы понять, как мы можем с ними работать:

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

Принцип работы прост: чтобы переопределить открываемую форму, мы должны проверить ВидФормы, установить в параметре ВыбраннаяФорма другое имя формы или объект метаданных формы, а в параметре СтандартнаяОбработка установить значение Ложь. Тогда платформа откроет указанную нами форму.

Пример реализации задачи

Давайте посмотрим, как мы можем применить этот подход для решения исходной задачи – открытия "ФормаВыбораСуббота" для справочника "Сотрудники" по субботам. Код необходимо разместить в модуле менеджера справочника "Сотрудники":


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    // Проверяем, что запрашивается именно форма выбора и текущий день - суббота
    Если ВидФормы = "ФормаВыбора" И ДеньНедели(ТекущаяДата()) = 7 Тогда // 7 - это суббота
        // Отменяем стандартную обработку
        СтандартнаяОбработка = Ложь;
        // Указываем имя нашей специальной формы выбора
        ВыбраннаяФорма = "Справочник.Сотрудники.Форма.ФормаВыбораСуббота";
    КонецЕсли;
КонецПроцедуры

Этот код гарантирует, что при любом запросе на открытие формы выбора для справочника "Сотрудники" (будь то интерактивный выбор из поля на форме или программный вызов ОткрытьФорму), в субботу будет открыта "ФормаВыбораСуббота". Это делает данное решение очень мощным и универсальным, так как оно работает на уровне всей конфигурации для данного объекта, независимо от способа вызова формы выбора.

Почему ОбработкаПолученияФормы – лучший выбор?

Мы выяснили, что процедура ОбработкаПолученияФормы является наиболее "кошерным" (как выразились наши коллеги на форуме) и правильным местом для реализации такой логики. Это связано с несколькими причинами:

  1. Универсальность: Она перехватывает запросы на открытие формы независимо от того, как они были инициированы – интерактивно пользователем через кнопку выбора в поле или программно с помощью функций типа ОткрытьФорму. Это подтверждается обсуждением на форуме, где было отмечено, что даже ОткрытьФорму прилетит в модуль менеджера.
  2. Централизованное управление: Вся логика по выбору формы сосредоточена в одном месте – модуле менеджера объекта. Это упрощает поддержку и анализ кода.
  3. Серверное исполнение: Процедура выполняется на сервере, что позволяет использовать серверные функции и данные без дополнительных вызовов с клиента.

Альтернативные подходы и нюансы

Хотя ОбработкаПолученияФормы является наиболее подходящим решением для глобальной подмены формы выбора, существуют и другие события, которые могут быть использованы для более специфичных или локальных задач. Давайте их рассмотрим, чтобы лучше понять разницу.

Событие ПриНачалеВыбораЗначения

Событие ПриНачалеВыбораЗначения возникает на клиенте перед началом стандартной процедуры выбора значения для конкретного элемента формы. Его можно использовать, если нам нужно:

  1. Открыть другую форму с отбором: Если мы хотим не полностью заменить стандартную форму выбора объекта, а лишь открыть ее (или другую форму списка) с заранее установленными условиями отбора.
  2. Реализовать специфическую логику выбора: Например, перед открытием формы выбора выполнить какие-либо проверки или предоставить пользователю дополнительные варианты выбора.

Для использования ПриНачалеВыбораЗначения необходимо установить СтандартнаяОбработка = Ложь в обработчике события элемента формы и самостоятельно открыть нужную форму с помощью функции ОткрытьФорму(), передав в нее необходимые параметры. Например:


&НаКлиенте
Процедура СотрудникиПриНачалеВыбора(Элемент, СтандартнаяОбработка)
    Если ДеньНедели(ТекущаяДата()) = 7 Тогда
        СтандартнаяОбработка = Ложь;
        ПараметрыОткрытия = Новый Структура("НачальноеЗначениеВыбора", Объект.Сотрудник);
        ОткрытьФорму("Справочник.Сотрудники.Форма.ФормаВыбораСуббота", ПараметрыОткрытия, Элемент);
    КонецЕсли;
КонецПроцедуры

Этот подход работает, но является менее универсальным, чем ОбработкаПолученияФормы, так как требует ручной реализации для каждого элемента формы, где нужна подмена. Если поле "Сотрудники" используется на множестве форм, придется дублировать код или выносить его в общие модули с последующим вызовом.

Событие ПриОткрытии формы выбора

На форуме было предложено "внутри ФормаВыбора ПриОткрытии подменять". Этот вариант подразумевает модификацию кода в обработчике события ПриОткрытии самой формы выбора. Однако это менее гибкое решение, поскольку:

Передача параметров в новую форму

Часто при динамическом открытии формы выбора возникает необходимость передать в нее какие-либо параметры, например, для установки отбора. Мы можем использовать параметр Параметры в процедуре ОбработкаПолученияФормы, чтобы передать структуру с нужными данными. А в самой открываемой форме в обработчике ПриСозданииНаСервере или ПриОткрытии можно будет эти параметры прочитать.


// В модуле менеджера
Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    Если ВидФормы = "ФормаВыбора" И ДеньНедели(ТекущаяДата()) = 7 Тогда
        СтандартнаяОбработка = Ложь;
        ВыбраннаяФорма = "Справочник.Сотрудники.Форма.ФормаВыбораСуббота";
        // Пример передачи параметра
        Параметры.Вставить("ТолькоАктивные", Истина);
    КонецЕсли;
КонецПроцедуры

// В форме "ФормаВыбораСуббота" в ПриСозданииНаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Если Параметры.Свойство("ТолькоАктивные") И Параметры.ТолькоАктивные Тогда
        // Установить отбор в динамическом списке
        Элементы.Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        Элементы.Список.Отбор.Элементы[0].ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Активен");
        Элементы.Список.Отбор.Элементы[0].ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        Элементы.Список.Отбор.Элементы[0].ПравоеЗначение = Истина;
        Элементы.Список.Отбор.Элементы[0].Использование = Истина;
    КонецЕсли;
КонецПроцедуры

Этот пример демонстрирует, как мы можем передать дополнительный параметр ТолькоАктивные из модуля менеджера в новую форму выбора для установки соответствующего отбора.

Работа с отбором для динамического списка

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

Составной тип реквизита

В случае, если реквизит имеет составной тип, и у элемента формы установлено свойство ВыбиратьТип, платформа сначала предложит пользователю выбрать тип объекта, и только потом будет вызван обработчик ОбработкаПолученияФормы. Если свойство ВыбиратьТип отключено, можно самостоятельно реализовать логику выбора типа в ПриНачалеВыбораЗначения и затем открыть нужную форму уже для конкретного типа.

Инициализация формы выбора

Если нам нужно "превратить" обычную форму списка в форму выбора, можно использовать процедуру ИнициализироватьФормуВыбора. Эта процедура устанавливает необходимые свойства, такие как РежимВыбора и МножественныйВыбор, для элемента динамического списка на форме, делая ее функциональной как форму выбора.

Расширения конфигурации

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

Заключение

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

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

← На главную