Как открыть форму списка документа с разными предустановленными отборами из меню?

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

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

Разберем детально, как устроена работа метода ОткрытьФорму в управляемом приложении, как накладывать условия фильтрации и как правильно управлять уникальностью окон интерфейса.

Базовый способ: передача структуры в системный параметр «Отбор»

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

Посмотрим на пример процедур клиентского контекста:


&НаКлиенте
Процедура ОткрытьФормуСпискаСОтбором1()
    ЗначениеОтбора = Новый Структура("Реквизит", Перечисления.ВидыОпераций.Значение1);
    ПараметрыВыбора = Новый Структура("Отбор", ЗначениеОтбора);
    ОткрытьФорму("Документ.НашДокумент.ФормаСписка", ПараметрыВыбора);
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФормуСпискаСОтбором2()
    ЗначениеОтбора = Новый Структура("Реквизит", Перечисления.ВидыОпераций.Значение2);
    ПараметрыВыбора = Новый Структура("Отбор", ЗначениеОтбора);
    ОткрытьФорму("Документ.НашДокумент.ФормаСписка", ПараметрыВыбора);
КонецПроцедуры

При таком подходе проявляется характерное поведение: если список уже открыт по первому пункту меню, то повторный вызов второго пункта просто активирует уже существующее окно и отбор не поменяется. Кроме того, установленное условие блокируется для изменения пользователем в панели настроек списка.

Решение проблемы одновременного открытия: параметр «Уникальность»

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

Если мы передаем в качестве параметра Уникальность произвольный идентификатор (ключ), платформа проверяет: если форма с таким ключом уже открыта — она активируется; если формы с таким ключом нет — открывается новое окно.

Объединим код в универсальную процедуру с параметризацией ключа уникальности:


&НаКлиенте
Процедура КомандаТовары(Команда)
    ОткрытьФормуСпискаСОтбором("Товар");
КонецПроцедуры

&НаКлиенте
Процедура КомандаУслуги(Команда)
    ОткрытьФормуСпискаСОтбором("Услуга");
КонецПроцедуры

&НаКлиенте
Процедура ОткрытьФормуСпискаСОтбором(ИмяОтбора)
    УсловияОтбора = Новый Структура(
        "ВидНоменклатуры", 
        ПредопределенноеЗначение("Перечисление.ВидыНоменклатуры." + ИмяОтбора)
    );
    ПараметрыФормы = Новый Структура("Отбор", УсловияОтбора);
    
    // Ключ уникальности позволяет держать открытыми оба варианта списков одновременно
    КлючУникальности = "Список_" + ИмяОтбора;
    
    ОткрытьФорму(
        "Документ.НашДокумент.ФормаСписка", 
        ПараметрыФормы, 
        ЭтотОбъект, 
        КлючУникальности
    );
КонецПроцедуры

Если передать в параметр Уникальность значение Истина, новое окно будет создаваться при каждом нажатии кнопки меню без поиска ранее созданных экземпляров.

Управление доступностью отбора: пользовательский или фиксированный

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

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

Рекомендации по улучшению интерфейса

Для создания полноценного и интуитивно понятного интерфейса разберем сопутствующие настройки, которые сделают работу пользователя удобной:

  1. Размещение команд в интерфейсе: Вместо написания кода в модуле приложения или общих модулях используйте объект метаданных Команда (общие команды или команды документа). В обработчике команды ОбработкаКоманды(ПараметрыКоманды, ПараметрыВыполненияКоманды) вызывайте процедуру открытия формы. Это позволит гибко разместить ссылки в нужных разделах командного интерфейса.
  2. Автозаполнение нового документа: Чтобы при нажатии кнопки «Создать» в отфильтрованном списке реквизит документа заполнялся автоматически, передавайте в параметрах вызова структуру ЗначенияЗаполнения:
    
    ПараметрыФормы.Вставить("ЗначенияЗаполнения", Новый Структура("ВидНоменклатуры", ЗначениеОтбора));
    
    Платформа автоматически перенесет эти значения в новый документ при создании.
  3. Заголовок окна: Так как пользователь открывает два одинаковых журнала документов, окна на панели задач могут вызывать путаницу. В событии формы ПриСозданииНаСервере рекомендуется переопределять заголовок формы:
    
    АвтоЗаголовок = Ложь;
    Заголовок = "Документы (" + Строка(ЗначениеОтбора) + ")";
    
  4. Создание отдельных форм: Если для разных видов документов состав колонок, видимость реквизитов и наборы кнопок командной панели существенно различаются, предпочтительнее отказаться от единой универсальной формы и создать две отдельные формы списка в конфигураторе (например, ФормаСпискаТовары и ФормаСпискаУслуги).
← На главную