Как правильно определить и изменить текущую страницу в управляемых формах при программном скрытии вкладок?

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

В практике разработки на платформе 1С:Предприятие 8.3 с использованием управляемых форм (УФ) программисты часто сталкиваются с неприятной особенностью: свойство ТекущаяСтраница у группы страниц ведет себя непредсказуемо, если изменять видимость закладок программно. Например, если при открытии формы мы скрываем лишние страницы, устанавливая Видимость = Ложь, то визуально пользователь видит одну страницу, а в программном коде свойство продолжает ссылаться на другую (скрытую). Рассмотрим подробнее, почему это происходит и как решить данную проблему.

Анализируем причину десинхронизации

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

Важные нюансы работы платформы:

  1. Программная модель vs UI: Свойство ТекущаяСтраница — это указатель в программной модели. Пока вы явно не измените его в коде, платформа может отображать одну страницу, но считать «текущей» совершенно другую.
  2. Событие ПриСменеСтраницы: Данное событие является исключительно интерактивным. Оно срабатывает только тогда, когда пользователь физически нажимает мышкой на закладку. Любые программные манипуляции (изменение видимости или даже прямое присвоение новой текущей страницы) это событие не вызывают.
  3. Потеря фокуса: Если ТекущаяСтраница ссылается на невидимый элемент, это часто приводит к потере фокуса ввода. В результате перестают работать горячие клавиши (например, Ins для добавления строки в таблицу или Del для удаления), так как система не понимает, какой активный элемент сейчас находится в фокусе.

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

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

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


Процедура УстановитьВидимостьЗакладки(ЭлЗакладка, Видимость, Доступность)
    
    // Если мы включаем страницу, просто устанавливаем свойства и выходим
    Если Видимость и Доступность Тогда
        ЭлЗакладка.Видимость = Видимость;
        ЭлЗакладка.Доступность = Доступность;
        Возврат;
    КонецЕсли;
    
    ГрЗакладки = ЭлЗакладка.Родитель;
    
    // Если скрываемая страница НЕ является текущей, скрываем её без лишних действий
    Если ЭлЗакладка <> ГрЗакладки.ТекущаяСтраница Тогда
        ЭлЗакладка.Видимость = Видимость;
        ЭлЗакладка.Доступность = Доступность;
        Возврат;
    КонецЕсли;
        
    // Если же мы пытаемся скрыть ТЕКУЩУЮ страницу, нужно найти ей замену
    Подчиненные = ГрЗакладки.ПодчиненныеЭлементы;
    Колич = Подчиненные.Количество();
    ИндексТекущей = Подчиненные.Индекс(ЭлЗакладка);
    
    // Циклический перебор всех страниц в группе для поиска первой видимой
    Для Смещение = 1 По Колич - 1 Цикл
        ПроверитьЭту = Подчиненные[(ИндексТекущей + Смещение) % Колич];
        Если ПроверитьЭту.Видимость и ПроверитьЭту.Доступность Тогда
            // Явно устанавливаем новую текущую страницу до того, как скроем старую
            ГрЗакладки.ТекущаяСтраница = ПроверитьЭту;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Теперь безопасно скрываем страницу
    ЭлЗакладка.Видимость = Видимость;
    ЭлЗакладка.Доступность = Доступность;
КонецПроцедуры

Разберем работу алгоритма по шагам

Рассмотрим, как работает предложенный метод:

  1. Проверка контекста: Процедура получает объект страницы, которую мы хотим скрыть. Сначала она проверяет, не является ли эта страница уже активной (свойство ТекущаяСтраница родительской группы).
  2. Поиск альтернативы: Если мы скрываем именно активную вкладку, код обращается к коллекции ПодчиненныеЭлементы. Используя оператор остатка от деления %, алгоритм реализует «кольцевой» поиск: он просматривает все соседние вкладки, пока не найдет ту, которая одновременно и видима, и доступна.
  3. Программная активация: Найденная страница назначается текущей. Это критически важный момент: мы сами управляем логикой интерфейса, не полагаясь на автоматику платформы.
  4. Установка фокуса: После выполнения этой процедуры платформа корректно передаст фокус на новую страницу, что позволит избежать проблем с работой горячих клавиш Ins и Del в табличных частях.

Дополнительные рекомендации

Проанализировав поведение управляемых форм, можно выделить еще несколько важных правил:

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

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

Использование ТекущийЭлемент. Если после программного переключения страниц вам нужно, чтобы курсор встал в конкретное поле на новой странице, не забудьте после установки ТекущаяСтраница явно прописать: ЭтаФорма.ТекущийЭлемент = Элементы.ИмяНужногоПоля;.

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

← На главную