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