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