«Программное заполнение настроек СКД» или «Как сделать отчёт на СКД с понятным для пользователя интерфейсом». (1С: Предприятие 8.1, 8.2 обычное приложение)


В настоящее время большинство отчётов пишется с использованием системы компоновки данных. Это удобно для разработчика, но не всегда удобно для пользователя. Чаще всего у пользователя нет ни времени, ни желания разбираться во всех широких возможностях отчёта, ему просто хочется видеть нужные ему настройки на форме и быстро получить желаемый результат. В данной статье я хочу привести пример, как можно вынести на форму настройки системы компоновки данных и программно сформировать отчёт на основе этих настроек.

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

  Пример  программного заполнения настроек построю на основе отчёта по оборотному регистру накопления Продажи с измерениями: Контрагент, Номенклатура и ресурсами: Количество и Сумма.

Создание отчёта и настройка схемы компоновки данных.

    Итак. Создаём новый отчёт. Открываем схему компоновки данных и добавляем новый набор данных запрос. В окне запроса пишем следующий запрос:

ВЫБРАТЬ

                        ПродажиОбороты.Регистратор,

                        ПродажиОбороты.Контрагент,

                        ПродажиОбороты.Номенклатура,

                        ПродажиОбороты.СуммаОборот,

                        ПродажиОбороты.КоличествоОборот

ИЗ

                        РегистрНакопления.Продажи.Обороты(, , Авто, ) КАК ПродажиОбороты

 

    На закладке «Ресурсы» указываем в качестве ресурсов поля КоличествоОборот и СуммаОборот.

    На закладке «Параметры» добавим новый параметр «Период» типа СтандартныйПериод. Для параметра «НачалоПериода» в качестве выражения укажем следующее значение:  &Период.ДатаНачала, для параметра «КонецПериода» - &Период.ДатаОкончания. Таким образом, мы избавим себя от приведения даты окончания к концу дня и установки каждого параметра в отдельности. Настройку структуры отчёта мы не делаем. Она будет сформирована программно.

На этом настройка схемы компоновки закончена. Переходим к настройке интерфейса.

 

Настройка пользовательского интерфейса.

    Вначале создадим реквизиты отчёта. Они понадобятся нам при создании интерфейса и дальнейшей программной обработке указанных пользователем настроек. Добавляем реквизит Период – тип СтандартныйПериод, Количество – тип Булево, Сумма – тип Булево. Данные реквизиты будут отвечать за переданный параметр Период и за вывод ресурсов отчёта КоличествоОборот и СуммаОборот соответственно. Также нам потребуется табличная часть Группировки с реквизитами Поле – тип Строка и ТипГруппировки – тип Строка. Табличная часть будет отвечать за выбранные группировки при формировании отчёта.

    Необходимые реквизиты созданы, теперь создаём форму отчёта.  

    На форме располагаем следующие элементы:

  • Поля ввода для указания периода: ДатаНачала – данные Период.ДатаНачала, Датаокончания - Период.ДатаОкончания, Период – данные Период и кнопку КнопкаВыбораПериода (для кнопки нужно назначить обработчик, открывающий диалог указания периода. Программный код можно посмотреть в прикреплённом внешнем отчёте) .
  • Панель с тремя страницами. Первую страницу назовём Отбор и расположим на ней табличное поле с данными КомпоновщикНастроек.Настройки.Отбор. Вторую страницу назовём УсловноеОформление и расположим на ней табличное поле с данными КомпоновщикНастроек.Настройки.УсловноеОформление. Третью страницу назовём Сортировка и расположим на ней табличное поле с данными КомпоновщикНастроек.Настройки.Порядок.
  • Табличное поле Группировки, связанное с табличной частью отчёта «Группировки», и добавляем командную панель с указанием в качестве источника действий табличного поля «Группировки». На командную панель добавляем кнопки «Добавить», «Удалить», «Переместить вверх», «Переместить вниз».  
  • 2 флажка ВыводитьКоличество и ВыводитьСумму, связанные с реквизитами отчёта Количество и Сумма соответственно.
  • Поле табличного документа Результат, автоматически созданное при создании формы, оставляем без изменения. 

    На этом создание пользовательского интерфейса завершено. Переходим к самому интересному – программной части.

Программная работа со схемой компоновки данных.

    В первую очередь, необходимо описать какие группировки будут доступны в нашем отчёте. Для этого в модуле объекта создадим экспортные переменные СписокДоступныхПолейГруппировки и СписокДоступныхТиповГруппировки. В теле основной программы заполним их списками значений:

СписокДоступныхПолейГруппировки = Новый СписокЗначений;

СписокДоступныхПолейГруппировки.Добавить("Регистратор");

СписокДоступныхПолейГруппировки.Добавить("Контрагент");

СписокДоступныхПолейГруппировки.Добавить("Номенклатура");

 

СписокДоступныхТиповГруппировки = Новый СписокЗначений;

СписокДоступныхТиповГруппировки.Добавить("Иерархия");

СписокДоступныхТиповГруппировки.Добавить("Элементы");

    При открытии формы заполним группировки значениями по умолчанию

               Группировки.Очистить();

               НоваяГруппировка = Группировки.Добавить();

               НоваяГруппировка.Поле = "Регистратор";

               НоваяГруппировка.ТипГруппировки = "Элементы";

                       

               НоваяГруппировка = Группировки.Добавить();

               НоваяГруппировка.Поле = "Контрагент";

               НоваяГруппировка.ТипГруппировки = "Элементы";

                       

               НоваяГруппировка = Группировки.Добавить();

               НоваяГруппировка.Поле = "Номенклатура";

               НоваяГруппировка.ТипГруппировки = "Элементы";

    Установим доступные списки выбора для полей группировок :

ЭлементыФормы.Группировки.Колонки.Поле.ЭлементУправления.СписокВыбора = СписокДоступныхПолейГруппировки;

ЭлементыФормы.Группировки.Колонки.ТипГруппировки.ЭлементУправления.СписокВыбора = СписокДоступныхТиповГруппировки;

    Также нам необходимо определить в модуле объекта обработчик ПриКомпоновкеРезультата, в котором будем загружать наши настройки в схему компоновки данных.

// Добавляет колонки (поля ресурсов) в соответствии с флажками на форме

               Если Количество И Не НайтиПолеКомпоновки("КоличествоОборот", НастройкиСКД.Выбор.Элементы) Тогда

                    ВыбранноеПоле = НастройкиСКД.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));

                    ВыбранноеПоле.Использование = Истина;

                    ВыбранноеПоле.Заголовок = "Количество";

                    ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("КоличествоОборот");

               КонецЕсли;   

               Если Сумма И Не НайтиПолеКомпоновки("СуммаОборот", НастройкиСКД.Выбор.Элементы) Тогда

                    ВыбранноеПоле = НастройкиСКД.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));

                    ВыбранноеПоле.Использование = Истина;

                    ВыбранноеПоле.Заголовок = "Сумма";

                    ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных("СуммаОборот");

               КонецЕсли;

//Удаляет колонки, соответствующие флажки которых не были отмечены

                Счетчик = 0;

                Пока Счетчик < НастройкиСКД.Выбор.Элементы.Количество() Цикл

                     ПолеКомпоновкиДанных = НастройкиСКД.Выбор.Элементы[Счетчик];

                     Если ПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных("КоличествоОборот") И Не Количество Тогда

                         НастройкиСКД.Выбор.Элементы.Удалить(ПолеКомпоновкиДанных);

                         Продолжить;

                     ИначеЕсли ПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных("СуммаОборот") И Не Сумма Тогда

                         НастройкиСКД.Выбор.Элементы.Удалить(ПолеКомпоновкиДанных);

                         Продолжить;

                     КонецЕсли;                       

                     Счетчик = Счетчик + 1;

                КонецЦикла;

//заполняем поля группировок в соответствии с настройками в табличной части Группировки

НастройкиСКД.Структура.Очистить();

               ЭлементСтруктуры = НастройкиСКД;        

               Для Каждого Группировка Из Группировки Цикл

                   ЭлементСтруктуры = ЭлементСтруктуры.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));

                   ЭлементГруппировки = ЭлементСтруктуры.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));

                   ЭлементГруппировки.Использование = Истина;

                   ЭлементГруппировки.Поле =  Новый ПолеКомпоновкиДанных(Группировка.Поле);                                                  

                   Если СписокДоступныхТиповГруппировки.НайтиПоЗначению(Группировка.ТипГруппировки)=Неопределено Тогда

                       ЭлементГруппировки.ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;

                  Иначе

                       ЭлементГруппировки.ТипГруппировки = ТипГруппировкиКомпоновкиДанных[Группировка.ТипГруппировки];

                   КонецЕсли;                                                                                                                  

                   ПолеСортировки = ЭлементСтруктуры.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));

                   ПолеСортировки.Использование = Истина;

 

                   ВыбранноеПоле = ЭлементСтруктуры.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));

                   ВыбранноеПоле.Использование = Истина;

               КонецЦикла;

 

    Далее, устанавливаем значения параметров и загружаем заполненные настройки

               Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период",Период);

               КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

 

    В алгоритме добавления ресурсов в схему компоновки использовалась функция НайтиПолеКомпоновки. Эта функция определяет, есть ли добавляемое поле в выбранных полях схемы или нет. Если уже есть, то добавлять поле не требуется.

Функция НайтиПолеКомпоновки(Имя, Коллекция)

        Для Каждого ПолеКомпоновкиДанных Из Коллекция Цикл

            Если ПолеКомпоновкиДанных.Поле = Новый ПолеКомпоновкиДанных(Имя) Тогда

                  Возврат Истина;

            Иначе

                 Продолжить;

            КонецЕсли;

      КонецЦикла;                

 Возврат Ложь;

КонецФункции

 

    Готово. Настройки схемы компоновки данных заполнены, и отчёт может быть сформирован.

Расшифровка

    Для того чтобы при обработке расшифровки поля отбора и группировок заполнились в соответствии с выбранным полем нужно самостоятельно описать обработчик расшифровки. Для этого создадим булевский реквизит отчёта ЭтоРасшифровка. Реквизит будет показывать, формируем мы простой отчёт или расшифровываем. Для  табличного поля Результат  создаём обработчик РезультатОбработкаРасшифровки. В созданном обработчике пишем

СтандартнаяОбработка = ложь;

               Если ДанныеРасшифровки = Неопределено Тогда Возврат КонецЕсли;

ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));

               Настройки = ОбработкаРасшифровки.Выполнить(Расшифровка);

               Если Настройки<>Неопределено Тогда                                                                                          

                    КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

                    ЭтоРасшифровка = Истина;

                    ЭлементыФормы.Результат.Очистить();

                    СкомпоноватьРезультат(ЭлементыФормы.Результат,ДанныеРасшифровки);

              КонецЕсли;

  А в обработчике ПриКомпоновкеРезультата модуля объекта указываем, что заполнять настройки группировок нужно только в том случае, если это не расшифровка. Таким образом, обработчик ПриКомпоновкеРезультата принимает вид:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

                        Если Не (Количество ИЛИ Сумма ) Тогда

                            СтандартнаяОбработка = Ложь;

                             Сообщить("Необходимо выбрать хотя бы один показатель!");

                             Возврат;

                        КонецЕсли;                    

                        Настройки = КомпоновщикНастроек.ПолучитьНастройки();

                       

                        Если НЕ ЭтоРасшифровка  Тогда

                             УстановитьСтруктуруГруппировокСКД(Настройки);

                        КонецЕсли;                     

                        Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Период",Период);

                        КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);

                        ЭтоРасшифровка = ложь;

КонецПроцедуры

 

Итог.

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

    Также при желании можно сделать отчёт более универсальным. Например, заполнять список полей группировок и настройки по умолчанию из СКД, создать табличную часть параметры и заполнять её   параметрами, перечисленными в макете компоновки данных. Таким образом, получится некий шаблон отчёта, на основе которого можно будет легко делать другие отчёты, меняя только запрос, указание ресурсов и список параметров.

Созданный отчёт прикрепляю к данной статье для ознакомления.

Файлы обработки:

-