Это старая версия документа.
Отчеты, СКД, построитель
Макеты СКД (статья на Инфостарте no name (json))
макеты_скд.pdf © ООО «Инфостарт»
Использование предопределенных макетов (статья на 1С ITS )
использование_предопределенных_макетов.pdf © ООО «1С»
Вывод иерархического справочника в СКД
Заготовка с формами (БСП БП 3.0)
Вывод варианта отчета на СКД (неуправляемая форма)
Размещаем на форме отчета поле выбора «ПолеВыбораВарианта». В модуль формы добавляем:
Процедура ПриОткрытии() //Заполнение вариантов настроек отчета Для Каждого ВариантНастроек Из СхемаКомпоновкиДанных.ВариантыНастроек Цикл ЭлементыФормы.ПолеВыбораВарианта.СписокВыбора.Добавить(ВариантНастроек.Имя, ВариантНастроек.Представление); КонецЦикла; Если СхемаКомпоновкиДанных.ВариантыНастроек.Количество() > 0 Тогда ЭлементыФормы.ПолеВыбораВарианта.Значение = СхемаКомпоновкиДанных.ВариантыНастроек[0].Имя; КонецЕсли; КонецПроцедуры
Процедура ПолеВыбораВариантаПриИзменении(Элемент) КомпоновщикНастроек.ЗагрузитьНастройки(СхемаКомпоновкиДанных.ВариантыНастроек.Найти(Элемент.Значение).Настройки); КонецПроцедуры
СКД открытие и закрытие
Для автоматического формирования отчета на СКД при открытии его формы надо добавить в модуль формы в процедуру ПриСозданииНаСервере:
Параметры.СформироватьПриОткрытии = Истина;
а для автоматического формирования из команды надо добавить в модуль команды в процедуру ОбработкаКоманды:
ПараметрыФормы = Новый Структура("СформироватьПриОткрытии", ИСТИНА); ОткрытьФорму("Отчет.ОстатокДенежныхСредств.Форма", ПараметрыФормы, ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
Что бы избежать запроса на сохранение варианта отчета при его закрытии надо в клиентскую процедуру ПередЗакрытием вставить:
ВариантМодифицирован = Ложь;
Пользовательские настройки СКД
Первоначальные пользовательские настройки устанавливаются в процедуре ПриЗагрузкеПользовательскихНастроекНаСервере:
ЭтаФорма.Отчет.Период = ТекущаяДата(); Параметр = ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Период")); Параметр.Значение = ЭтаФорма.Отчет.Период; Параметр.Использование = ИСТИНА;
Передача периода из формы отчета в СКД
НачалоПериода и КонецПериода - заданные в компановщике параметры
Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НачалоПериода")); Параметр.Значение = НачалоДня(НачПериода); Параметр.Использование = ИСТИНА; Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода")); Параметр.Значение = КонецДня(КонПериода); Параметр.Использование = ИСТИНА;
Передача реквизита СкладОтбор из формы отчета в СКД
ПолеСклад = Новый ПолеКомпоновкиДанных("Склад"); Для Каждого Элемент Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл Если ТипЗнч(Элемент) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных") Тогда // Если есть группы отборов Продолжить; КонецЕсли; Если Элемент.ЛевоеЗначение = ПолеСклад Тогда ЭлементОтбора = Элемент; Прервать; КонецЕсли; КонецЦикла; Если ЭлементОтбора = Неопределено Тогда ЭлементОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных")); КонецЕсли; ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; ЭлементОтбора.ЛевоеЗначение = ПолеСклад; ЭлементОтбора.ПравоеЗначение = СкладОтбор; ЭлементОтбора.Использование = НЕ СкладОтбор.Пустая();
Программное формирование отчета на СКД и изменение выводимой формы
Отчет на СКД можно сформировать программно в процедуре «ПриКомпоновкеРезультата()» модуля отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) СтандартнаяОбработка = ЛОЖЬ; НастройкиКомпоновки = КомпоновщикНастроек.ПолучитьНастройки(); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновки, ДанныеРасшифровки); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); КонецПроцедуры
Программный вывод отчета и расшифровки к нему
НастройкиСКД = КомпоновщикНастроек.Настройки; СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); ДанныеРасшифровкиОтчета = Новый ДанныеРасшифровкиКомпоновкиДанных; НастройкиСКД.ПараметрыДанных.Элементы.Найти("Номенклатура").Значение = Справочники.Номенклатура.НайтиПоКоду("1"); // заполняем какие-то параметры КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиСКД, ДанныеРасшифровкиОтчета); ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровкиОтчета); ДокументРезультат = ЭлементыФормы.Результат; ДокументРезультат.Очистить(); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.Вывести(ПроцессорКомпоновки); ДокументРезультат.Показать();
ДанныеРасшифровкиОтчета - это переменная модуля формы отчета (то, что объявляется через ключевое слово Перем). ЭлементыФормы.Результат - Результат это имя табличного документа куда выводится отчет.
Вывод расшифровок:
Вариант 1.
На табличном документе идет в обработчики событий и делаем обработчик на событие ОбработкаРасшифровки. Процедура обработчик будет иметь вид похожий на это:
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровкиОтчета, Новый ИсточникДоступныхНастроекКомпоновкиДанных(ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных")) ); МассивДоступныхДействий = Новый Массив; МассивДоступныхДействий.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение); НастройкиРасшифровки = ОбработкаРасшифровки.Выполнить(Расшифровка,, МассивДоступныхДействий); КонецПроцедуры
Результат работы этого когда: двойной клик на любой ячейке ссылочного типа производит открытие этого элемента. Будь то документ, элемент справочника или ещё что-нибудь.
Вариант 2.
Все так же идем в обработчики события поля табличного документа и устанавливаем обработчик на ОбработкаРасшифровки:
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка) СтандартнаяОбработка=Ложь; ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровкиОтчета, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных)); ПолеРасшифровки = ДанныеРасшифровкиОтчета.Элементы[Расшифровка].ПолучитьПоля()[0]; Если ПолеРасшифровки.Поле = "Контрагент" ИЛИ ПолеРасшифровки.Поле = "Документ" Тогда Ссылка = ПолеРасшифровки.Значение; ОткрытьЗначение(Ссылка); КонецЕсли; КонецПроцедуры
Тут получаем информацию о том куда пользователь щелкнул. Зная это мы можем получить значение, которое находится в расшифровке. Дальше с ним можем делать что угодно. В этом примере результат не отличается от варианта 1, т.к. и в том и в том случае мы просто хотим открыть значения каких-то ссылок. Но если бы, например, мы получали текст или число, которое нужно было как-то хитро обработать, то в варианте №2 мы можем это сделать.
Вместо выводов: если вы хотите открывать ссылочные типы, тогда какой вариант использовать - дело ваше. Преимущество первого над вторым, я вижу, только в компактности и универсальности кода. Как насчет быстродействия, например, я не мерял. Но если же вам нужно получить результат расшифровки и как-то его обработать дополнительно - вы можете воспользоваться вариантом №2.
При программном выводе отчета возможно вмешаться в выводимою форму. В примере ниже показано добавление наименования Родителя (/Родитель/) к тексту выводимого поля Номенклатура:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) . . . // см. пример выше КоличествоСтрок = ДокументРезультат.ВысотаТаблицы; КоличествоКолонок = ДокументРезультат.ШиринаТаблицы; Для СтрокаДокумента = 1 По КоличествоСтрок Цикл Для КолонкаДокумента = 1 По КоличествоКолонок Цикл Область = ДокументРезультат.Область(СтрокаДокумента, КолонкаДокумента); Расшифровка = Область.Расшифровка; Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда ПоляРасшифровки = ДанныеРасшифровки.Элементы.Получить(Расшифровка).ПолучитьПоля(); НайденноеПоле = ПоляРасшифровки.Найти("Номенклатура"); Если НЕ НайденноеПоле = НЕОПРЕДЕЛЕНО Тогда ЗначениеПоля = НайденноеПоле.Значение; Если ТипЗнч(ЗначениеПоля) = Тип("СправочникСсылка.Номенклатура") И ЗначениеЗаполнено(ЗначениеПоля) Тогда Область.Текст = "/" + ЗначениеПоля.Родитель + "/ " + ЗначениеПоля.Наименование; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; КонецЦикла; КонецПроцедуры
При программном формировании отчета можно добавить свою область шапки или подвала в формируемый отчет:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) ДокументРезультат.Очистить(); МакетШапки = ПолучитьМакет("МакетШапки"); ОбластьШапка = НашМакетШапки.ПолучитьОбласть("Шапка"); ДокументРезультат.Вывести(ОбластьШапка); . . . // программно формируем отчет КонецПроцедуры
Использоваие внешнего набора данных (программное выполнение компоновщика)
ВнешниеНаборыДанных = Новый Структура; ВнешниеНаборыДанных.Вставить("ИмяОбъектаСодержащегоДанные", ТаблицаЗначений); СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпановки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки); ПроцессорКомпановкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпановкиДанных.Инициализировать(МакетКомпановки, ВнешниеНаборыДанных); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент); ПроцессорВывода.Вывести(ПроцессорКомпановкиДанных);
Вывод компоновщика в дерево значений
Существует ряд ограничений. Главное из которых: в настройках должны присутствовать только группировки и поля (без таблиц и т.п.).
Макет компановки задается:
МакетКомпановки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки,,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
Для процессора вывода используется метод УстановитьОбъект:
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; ПроцессорВывода.УстановитьОбъект(ДеревоЗначений);
Вывод производится: в цикле:
ПроцессорВывода.НачатьВывод(); Пока Истина Цикл ЭлементРезультатаКомпановкиДанных = ПроцессорКомпановкиДанных.Следующий(); Если ЭлементРезультатаКомпановкиДанных = Неопределено Тогда Прервать; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпановкиДанных); КонецЦикла; ПроцессорВывода.ЗакончитьВывод();
Весь код:
СхемаКомпоновкиДанных = ПолучитьМакет("МакетКомпановкиДанных"); Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпановки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки,,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")); ПроцессорКомпановкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпановкиДанных.Инициализировать(МакетКомпановки); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; ПроцессорВывода.УстановитьОбъект(ДеревоЗначений); ПроцессорВывода.НачатьВывод(); Пока Истина Цикл ЭлементРезультатаКомпановкиДанных = ПроцессорКомпановкиДанных.Следующий(); Если ЭлементРезультатаКомпановкиДанных = Неопределено Тогда Прервать; КонецЕсли; ПроцессорВывода.ВывестиЭлемент(ЭлементРезультатаКомпановкиДанных); КонецЦикла; ПроцессорВывода.ЗакончитьВывод();
Вывод в таблицу значений:
ВнешниеНаборыДанных = Новый Структура; ВнешниеНаборыДанных.Вставить("НазваниеНабораДанных1вСКД", ТаблицаРезультат); ВнешниеНаборыДанных.Вставить("НазваниеНабораДанных2вСКД", ТаблицаРезультат2); СхемаКомпоновкиДанных = ОбработкаОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию; КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки,,,Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений")); ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений; ОбъединеннаяТаблица = Новый ТаблицаЗначений; ПроцессорВывода.УстановитьОбъект(ОбъединеннаяТаблица); ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
Отбор с помощью СКД
Использование внешних функций в СКД
В СКД можно использовать функции глобальных и неглобальных общих модулей в вычисляемых полях при условии что функция объявлена как экспортная.
при программном выполнении отчета надо инициализировать так:
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,,,Истина);
Функция Вычислить в СКД
Вычислить(Выражение, Группировка, ТипРасчета)
Параметры: Выражение (Строка). Cодержит вычисляемое выражение; Группировка (Строка). Содержит имя группировки, в контексте которой необходимо вычислить выражение. В случае если в качестве имени группировки используется пустая строка, вычисление будет выполнено в контексте текущей группировки. В случае если в качестве имени группировки будет использована строка ОбщийИтог, вычисление будет выполнено в контексте общего итога. В остальных случаях вычисление будет выполняться в контексте родительской группировки с таким именем.
Например:
Сумма(СуммаОборот) / Вычислить("Сумма(СуммаОборот)", "ОбщийИтог")
В данном примере в результате получится отношение суммы по полю «СуммаОборот» записи группировки к сумме того же поля во всей компоновке. ТипРасчета (Строка). В случае если данный параметр имеет значение «ОбщийИтог», выражение будет вычисляться для всех записей группировки. В случае если значение параметра «Группировка», значения будут вычисляться для текущей групповой записи группировки.
Использование Пользовательских полей в СКД
В СКД можно создавать пользовательские поля.
пример вывода в детальных записях процента Суммы договора от итога по вышестоящей группировке (Проект):
Выбор Когда Вычислить("Сумма(СуммаДоговора)", "Проект") > 0 Тогда Формат(СуммаДоговора / Вычислить("Сумма(СуммаДоговора)", "Проект") * 100, "ЧДЦ=2") Иначе 0 Конец
Конец периода в СКД
Полезно использовать для конца периода в СКД в параметрах в поле Выражение следующую конструкцию:
ВЫБОР КОГДА &Период.ДатаОкончания=ДАТАВРЕМЯ(1,1,1) ИЛИ &Период.ДатаОкончания<&Период.ДатаНачала ТОГДА ДАТАВРЕМЯ(3999,12,31,23,59,59) ИНАЧЕ &Период.ДатаОкончания КОНЕЦ
Правильный вывод остатков регистра накопления при выводе регистратора в СКД
В параметрах виртуальной таблицы регистра накопления периодичность выбирается «АВТО». В выбранные поля добавляется Регистратор и обязательно - ПериодСекунда.
Особенности получения остатков по регистру в СКД
Для получения правильных остатков в запрос схемы компановки данных СКД должны быть включены поля и с Начальным, и с Конечным остатками виртуальной таблицы, а выводить можно уже только один из них.
Построитель отчета
Построитель = Новый ПостроительОтчета; Построитель.Текст = "Текст запроса"; Построитель.Параметры.Вставить("ПараметрЗапроса", ЗначениеПараметраЗапроса); Построитель.ЗаполнитьНастройки(); Построитель.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.БезОформления); Построитель.Выполнить(); Построитель.Вывести(); // Или Построитель.Вывести(ТабДок) (ТабДок может быть ЭлементыФормы.ПолеТабличногоДокумента) // посмотреть макет можно: Построитель.Макет.Показать()
&НаСервере Функция ПолучитьТабличныйДокументИзТабличнойЧасти(НаименованиеТабЧасти = "ТаблицаРезультат_ОбщПравилаОстатки") ТабДокумент = Новый ТабличныйДокумент; ОбработкаОбъект = РеквизитФормыВЗначение("Отчет"); ТаблицаСДанными = Неопределено; Выполнить("ТаблицаСДанными = ОбработкаОбъект." + НаименованиеТабЧасти + ".Выгрузить()"); Если ТипЗнч(ТаблицаСДанными) <> Тип("ТаблицаЗначений") Тогда Возврат ТабДокумент; КонецЕсли; Построитель = Новый ПостроительОтчета; Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаСДанными); Построитель.Выполнить(); Построитель.Вывести(ТабДокумент); Возврат ТабДокумент; КонецФункции
Статья Печенкина Романа на Mista.ru Ссылка на статью