Вкладки на управляемой форме 1С: от группы страниц до динамического создания
Содержание
Вкладки на форме 1С — это группа с видом «Страницы», внутри которой лежат группы с видом «Страница». Одна страница — одна вкладка. Добавляется всё в конфигураторе, на закладке «Элементы» редактора формы, за пять кликов.
Ниже речь об управляемых формах платформы 8.3. Сначала соберём вкладки мышкой, потом научимся ими управлять из кода: переключать, скрывать, создавать на лету и ловить смену вкладки.
1. Как добавить вкладки на форму
Откройте форму в конфигураторе и перейдите на закладку «Элементы». Дальше по шагам.
- Выделите корневой элемент формы или ту группу, куда вкладки должны попасть.
- Нажмите «Добавить» (зелёный плюс) и выберите
Группа — Страницы. Платформа создаст элементГруппаСтраницыи сразу положит в него одну страницу. - Выделите созданную группу страниц и снова «Добавить», на этот раз
Страница. Повторите для каждой нужной вкладки. - У каждой страницы задайте «Имя» (латиницей или кириллицей без пробелов — оно нужно для кода) и «Заголовок» (то, что увидит пользователь).
- Перетащите реквизиты формы из правой панели «Реквизиты» внутрь нужных страниц.
Получится иерархия: форма → группа «Страницы» → страницы → поля и таблицы. Всё, что лежит внутри страницы, показывается только когда эта вкладка активна.
Заголовки страниц делайте короткими, одно-два слова: «Основное», «Товары», «Дополнительно». Длинный заголовок раздвигает полосу закладок, и вкладки начинают уезжать за край окна.
Страница не может лежать на форме сама по себе — только внутри группы «Страницы». Если перетащили страницу мимо группы, платформа просто не даст её вставить.
2. Свойства закладок: расположение, оформление, группировка
Выделите ГруппаСтраницы и откройте палитру свойств. Самое полезное:
| Свойство | Что делает |
|---|---|
| «Отображение страниц» | Где рисовать заголовки: сверху, снизу, слева, справа или не рисовать вообще |
| «Отображение» страницы / картинка | Значок рядом с заголовком вкладки |
| «Группировка» страницы | Как вкладка ведёт себя внутри: вертикально, горизонтально или без рамки |
| «Заголовок» | Подпись вкладки (у группы «Страницы» самой заголовка нет) |
| «Подсказка» | Всплывающий текст при наведении |
| «Доступность» и «Видимость» | Включают и выключают вкладку |
Режим «Нет» у отображения страниц — это не ошибка, а приём. Заголовков не видно, переключаться можно только из кода. Так делают мастера и пошаговые формы: вместо закладок пользователь видит кнопки «Далее» и «Назад».
Как расположить элементы внутри вкладки
У каждой страницы есть свойство «Группировка». Если оставить значение по умолчанию, поля идут столбиком. Нужны два столбца — вложите внутрь страницы обычную группу без отображения и поставьте ей горизонтальную группировку, а в неё положите две группы с полями.
Табличные части и динамические списки лучше не прятать в глубину. Одна вкладка — одна большая таблица, иначе пользователь теряется.
Картинки на вкладках
Для страницы можно выбрать картинку из библиотеки стандартных картинок или из собственных общих картинок конфигурации. Значок помогает, когда вкладок больше шести: глаз цепляется за картинку быстрее, чем читает подпись.
3. Как переключать вкладки из кода
Текущую страницу хранит свойство ТекущаяСтраница группы «Страницы». Переключить можно одной строкой:
&НаКлиенте
Процедура ПоказатьТовары(Команда)
Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаТовары;
КонецПроцедуры
Присваивается не имя в кавычках, а сам элемент формы. Строка "СтраницаТовары" не сработает.
Прочитать, какая вкладка открыта сейчас, можно так:
Если Элементы.ГруппаСтраницы.ТекущаяСтраница = Элементы.СтраницаТовары Тогда
// пользователь сейчас на вкладке «Товары»
КонецЕсли;
Куда ставить такой код? Хорошие места: ПриОткрытии (открыть нужную вкладку по параметру формы), обработчик команды или ПриСозданииНаСервере, если вкладка выбирается до показа формы.
В ПриСозданииНаСервере обращение к Элементы.ГруппаСтраницы.ТекущаяСтраница работает, потому что элементы формы уже построены. Но фокус на поле внутри страницы отсюда выставить нельзя — это делается на клиенте, в ПриОткрытии.
Открыть форму сразу на нужной вкладке
Передайте параметр при открытии формы, а в ПриСозданииНаСервере прочитайте его:
// вызов
ПараметрыФормы = Новый Структура("ОткрытьВкладку", "СтраницаДополнительно");
ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта", ПараметрыФормы);
// форма
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОткрытьВкладку") Тогда
Страница = Элементы.Найти(Параметры.ОткрытьВкладку);
Если Страница <> Неопределено Тогда
Элементы.ГруппаСтраницы.ТекущаяСтраница = Страница;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Метод Элементы.Найти вернёт Неопределено, если имени нет, — на этом и строится проверка.
4. Скрыть, показать или заблокировать вкладку
За это отвечают два свойства страницы: Видимость и Доступность.
&НаСервере
Процедура ОбновитьВидимостьВкладок()
Элементы.СтраницаДополнительно.Видимость = ИспользоватьДополнительно;
Элементы.СтраницаСкидки.Доступность = ЕстьПравоНаСкидки;
КонецПроцедуры
Разница простая:
- 🙈
Видимость = Ложь— вкладка исчезает с полосы закладок целиком; - 🔒
Доступность = Ложь— заголовок остаётся серым, а содержимое недоступно для редактирования.
Если скрыть ту страницу, которая сейчас активна, платформа сама переключится на соседнюю. Но надёжнее перед скрытием явно поставить ТекущаяСтраница на другую вкладку, иначе поведение зависит от порядка страниц.
Видимость от функциональных опций и прав
Если вкладка нужна не всем, не пишите код: у любого элемента формы есть свойство «Функциональные опции» (в палитре свойств) и «Доступность по ролям». Платформа сама спрячет вкладку, когда опция выключена или прав нет. Код нужен тогда, когда видимость зависит от данных документа, например от вида операции.
Скрытие вкладки по условию лучше собрать в одну процедуру УстановитьВидимость и вызывать её из ПриСозданииНаСервере и из ПриИзменении нужных реквизитов. Тогда логика лежит в одном месте.
5. Динамические вкладки: создание во время выполнения
Иногда набор вкладок заранее неизвестен: по одной на склад, на организацию, на вид дополнительных сведений. Тогда вкладки добавляют кодом через Элементы.Добавить.
&НаСервере
Процедура ДобавитьВкладку(ИмяВкладки, ЗаголовокВкладки)
Страница = Элементы.Добавить(ИмяВкладки, Тип("ГруппаФормы"), Элементы.ГруппаСтраницы);
Страница.Вид = ВидГруппыФормы.Страница;
Страница.Заголовок = ЗаголовокВкладки;
КонецПроцедуры
Три момента, на которых спотыкаются чаще всего:
- Родителем указывают именно группу «Страницы», а не форму.
- Вид страницы задаётся свойством
Видсо значениемВидГруппыФормы.Страница. - Имя элемента должно быть уникальным и начинаться с буквы:
Склад_1, а не1.
Если саму группу «Страницы» тоже нужно создать в коде, вид для неё берут другой — ВидГруппыФормы.СтраницыФормы.
Поля внутри динамической вкладки
Чтобы на новой вкладке появилось поле, нужен реквизит формы. Его тоже создают кодом: через ИзменитьРеквизиты, а затем добавляют поле с ПутьКДанным.
&НаСервере
Процедура ДобавитьПолеНаВкладку(Страница, ИмяРеквизита, ЗаголовокПоля)
Реквизиты = Новый Массив;
Реквизиты.Добавить(Новый РеквизитФормы(ИмяРеквизита, Новый ОписаниеТипов("Число"), , ЗаголовокПоля));
ИзменитьРеквизиты(Реквизиты);
Поле = Элементы.Добавить("Поле_" + ИмяРеквизита, Тип("ПолеФормы"), Страница);
Поле.Вид = ВидПоляФормы.ПолеВвода;
Поле.ПутьКДанным = ИмяРеквизита;
КонецПроцедуры
Реквизиты и элементы, созданные кодом, живут только до закрытия формы. При следующем открытии их нужно построить заново в ПриСозданииНаСервере.
ИзменитьРеквизиты перестраивает форму и сбрасывает введённые, но не записанные данные в динамических реквизитах. Вызывайте её один раз пачкой для всех реквизитов, а не по одному в цикле: так быстрее и безопаснее.
Удаление динамической вкладки
Сначала удаляют вложенные поля, затем страницу, затем (если нужно) сам реквизит:
Элементы.Удалить(Элементы.Поле_Остаток);
Элементы.Удалить(Элементы.Склад_1);
Удалить можно только то, что создано кодом. Элементы, нарисованные в конфигураторе, Элементы.Удалить не трогает.
6. Обработка событий: что происходит при смене вкладки
У группы «Страницы» есть событие «При смене текущей страницы». Назначить обработчик можно в палитре свойств группы, нажав на лупу напротив события. Платформа сама создаст заготовку:
&НаКлиенте
Процедура ГруппаСтраницыПриСменеТекущейСтраницы(Элемент, ТекущаяСтраница)
Если ТекущаяСтраница = Элементы.СтраницаИстория Тогда
ЗагрузитьИсториюНаСервере();
КонецЕсли;
КонецПроцедуры
Параметр ТекущаяСтраница — это вкладка, на которую перешли. Предыдущую вкладку событие не отдаёт: если она нужна, запоминайте её в реквизите формы.
Главный практический смысл события — ленивая загрузка. Тяжёлую таблицу (история изменений, остатки по складам, связанные документы) заполняют не при открытии формы, а когда пользователь впервые зашёл на вкладку.
&НаКлиенте
Процедура ГруппаСтраницыПриСменеТекущейСтраницы(Элемент, ТекущаяСтраница)
Если ТекущаяСтраница = Элементы.СтраницаОстатки И Не ОстаткиЗагружены Тогда
ЗаполнитьОстаткиНаСервере();
ОстаткиЗагружены = Истина;
КонецЕсли;
КонецПроцедуры
Реквизит ОстаткиЗагружены (тип «Булево») добавьте на форму вручную. Без флага запрос выполнялся бы при каждом возврате на вкладку.
Обработчик для вкладки, созданной кодом
У динамически созданной группы «Страницы» обработчик назначают методом УстановитьДействие:
ГруппаСтраниц.УстановитьДействие("ПриСменеТекущейСтраницы", "ГруппаСтраницыПриСменеТекущейСтраницы");
Вторым параметром идёт имя клиентской процедуры формы с той же сигнатурой, что показана выше.
7. Ошибки: почему вкладки не работают так, как задумано
Разберём то, что реально ломается у разработчиков.
ТекущаяСтраница строку. Нужно передавать сам элемент: Элементы.СтраницаТовары, без кавычек. Либо имя страницы написано с опечаткой, проверьте через Элементы.Найти.ИзменитьРеквизиты, потом Элементы.Добавить с ПутьКДанным.ТекущаяСтраница на другую.ПриСозданииНаСервере.Если не помогло
Откройте форму в режиме отладки и поставьте точку останова на строке присваивания страницы. Посмотрите в окне вычисления выражений значение Элементы.ГруппаСтраницы.ПодчинённыеЭлементы: там перечислены все реально существующие страницы с их именами. Чаще всего проблема находится именно здесь — страницы названы не так, как вы думали.
Ещё одна причина: код вызывается на сервере, а событие или присваивание ожидает клиентский контекст (или наоборот). Проверьте директивы &НаКлиенте и &НаСервере у процедуры.
8. Какой способ выбрать и что проверить перед сдачей
Не каждую вкладку нужно строить программно. Сравните подходы.
| Задача | Способ | Риск |
|---|---|---|
| Фиксированный набор разделов формы | Страницы в конфигураторе | Минимальный: всё видно в редакторе |
| Вкладка нужна только части пользователей | Функциональная опция или роль | Нужно продумать настройку опции |
| Вкладка зависит от данных документа | Видимость из кода | Забытый вызов при смене реквизита |
| Набор вкладок заранее неизвестен | Элементы.Добавить | Сложнее отладка, всё надо строить заново при открытии |
| Пошаговый мастер | Отображение страниц «Нет» и кнопки «Далее» | Нужно самому вести порядок шагов |
Правило простое: пока можно нарисовать в конфигураторе, рисуйте там. Код добавляйте, когда без него никак. Статичную форму проще поддерживать, а следующий разработчик увидит все вкладки сразу, без чтения процедур.
Мастер из вкладок: короткий пример
Для мастера создайте группу «Страницы» с отображением «Нет» и три страницы по числу шагов. Кнопка «Далее» двигает пользователя вперёд:
&НаКлиенте
Процедура Далее(Команда)
Страницы = Элементы.ГруппаСтраницы.ПодчинённыеЭлементы;
Индекс = Страницы.Индекс(Элементы.ГруппаСтраницы.ТекущаяСтраница);
Если Индекс < Страницы.Количество() - 1 Тогда
Элементы.ГруппаСтраницы.ТекущаяСтраница = Страницы[Индекс + 1];
КонецЕсли;
КонецПроцедуры
Для «Назад» меняйте условие на Индекс > 0 и берите Страницы[Индекс - 1]. Перед переходом проверяйте заполнение полей текущего шага, иначе мастер превратится в обычную форму с лишними кнопками.
Если у шага есть обязательные поля, делайте кнопку «Далее» недоступной, пока они пусты. Пользователю понятнее, чем сообщение об ошибке после нажатия.
Чек-лист перед сдачей формы
Прогоните форму по списку, прежде чем отдавать её пользователям.
Частые вопросы
Можно ли сделать вкладки в обычной (не управляемой) форме?
Сколько вкладок можно сделать на форме?
Как поменять порядок вкладок?
Элементы.Переместить.Как сделать вкладки не сверху, а слева?
Как узнать, на какой вкладке сейчас пользователь?
Элементы.ГруппаСтраницы.ТекущаяСтраница на клиенте и сравните с нужным элементом.