При разработке сложных интерфейсов в 1С часто возникает задача реализовать механизм «вложенности», когда внутри основной формы (например, обработки или справочника) на разных закладках должны отображаться списки документов или другие формы. Стандартный вызов метода ОткрытьФорму часто приводит к тому, что открываемая форма либо замещает текущую, либо открывается в отдельном окне, что нарушает пользовательский опыт. В этой статье мы подробно разберем, как правильно организовать работу с несколькими страницами и отображением связанных данных, чтобы интерфейс оставался целостным.
Рассмотрим ситуацию, с которой сталкиваются многие разработчики: попытка передать группу формы (страницу) в качестве владельца при открытии новой формы. Проанализируем пример кода:
&НаКлиенте
Процедура ОткрытьФормуПочты(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ТипСобытия", ПредопределенноеЗначение("Перечисление.ТипыСобытий.ЭлектронноеПисьмо"));
// Попытка открыть форму списка внутри конкретной страницы
ОткрытьФорму("Документ.Событие.ФормаСписка", ПараметрыФормы, Элементы.ГруппаСтраницаПочта);
КонецПроцедуры
В данном случае платформа 1С ведет себя специфично. Хотя параметр Владелец принимает элемент формы, это не означает, что форма «вклеится» в визуальную область этой группы. Чаще всего текущая форма либо полностью перекроется новой, либо закладки основной формы станут недоступны. Выясним причину: управляемые формы проектируются как самостоятельные единицы интерфейса. Для реализации «вложенного» вида, как в типовых конфигурациях (например, ссылки «Документы», «Файлы» в карточке контрагента), используются другие механизмы.
Это самый надежный и правильный способ с точки зрения производительности и удобства пользователя. Вместо того чтобы открывать чужую форму списка, мы размещаем Динамический список непосредственно на нужной нам странице текущей формы.
Разберем реализацию по шагам:
СписокПисем) и установим ему тип ДинамическийСписок.Документ.Событие.СписокПисем на нужную страницу (закладку) в дерево элементов формы. Платформа автоматически создаст таблицу формы.Для программного управления отбором в этом списке используем следующий код в модуле формы:
&НаСервере
Процедура НастроитьОтборСпискаНаСервере()
// Очищаем старые отборы, если они были
ЭлементОтбора = СписокПисем.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТипСобытия");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Перечисления.ТипыСобытий.ЭлектронноеПисьмо;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецПроцедуры
Преимущества этого метода: пользователь не покидает форму, сохраняется видимость всех закладок, а данные подгружаются динамически только при переключении на соответствующую страницу. Для расширения состава отображаемых колонок можно использовать методы доработки динамических списков.
Если ваша задача — сделать интерфейс похожим на типовое решение УНФ или БП, где в верхней части формы расположены гиперссылки (Основное, Документы, Договоры), то следует использовать Панель навигации формы.
Проанализируем ситуацию: ссылки в верхней части — это не кнопки на страницах, а команды перехода. Рассмотрим, как их настроить:
Чтобы управлять видимостью этих ссылок программно, мы можем обратиться к коллекции КомандныйИнтерфейс:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Управляем видимостью команд перехода в верхней панели
ЭтаФорма.КомандныйИнтерфейс.Навигация.ГруппаПерейти.КомандаСобытияПоКонтрагенту.Видимость = Истина;
КонецПроцедуры
Иногда требуется открыть форму и сразу активировать на ней определенную страницу. Рассмотрим, как это сделать правильно, используя получение формы и обращение к её элементам.
Посмотрим на пример кода, который позволяет подготовить форму перед показом:
&НаКлиенте
Процедура ОткрытьФормуСПереходомНаСтраницу()
// Получаем форму без открытия
ПараметрыОткрытия = Новый Структура("Ключ", СсылкаНаОбъект);
ФормаОбъекта = ПолучитьФорму("Справочник.Контрагенты.ФормаОбъекта", ПараметрыОткрытия);
// Устанавливаем текущую страницу программно
// Предположим, что на форме есть группа страниц "ГруппаВсеСтраницы"
// и в ней есть страница "СтраницаДоговоры"
ФормаОбъекта.Элементы.ГруппаВсеСтраницы.ТекущаяСтраница = ФормаОбъекта.Элементы.СтраницаДоговоры;
// Теперь показываем настроенную форму пользователю
ФормаОбъекта.Открыть();
КонецПроцедуры
Важный нюанс: при таком подходе нужно убедиться, что в процедуре ПриОткрытии или ПриЧтенииНаСервере самой открываемой формы нет жесткого переопределения текущей страницы, иначе ваши настройки будут сброшены.
При открытии форм списков или форм объектов часто полезно использовать параметр КлючНазначенияИспользования. Выясним, зачем он нужен в контексте нашей задачи.
Когда вы открываете одну и ту же форму из разных мест (например, форму списка документов из меню и ту же форму из вашей обработки), 1С сохраняет пользовательские настройки (ширину колонок, положение окна, активную закладку). Если вы хотите, чтобы для вашей обработки настройки формы сохранялись отдельно и не мешали стандартному виду списка, передавайте уникальный ключ:
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("КлючНазначенияИспользования", "УникальныйКонтекстДляМоейОбработки");
ОткрытьФорму("Документ.Событие.ФормаСписка", ПараметрыФормы);
Это позволит системе «запомнить», что именно в этом режиме вызова пользователю, например, удобнее видеть список без иерархии или с определенным набором колонок.
Подведем итог: если вам нужно отобразить данные другого объекта «внутри» текущей формы и сохранить закладки:
ПолучитьФорму(), программно устанавливайте свойство ТекущаяСтраница и только после этого вызывайте Открыть().Помните, что визуальное «вложение» одной формы в другую (как контрол в контрол) в классическом понимании в 1С 8.3 не реализовано через ОткрытьФорму, и имитация этого поведения через динамические списки является стандартом разработки.