21 мар. 2013 г.

СКД: делаем свой вывод списка в форме II

В прошлом примере был приведен частный случай вывода данных динамического списка с помощью СКД. Но пользователь может произвести дополнительные настройки динамического списка под себя. Например, добавить группировки, либо настроить оформление полей. Поэтому стоит оказаться от варианта "каждому списку - свой отчет" и реализовать общий механизм формирования выходной формы. Попробуем сделать первый шаг к универсальности, будем создавать схему компоновки данных в отдельном модуле, а так же научим понимать группировки в динамическом списке.

Основной код выносится в общий модуль "ПечатьДинамическогоСписка":

Функция ПолучитьРезультат(Список, СтруктураПолей, ПараметрыВывода) Экспорт
 
 ТабДокумент = Новый ТабличныйДокумент;
 
 ТекстЗапроса = ?(Список.ПроизвольныйЗапрос, Список.ТекстЗапроса, ПолучитьТекстЗапроса(Список.ОсновнаяТаблица));
 
 СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
 
 Для Каждого Параметр Из ПараметрыВывода Цикл
  ПолеПараметр = СхемаКомпоновки.НастройкиПоУмолчанию.ПараметрыВывода.Элементы.Найти(Параметр.Ключ);
  ПолеПараметр.Значение = Параметр.Значение;
  ПолеПараметр.Использование = Истина;
 КонецЦикла;
 
 ИсточникДанных = СхемаКомпоновки.ИсточникиДанных.Добавить();
 ИсточникДанных.Имя = "ИсточникДанных";
 ИсточникДанных.ТипИсточникаДанных = "Local";
 
 НаборДанных = СхемаКомпоновки.НаборыДанных.Добавить(Тип("НаборДанныхЗапросСхемыКомпоновкиДанных"));
 НаборДанных.Запрос = ТекстЗапроса;
 НаборДанных.Имя = "НаборДанных";
 НаборДанных.ИсточникДанных = "ИсточникДанных";

 ДоступныеПоля = Список.Порядок.ДоступныеПоляПорядка.Элементы;
 Для Каждого ПолеСписка Из ДоступныеПоля Цикл
  Если ПолеСписка.Папка ИЛИ ПолеСписка.Таблица Тогда
   Продолжить;
  КонецЕсли;
  ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
  ПолеНабора.Заголовок = ПолеСписка.Заголовок;
  ПолеНабора.Поле = Строка(ПолеСписка.Поле);
 КонецЦикла;
 
 ВыбранныеПоля = СхемаКомпоновки.НастройкиПоУмолчанию.Выбор.Элементы;
 Для Каждого ПолеПорядок Из СтруктураПолей Цикл
  ПолеОтчет = ВыбранныеПоля.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
  ПолеКомпоновки = ДоступныеПоля.Найти(ПолеПорядок.Ключ);
  ПолеОтчет.Заголовок = ПолеПорядок.Значение;
  ПолеОтчет.Поле = ПолеКомпоновки.Поле;
 КонецЦикла;
 
 СтруктураГруппировки = СхемаКомпоновки.НастройкиПоУмолчанию.Структура;
 ГруппыСписок = Список.Группировка.Элементы;
 
 Для Каждого ЭлементГруппа Из ГруппыСписок Цикл
  ДобавитьГруппировкуСтруктуры(СтруктураГруппировки, ЭлементГруппа);
 КонецЦикла;
 ДобавитьГруппировкуСтруктуры(СтруктураГруппировки);
 
 КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
 ОтборПоУмолчанию = СхемаКомпоновки.НастройкиПоУмолчанию.Отбор;
 
 ОтборКомпоновка = Список.Отбор;
 Для Каждого Элемент Из ОтборКомпоновка.Элементы Цикл
  ЭлементОтбор = ОтборПоУмолчанию.Элементы.Добавить(Тип(Элемент));
  ЗаполнитьЗначенияСвойств(ЭлементОтбор, Элемент);
 КонецЦикла;
 
 МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, СхемаКомпоновки.НастройкиПоУмолчанию);
 
 ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
 ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
 
 ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
 ПроцессорВывода.УстановитьДокумент(ТабДокумент);
 
 ПроцессорВывода.Вывести(ПроцессорКомпоновки); 
 
 ТабДокумент.ТолькоПросмотр = Истина;
 ТабДокумент.ОтображатьСетку = Ложь;
 ТабДокумент.ОтображатьЗаголовки = Ложь;
 
 Возврат ТабДокумент;
 
КонецФункции

Процедура ДобавитьГруппировкуСтруктуры(СтруктураГруппировки, ЭлементГруппа = Неопределено)
 
 ЭлементГруппировки = СтруктураГруппировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
 ЭлементГруппировки.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
 Если ЭлементГруппа = Неопределено Тогда
  //...
 Иначе
  ЭлементГруппы = ЭлементГруппировки.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
  ЗаполнитьЗначенияСвойств(ЭлементГруппы, ЭлементГруппа);
 КонецЕсли;
 
 СтруктураГруппировки = ЭлементГруппировки.Структура;
 
КонецПроцедуры

Функция ПолучитьТекстЗапроса(ОсновнаяТаблица)
 
 ЗапросТекст = 
  "ВЫБРАТЬ
  | " + ОсновнаяТаблица + ".*
  |ИЗ
  | " + ОсновнаяТаблица;
  
 Возврат ЗапросТекст;
  
КонецФункции

Функция ПолучитьПараметрыВывода() Экспорт
 
 //в дальнейшем можно расширить дополнительными параметрами
 Возврат Новый Структура("Заголовок"); 
 
КонецФункции

Теперь перепишем модуль формы списка заявок, прошлый код закомменитрован:

&НаСервере
Функция ПечатьСпискаСервер()

 //настройка компоновки вынесена в модуль менеджера документа
 //в функцию настройки компоновки передаем отбор динамического списка
 //Возврат Документы.ЗаявкиКонтрагентов.ПечатьСпискаКомпоновка(Список.Отбор);
 
 мПоля = Новый Структура;
 Для Каждого ЭлементСписка Из Элементы.Список.ПодчиненныеЭлементы Цикл
  мПоля.Вставить(ЭлементСписка.Имя, ЭлементСписка.Заголовок);
 КонецЦикла;
 
 ПараметрыВывода = ПечатьДинамическогоСписка.ПолучитьПараметрыВывода();
 ПараметрыВывода.Заголовок = "Реестр заказов";
 
 Возврат ПечатьДинамическогоСписка.ПолучитьРезультат(Список, мПоля, ПараметрыВывода);

КонецФункции // ПечатьСпискаСервер()

&НаКлиенте
Процедура ПечатьСписка(Команда)
 
 ТабДок = ПечатьСпискаСервер();
 ТабДок.Показать();
 
КонецПроцедуры
 
Проверяем, задаем группировку в списке через команду формы "Настроить список".



Таким же образом размещаем код обращения к общему модулю в форме списка документов "Оприходование товаров".


Выгрузка конфигурации Тесты СКД (cf)

update: Не актуально, в платформе 8.3.6.1977 появился необходимый функционал.

1 комментарий:

  1. Спасибо, очень ценная информация. Мне пригодилась.

    ОтветитьУдалить