Как реализовать условную видимость вкладки в форме 1С в зависимости от вызывающего документа?

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

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

Представим ситуацию: у нас есть универсальная форма «РегистрацияСерийТоваров», которая используется для ввода и выбора серий как в документах прихода (например, «ПриходныйОрдерНаТовары»), так и в документах расхода (например, «РасходныйОрдерНаТовары»). Эта форма содержит две основные вкладки: «Ввод серий» и «Выбор». Наша задача состоит в том, чтобы вкладка «Ввод серий» была недоступна (скрыта) только в том случае, если форма вызывается из документа «РасходныйОрдерНаТовары», но при этом оставалась видимой при вызове из «ПриходногоОрдераНаТовары».

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

Причина неэффективности прямых изменений в расширении

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

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

Решение проблемы: Передача параметров и их проверка на сервере

Основная идея заключается в том, чтобы при вызове формы «РегистрацияСерийТоваров» из документа «РасходныйОрдерНаТовары» передать специальный параметр, который будет указывать на тип вызывающего документа. Затем, в самой форме «РегистрацияСерийТоваров», мы проанализируем этот параметр в серверном обработчике ПриСозданииНаСервере и на его основе примем решение о видимости вкладки.

  1. Шаг 1: Изменяем процедуру вызова формы в документе «РасходныйОрдерНаТовары»

    Начнем с документа «РасходныйОрдерНаТовары». В этом документе, как правило, есть клиентская процедура, которая отвечает за открытие формы регистрации серий. В нашем случае это процедура ОткрытьПодборСерий. Мы добавим в структуру параметров, передаваемых форме, дополнительное свойство, которое будет однозначно идентифицировать документ-владелец.

    Найдите в модуле формы документа «РасходныйОрдерНаТовары» процедуру ОткрытьПодборСерий. В этой процедуре формируется структура ПараметрыФормыУказанияСерий, которая затем передается в метод ОткрытьФорму. Именно в эту структуру нам нужно добавить наш флаг.

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

    Мы использовали метод Вставить() для добавления нового свойства ВидДокумента со строковым значением "РасходныйОрдерНаТовары". Теперь, когда форма «РегистрацияСерийТоваров» будет открываться из «РасходногоОрдераНаТовары», она будет получать этот параметр.

  2. Шаг 2: Модифицируем обработчик «ПриСозданииНаСервере» в форме «РегистрацияСерийТоваров»

    Следующий шаг — обработать переданный параметр в форме «РегистрацияСерийТоваров». Наилучшим местом для этого является серверный обработчик ПриСозданииНаСервере. Эта процедура выполняется один раз при создании формы на сервере, до того как форма будет отображена пользователю на клиенте, и в ней доступны все переданные при открытии формы параметры.

    Найдите процедуру ПриСозданииНаСервере в модуле формы «РегистрацияСерийТоваров» и добавьте в нее следующий код:

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

    Здесь мы сначала проверяем, существует ли переданный параметр ВидДокумента с помощью метода Свойство(), а затем сравниваем его значение. Если значение совпадает с "РасходныйОрдерНаТовары", мы устанавливаем свойство Видимость элемента формы СтраницаВводСерии в значение Ложь. Это приведет к тому, что данная вкладка будет полностью скрыта от пользователя.

Альтернативный подход: Использование параметра «Регистратор»

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


Регистратор = Параметры.Регистратор;

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // ... существующий код ...

    Если Параметры.Свойство("Регистратор") Тогда
        // Проверяем тип документа-регистратора
        Если ТипЗнч(Параметры.Регистратор) = Тип("ДокументСсылка.РасходныйОрдерНаТовары") Тогда
            Элементы.СтраницаВводСерии.Видимость = Ложь;
        КонецЕсли;
    КонецЕсли;

    // ... остальной существующий код обработки формы ...
КонецПроцедуры

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

Важность выбора места для проверки параметров

Мы выяснили, что процедура ПриСозданииНаСервере является оптимальным местом для проверки параметров и управления элементами формы. Почему это так важно?

Различия между Видимость, Доступность и ТолькоПросмотр

В контексте управления элементами формы важно понимать разницу между этими тремя свойствами:

В данной задаче требовалось именно «снятие доступности вкладки», но при этом подразумевалось ее полное сокрытие. Соответственно, использование Видимость = Ложь является корректным решением для достижения желаемого эффекта.

Использование расширений конфигурации

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

Явное объявление параметров формы

Для улучшения читаемости и поддержки кода, а также для предотвращения возможных ошибок, связанных с отсутствием параметров, рекомендуется явно объявлять параметры формы в конфигураторе. На вкладке «Параметры» в редакторе формы «РегистрацияСерийТоваров» мы можем добавить новый параметр, например, с именем ВидДокумента и типом Строка. В этом случае в коде процедуры ПриСозданииНаСервере нам не потребуется дополнительно проверять наличие свойства у структуры Параметры с помощью Параметры.Свойство("ВидДокумента"), поскольку платформа гарантирует его существование (пусть даже с пустым значением, если параметр не был передан).

Влияние на производительность

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

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

← На главную