Как избежать перескакивания на первую страницу при установке отбора в управляемой форме 1С?

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

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

Выясняем причину: почему происходит «перескакивание» на первую страницу?

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

  1. Глобальные команды поиска и отбора: Стандартные кнопки командной панели («Найти», «Исключить из поиска», «Отменить поиск») по умолчанию привязаны к основному реквизиту формы.
  2. Принудительная активация: Как только пользователь инициирует команду поиска или открывает окно настройки отбора, платформа программно обращается к основному реквизиту формы. Чтобы отобразить результаты, она обязана активизировать связанный с ним элемент интерфейса (таблицу).
  3. Сброс фокуса: Поскольку таблица основного списка расположена на первой странице, платформа принудительно делает активной именно эту страницу, игнорируя то, что пользователь в данный момент работал со списком на другой вкладке.

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

Решение 1. Использование ОДНОГО динамического списка и «Тумблера» (Стандарт разработки 1С)

Создание нескольких динамических списков под каждый статус — ресурсоемкий подход. Он перегружает сервер лишними запросами, усложняет поддержку кода и приводит к неоправданному расходу оперативной памяти. Фирма «1С» в стандартах разработки (интерфейс «Такси») рекомендует использовать один динамический список и быстрый отбор с помощью элемента управления типа «Тумблер».

Давайте по шагам разберем, как реализовать этот механизм:

  1. Оставим на форме только один динамический список Список и одну таблицу, отображающую его. Никаких вкладок и страниц для разделения списков создавать не нужно.
  2. Создадим новый реквизит формы. Назовем его, например, ОтборСтатус. В качестве типа данных выберем ссылку на соответствующий справочник, перечисление (например, ПеречислениеСсылка.СтатусыДокументов) или простую строку.
  3. Перенесем созданный реквизит ОтборСтатус на форму в область над таблицей динамического списка.
  4. В свойствах появившегося элемента формы установим следующие параметры:
    • Вид: Поле переключателя.
    • Вид переключателя: Тумблер.
  5. Заполним список выбора для тумблера возможными значениями (например: «Все», «Новые», «В работе», «Выполненные»).
  6. Создадим для элемента формы ОтборСтатус обработчик события ПриИзменении.

Теперь напишем программный код, который будет быстро и корректно управлять отбором без перезапуска формы и лишних запросов к базе данных. Для этого мы задействуем функции Библиотеки Стандартных Подсистем (БСП):


&НаКлиенте
Процедура ОтборСтатусПриИзменении(Элемент)
    УстановитьОтборПоСтатусуНаСервере();
КонецПроцедуры

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

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

Решение 2. Использование страниц (вкладок) с ОДНИМ динамическим списком

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

Проанализируем этот сценарий по шагам:

  1. Создадим на форме группу страниц (вкладки). Назовем страницы в соответствии со статусами документов (например, СтраницаНовые, СтраницаВРаботе, СтраницаАрхив).
  2. Важно: Не размещайте таблицы внутри этих страниц! Оставьте страницы пустыми.
  3. Единственную таблицу динамического списка Список разместите на форме непосредственно под группой страниц (или над ней, в зависимости от компоновки интерфейса).
  4. Для группы страниц назначим обработчик события ПриСменеСтраницы. При клике на вкладку мы будем программно менять отбор в нашем единственном списке.

Рассмотрим пример реализации программного кода для этого варианта:


&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)
    УстановитьОтборПриСменеВкладкиНаСервере(ТекущаяСтраница.Имя);
КонецПроцедуры

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

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

Решение 3. Что делать, если динамические списки действительно должны быть разными?

Бывают сложные архитектурные задачи, когда на разных страницах должны отображаться принципиально разные данные, которые невозможно объединить в рамки одного динамического списка (например, на первой вкладке отображаются «Заказы клиентов», а на второй — «Заявки на возврат товаров»).

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

  1. Откроем свойства управляемой формы и отключим автоматическое заполнение командной панели формы (свойство Автозаполнение установим в значение Ложь). Это предотвратит появление глобальных кнопок поиска, ориентированных только на основной реквизит формы.
  2. Для каждой таблицы, расположенной на страницах, создадим свою индивидуальную командную панель (элемент формы Группа - Командная панель).
  3. В свойствах каждой созданной командной панели обязательно укажем свойство ИсточникДействий — выберем соответствующую таблицу этой страницы (например, ТаблицаЗаказы или ТаблицаВозвраты).
  4. Для каждой командной панели установим свойство Автозаполнение в значение Истина. Теперь стандартные кнопки «Найти» и «Отбор» будут жестко привязаны к конкретной таблице на активной вкладке и не вызовут переключения фокуса на первую страницу формы.

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

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

← На главную