Приведенный ниже программный код предназначен для выполнения в контексте тонкого клиента. Проверка работоспособности проведена на платформе: 8.3.11.2867.
1. Визуализация направления сортировки в заголовке колонки.
Ищем поля порядка на всю глубину вложенности группировок отчета. Здесь _Структура - структура настроек отчета.
&НаСервере
procedure ПолучитьНаправлениеСортировки(_Структура,_sps)
_Коллекция=_Структура.Порядок.Элементы;
if _Коллекция.Количество()>0 then
ПолучитьНаправлениеЭлемента(_Коллекция,_sps);
if _Структура.Структура.Количество()>0 then
for each _эл in _Структура.Структура do
ПолучитьНаправлениеСортировки(_эл,_sps);
enddo;
endif;
endif;
endprocedure
Запоминаем направление сортировки для каждого найденного поля. Элементы автопорядка пропускаем.
&НаСервере
procedure ПолучитьНаправлениеЭлемента(_Элементы,_sps)
for each _эл in _Элементы do
if ТипЗнч(_эл) <> Тип("АвтоЭлементПорядкаКомпоновкиДанных") then
x=string(_эл.Поле);
v=0;
if _эл.ТипУпорядочивания=НаправлениеСортировкиКомпоновкиДанных.Убыв then
v=1;
endif;
_sps.Вставить(x,v);
endif;
enddo;
endprocedure
И наконец, вызывающая процедура. По заголовку поля ищем заголовок колонки отчета, и в зависимости от направления сортировки вставляем соответствующую пиктограмму в заголовок колонки. Нулевой индекс, в структуре настроек указывает на то, что в нашем отчете только одна область вывода данных. Если в отчет выводятся несколько наборов данных в разные области, то для каждой области должен быть указан соответствующий индекс.
&НаСервере
procedure ОтобразитьНаправленияСортировки()
//Отображает направление в заголовках колонок
Настройки=Отчет.КомпоновщикНастроек.ПолучитьНастройки();
sps=new Структура();
ПолучитьНаправлениеСортировки(Настройки.Структура[0],sps);
for each x in sps do
fld=x.Ключ;
srt=x.Значение;
_Поле=Отчет.КомпоновщикНастроек.Настройки.ДоступныеПоляПорядка.НайтиПоле(new ПолеКомпоновкиДанных(fld));
if not _Поле=undefined then
cap=_Поле.Заголовок;
Область=Результат.НайтиТекст(cap,,,true,true);
if not Область=undefined then
if srt=0 then
Область.Картинка=БиблиотекаКартинок.СтрелкаВверх;
else
Область.Картинка=БиблиотекаКартинок.СтрелкаВниз;
endif;
Область.РазмерКартинки=РазмерКартинки.РеальныйРазмер;
Область.ПоложениеТекстаОтносительноКартинки=ПоложениеТекстаОтносительноКартинки.Сверху;
endif;
endif;
enddo;
endprocedure
2. Сортировка по заголовку колонки.
Единственным событием, к которому можно привязать сортировку является событие "Выбор" - событие, возникающее при двойном щелчке на ячейку или рисованный объект в режиме "только просмотр".
&НаКлиенте
Процедура РезультатВыбор(Элемент, Область, СтандартнаяОбработка)
//Двойной щелчок на активной области
Текст=Область.Текст;
if УстановитьПолеСортировки(Текст) then
ОтобразитьНаправленияСортировки();
endif;
КонецПроцедуры
По заголовку колонки получаем имя выбранного поля, и запускаем процедуру поиска в структуре настроек отчета.
&НаСервере
function УстановитьПолеСортировки(txt)
//Ищет поле сортировки по заголовку колонки
Настройки=Отчет.КомпоновщикНастроек.ПолучитьНастройки();
ДоступныеПоля=Настройки.Порядок.ДоступныеПоляПорядка.Элементы;
for each д in ДоступныеПоля do
if д.Заголовок=txt then
НайтиПолеВИерархии(д.Поле,Настройки.Структура[0]);
ОбновитьОтчет(Настройки);
return true;
endif;
enddo;
return false;
endfunction
Сначала проверяем на совпадение нашего поля с полями группировок. Если совпадение найдено, удаляем у найденного поля элемент автопорядка, если он есть. Если в полях группировок наше поле не найдено, то это означает, что это поле является ресурсом и для него будет создано новое поле порядка.
&НаСервере
procedure НайтиПолеВИерархии(fld,_Структура)
//Ищет в группировках поле, выбранное пользователем
ПолеГрупп=_Структура.ПоляГруппировки.Элементы;
for each п in ПолеГрупп do
if п.Поле=fld then
_Коллекция=_Структура.Порядок.Элементы;
ПроверкаПоляАвтоПорядка(_Коллекция);
НайтиПолеПорядка(fld,_Коллекция);
return;
endif;
enddo;
//Поле не найдено, спускаемся ниже
if _Структура.Структура.Количество()>0 then
for each _эл in _Структура.Структура do
НайтиПолеВИерархии(fld,_эл);
enddo;
else
//Это ресурс
_Коллекция=_Структура.Порядок.Элементы;
ПроверкаПоляАвтоПорядка(_Коллекция);
НайтиПолеПорядка(fld,_Коллекция)
endif;
endprocedure
Удаление элементов автопорядка.
procedure ПроверкаПоляАвтоПорядка(_Коллекция)
//Если элемент автопорядка - удаляем
if _Коллекция.Количество()>0 then
for each _эл in _Коллекция do
if ТипЗнч(_эл) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") then
_Коллекция.Удалить(_эл);
endif;
enddo;
endif;
endprocedure
После того, как мы определились, по какому полю будет выполнена сортировка, проверим наличие полей порядка у нашего поля. Тут возможны три варианта. Первый - поля порядка есть в структуре отчета. В этом случае меняем порядок сортировки на обратный. Второй вариант - выбрано другое поле сортировки. Например, в отчете присутствует группировка по полю "Товар", у данной группировки есть два ресурса "Количество" и "Сумма". В настройках отчета указано, что сортировка по группировке "Товар" должна выполняться по ресурсу "Количество". Если в сформированном отчете пользователь щелкнул на колонке "Количество" то у группировки "Товар" и данного ресурса сортировка изменится на обратную (первый вариант), если была выбрана колонка "Сумма", то предыдущая сортировка удаляется, и устанавливается сортировка по полю "Сумма" (второй вариант). И наконец третий вариант, у выбранной колонки нет полей порядка, в этом случае создаем новую сортировку.
&НаСервере
procedure НайтиПолеПорядка(fld,_Коллекция)
//Проверка наличия поля порядка для fld
if _Коллекция.Количество()>0 then
for each _эл in _Коллекция do
_ПолеПорядка=_эл.Поле;
if _ПолеПорядка=fld then
ИзменитьПорядокСортировки(_эл);
return;
endif;
enddo;
//Выбрано другое поле, очищаем коллекцию существующей сортировки и добавляем новое поле
_Коллекция.Очистить();
НовоеПолеПорядка(fld,_Коллекция)
else
//Коллекция пустая (нет полей сортировки), добавляем новое поле
НовоеПолеПорядка(fld,_Коллекция)
endif;
endprocedure
Изменение направления сортировки.
&НаСервере
procedure ИзменитьПорядокСортировки(_Порядок)
//Меняет порядок сортировки на обратный
if _Порядок.ТипУпорядочивания=НаправлениеСортировкиКомпоновкиДанных.Возр then
_Порядок.ТипУпорядочивания=НаправлениеСортировкиКомпоновкиДанных.Убыв;
else
_Порядок.ТипУпорядочивания=НаправлениеСортировкиКомпоновкиДанных.Возр;
endif;
endprocedure
Добавление новой сортировки в коллекцию полей порядка.
&НаСервере
procedure НовоеПолеПорядка(fld,_Коллекция)
//Вставляет новое поле сортировки в коллекцию злементов порядка
НовыйПорядок=_Коллекция.Вставить(0,Тип("ЭлементПорядкаКомпоновкиДанных"));
НовыйПорядок.Поле= fld;
НовыйПорядок.Использование=Истина;
НовыйПорядок.ТипУпорядочивания=НаправлениеСортировкиКомпоновкиДанных.Возр;
endprocedure
Формируем отчет с новыми настройками сортировки.
&НаСервере
procedure ОбновитьОтчет(Настройки)
//Сформировать отчет с новыми настройками
Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
ЭтаФорма.СкомпоноватьРезультат(РежимКомпоновкиРезультата.Непосредственно);
endprocedure
Во вложении находится тестовый отчет с примерами сортировки трех типов отчетов: "Группировка", "Детальные записи" и "Таблица".