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

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

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

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

Причина поведения: как формируется параметр Уникальность

В типовых конфигурациях (например, УТ 11, КА, ERP) в модулях команд используется следующий типовой код:


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

Значение ПараметрыВыполненияКоманды.Уникальность генерируется платформой «1С:Предприятие» динамически в момент интерактивного клика по кнопке интерфейса командной панели. В платформе нет отдельного метода, позволяющего заранее прочитать системный идентификатор команды интерфейса до её нажатия. Если открыть форму методом ОткрытьФорму с пустым или произвольным ключом уникальности, платформа воспринимает её как независимую форму и не сопоставляет с последующим вызовом интерактивной команды.

Решение 1. Открытие через навигационную ссылку (рекомендуемый способ)

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

Посмотрим на пример программного вызова команды открытия списка:


// Открытие списка через вызов команды объекта
ПерейтиПоНавигационнойСсылке("e1cib/command/Документ.ЗаказКлиента.Команда.ЗаказыКлиентов");

// Либо открытие стандартного списка объекта метаданных
ПерейтиПоНавигационнойСсылке("e1cib/list/Документ.ЗаказКлиента");

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

Решение 2. Программный поиск и активизация уже открытого окна

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

Рассмотрим пример функции для поиска и переключения на существующую форму:


&НаКлиенте
Процедура АктивизироватьФормуСписка(ИмяИскомойФормы)
    
    ОкнаПриложения = ПолучитьОкна();
    Для Каждого ТекОкно Из ОкнаПриложения Цикл
        Для Каждого ТекФорма Из ТекОкно.Содержимое Цикл
            Если ТекФорма.ИмяФормы = ИмяИскомойФормы Тогда
                ТекОкно.Активизировать();
                Возврат;
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
    // Если форма не найдена среди открытых — открываем новую
    ОткрытьФорму(ИмяИскомойФормы);
    
КонецПроцедуры

Решение 3. Групповое автооткрытие форм при старте и возврат на начальную страницу

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

Разберем пример такой реализации:


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

&НаКлиенте
Процедура АктивизироватьНачальнуюСтраницу() Экспорт
    
    ОкнаПриложения = ПолучитьОкна();
    Для Каждого ТекОкно Из ОкнаПриложения Цикл
        Если ТекОкно.НачальнаяСтраница Тогда
            ТекОкно.Активизировать();
            Если ТекОкно.Содержимое.Количество() > 0 Тогда
                ТекОкно.Содержимое[0].Активизировать();
            КонецЕсли;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

Ограничения перехвата команд через расширения конфигурации

При попытке переопределить модуль команды через механизм расширений с помощью аннотации &Вместо("ОбработкаКоманды") разработчики могут столкнуться с синтаксической ошибкой валидации модуля. Выясним причину этой проблемы:

  1. Модули команд не поддерживали перехват процедур аннотациями &Вместо, &Перед, &После в ранних версиях платформы (при режиме совместимости 8.3.8 и ниже).
  2. Для корректного расширения модулей команд режим совместимости как основной конфигурации, так и расширения должен быть не ниже версии, поддерживающей данный функционал.
  3. Если конфигурация находится на поддержке без возможности снятия режима совместимости, наиболее стабильным решением остается использование навигационных ссылок через ПерейтиПоНавигационнойСсылке.
← На главную