В практике разработки на платформе 1С:Предприятие 8.3 с использованием управляемых форм (УФ) программисты часто сталкиваются с неприятной особенностью: свойство ТекущаяСтраница у группы страниц ведет себя непредсказуемо, если изменять видимость закладок программно. Например, если при открытии формы мы скрываем лишние страницы, устанавливая Видимость = Ложь, то визуально пользователь видит одну страницу, а в программном коде свойство продолжает ссылаться на другую (скрытую). Рассмотрим подробнее, почему это происходит и как решить данную проблему.
Разберем ситуацию: когда мы программно скрываем активную в данный момент страницу, платформа 1С автоматически перерисовывает интерфейс, переключая пользователя на первую доступную видимую вкладку. Однако это «визуальное» переключение происходит только в графической оболочке. Программный объект формы на стороне сервера или клиента при этом не обновляет значение свойства ТекущаяСтраница.
Важные нюансы работы платформы:
ТекущаяСтраница — это указатель в программной модели. Пока вы явно не измените его в коде, платформа может отображать одну страницу, но считать «текущей» совершенно другую.ТекущаяСтраница ссылается на невидимый элемент, это часто приводит к потере фокуса ввода. В результате перестают работать горячие клавиши (например, Ins для добавления строки в таблицу или Del для удаления), так как система не понимает, какой активный элемент сейчас находится в фокусе.Чтобы избежать ошибок в работе команд формы и корректно управлять состоянием интерфейса, мы не должны просто устанавливать Видимость = Ложь. Нам необходимо сначала проверить, не является ли скрываемая страница текущей, и если является — принудительно переключить фокус на другую видимую страницу.
Проанализируем пример кода, который решает эту задачу универсально для любой группы страниц:
Процедура УстановитьВидимостьЗакладки(ЭлЗакладка, Видимость, Доступность)
// Если мы включаем страницу, просто устанавливаем свойства и выходим
Если Видимость и Доступность Тогда
ЭлЗакладка.Видимость = Видимость;
ЭлЗакладка.Доступность = Доступность;
Возврат;
КонецЕсли;
ГрЗакладки = ЭлЗакладка.Родитель;
// Если скрываемая страница НЕ является текущей, скрываем её без лишних действий
Если ЭлЗакладка <> ГрЗакладки.ТекущаяСтраница Тогда
ЭлЗакладка.Видимость = Видимость;
ЭлЗакладка.Доступность = Доступность;
Возврат;
КонецЕсли;
// Если же мы пытаемся скрыть ТЕКУЩУЮ страницу, нужно найти ей замену
Подчиненные = ГрЗакладки.ПодчиненныеЭлементы;
Колич = Подчиненные.Количество();
ИндексТекущей = Подчиненные.Индекс(ЭлЗакладка);
// Циклический перебор всех страниц в группе для поиска первой видимой
Для Смещение = 1 По Колич - 1 Цикл
ПроверитьЭту = Подчиненные[(ИндексТекущей + Смещение) % Колич];
Если ПроверитьЭту.Видимость и ПроверитьЭту.Доступность Тогда
// Явно устанавливаем новую текущую страницу до того, как скроем старую
ГрЗакладки.ТекущаяСтраница = ПроверитьЭту;
Прервать;
КонецЕсли;
КонецЦикла;
// Теперь безопасно скрываем страницу
ЭлЗакладка.Видимость = Видимость;
ЭлЗакладка.Доступность = Доступность;
КонецПроцедуры
Рассмотрим, как работает предложенный метод:
ТекущаяСтраница родительской группы).ПодчиненныеЭлементы. Используя оператор остатка от деления %, алгоритм реализует «кольцевой» поиск: он просматривает все соседние вкладки, пока не найдет ту, которая одновременно и видима, и доступна.Ins и Del в табличных частях.Проанализировав поведение управляемых форм, можно выделить еще несколько важных правил:
Вызов обработчиков вручную. Так как программная смена страницы не вызывает событие ПриСменеСтраницы, если у вас в этом обработчике написана важная логика (например, расчет итогов или заполнение данных), вам необходимо вызвать эту процедуру из своего кода явно сразу после изменения свойства ТекущаяСтраница.
Место вызова (Сервер vs Клиент). Настройку видимости страниц лучше всего выполнять в процедуре ПриСозданииНаСервере. Однако окончательную установку ТекущаяСтраница для корректного позиционирования фокуса иногда эффективнее делать в ПриОткрытии на клиенте, когда форма уже полностью инициализирована в контексте пользователя.
Использование ТекущийЭлемент. Если после программного переключения страниц вам нужно, чтобы курсор встал в конкретное поле на новой странице, не забудьте после установки ТекущаяСтраница явно прописать: ЭтаФорма.ТекущийЭлемент = Элементы.ИмяНужногоПоля;.
Таким образом, использование правильного порядка действий — сначала выбор новой активной страницы, а затем скрытие старой — гарантирует стабильную работу интерфейса и предсказуемое поведение программного кода в управляемом приложении.