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