Введение
Программное формирование отчета на СКД выполняется с помощью следующего кода, который очень многие не раз использовали:
Стандартное программное формирование отчета на СКД
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
//Можем редактировать настройки компоновки (ИтоговыеНастройки)
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
//Можем редактировать табличный документ (ДокументРезультат)
КонецПроцедуры
Программное формирование используется очень многими разработчиками, в том числе, встречается и в типовых системах. Стандартные причины использования - это необходимость программной доработки отчета, которая обычно выполняется через программную доработку настройки компоновки или через корректировки итогового табличного документа. Но, по каким-то причинам (я таких примеров не видел), не используются возможности объектов МакетКомпоновкиДанных и ПроцессорКомпоновкиДанных. Ключевое удобство их использования состоит в том что на момент их выполнения мы одновременно имеем данные и по настройкам (структуре) отчета, и итоговые данные, рассчитанные для вывода. Далее я опишу возможности использования данных объектов и приведу примеры. Некоторые примеры, возможно, покажутся выдуманными, а для некоторых могут быть другие пути решения, но цель данных примеров показать возможности неиспользуемых механик СКД, а как вы их будете применять на практике, вам виднее. Кроме того, в прикрепленных файлах приложу отчет со всеми приведенными здесь примерами и даже более. Для формирования отчета нужен регистр бухгалтерии Хозрасчетный, но я проверял его только на 1С: Бухгалтерия 3.0.
Всё, что будет описано далее, это предмет моих личных изысканий и не претендует на полноту.
МакетКомпоновкиДанных - хранит и предоставляет возможность редактировать все макеты табличного документа, которые подготовлены компоновщиком и будут использоваться при выводе отчета.
ПроцессорКомпоновкиДанных - позволяет не только сформировать весь отчет единовременно, но и может заполнять табличный документ по элементам (строкам) отчета используя объект ЭлементРезультатаКомпоновкиДанных.
С учетом вышесказанного, текст кода программного формирования отчета можно представить в виде:
Расширенное программное формирование отчета на СКД
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
//Можем редактировать настройки компоновки (ИтоговыеНастройки)
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
//Можем редактировать итоговые наборы данных и макеты табличного документа (МакетКомпоновкиДанных)
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
//Формируем отчет поэлементно
//Вместо стандартного вывода одним методом - ПроцессорВывода.Вывести(ПроцессорКомпоновки)
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
//Можем редактировать данные, внешний вид и расшифровку выводимого элемента (ЭлементРезультата)
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
//Можем редактировать табличный документ (ДокументРезультат)
КонецПроцедуры
Макет компоновки данных
Посмотрим какие свойства есть у объекта МакетКомпоновкиДанных:
Свойства Макета компоновки данных
- ЗначенияПараметров - значения общих для отчета параметров. Это, прежде всего, параметры Схемы Компоновки Данных;
- НаборыДанных, СвязиНаборовДанных, ИсточникиДанных - итоговые наборы данных для получения информации для отчета;
- ТребуемаяАктуальностьДанных, ТребуемоеВремяАктуальностиДанных - параметры, определяющие возможность использования данных из Копии базы данных;
- Тело - содержит структуру итогового отчета с указанием макетов, которые должны использоваться;
- Макеты - собственно макеты, используя которые будет формироваться итоговый отчет.
Из представленных свойств нам сейчас будут наиболее интересны Тело и Макеты, с помощью которых можно редактировать макеты табличного документа, подготовленные компоновщиком для формирования отчета. В них можно менять значения и расшифровку ячеек, изменять выражения для расчета параметров, менять внешний вид, объединять и разъединять ячейки по строкам и колонкам, и многое другое. Все свойства более-менее понятны и вы сможете сами подробно их посмотреть через отладчик, но я приведу их краткое описание:
Описание Тела Макета компоновки данных
Тело макета компоновки состоит из массива элементов, описывающих отображение данных отчета в порядке их вывода.
Стандартный перечень элементов отчета:
Индекс |
Значение элемента |
Макет |
Идентификатор |
... |
МакетШапки |
МакетПодвала |
Тело |
ТелоИерархии |
0 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет1" |
<> |
... |
<> |
<> |
<> |
<> |
1 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет2" |
<> |
... |
<> |
<> |
<> |
<> |
2 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет3" |
<> |
... |
<> |
<> |
<> |
<> |
3 |
ГруппировкаМакетаКомпоновкиДанных |
<> |
"" |
... |
"" |
"" |
ТелоМакетаКомпоновкиДанных |
ТелоМакетаКомпоновкиДанных |
4 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет5" |
<> |
... |
<> |
<> |
<> |
<> |
5 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет6" |
<> |
... |
<> |
<> |
<> |
<> |
6 |
МакетОбластиМакетаКомпоновкиДанных |
"Макет7" |
<> |
... |
<> |
<> |
<> |
<> |
7 |
ГруппировкаМакетаКомпоновкиДанных |
<> |
"Группировка" |
... |
"" |
"Макет9" |
ТелоМакетаКомпоновкиДанных |
ТелоМакетаКомпоновкиДанных |
Первые 1-3 элемента - это заголовок отчета.
Далее идет группировка, выводящая информацию об актуальности выводимых данных. Это типовой элемент, который показывает актуальность при получении данных из Копии базы.
Далее могут присутствовать макеты с выводом Параметров и Отборов отчета.
Последний макет перед второй группировкой (индекс 6 из примера) - это шапка таблицы отчета. Найдя макет по имени "Макет7" в перечне макетов МакетКомпоновкиДанных.Макеты, мы можем программно его откорректировать и получить нужную нам шапку для отчета. Зачастую, это гораздо удобнее, чем пользоваться макетами в соответствующем разделе настроек СКД, а иногда, это единственный удобный выход для формирования необходимой шапки таблицы отчета. По редактированию шапки будет приведен пример.
Последний элемент - это, собственно, наша таблица с отчетом. В колонках Тело и ТелоИерархии мы можем найти макеты для вывода строк отчета. В случае использования нескольких группировок, в колонке Тело будут указаны, в том числе, нижестоящие группировки.
В элементе тела с типом ГруппировкаМакетаКомпоновкиДанных есть еще множество свойств, определяющих формирование отчета, в том числе, Выражения по отбору записей и группировок и Выражения для определения порядка.
Есть еще множество типов элементов тела для описания таблиц, диаграмм и других составных частей отчета, но здесь их рассматривать не буду.
Все макеты, указанные в Теле макета компоновки данных, определены в МакетКомпоновкиДанных.Макеты:
Описание Макетов областей Макета компоновки данных
В свойстве Макеты у Макета компоновки данных содержится перечень всех макетов, используемых для вывода отчета и указанных в Теле Макета компоновки данных.
Данный перечень мы можем дополнить своим Описанием макета области и использовать его при выводе отчета, и, конечно, можем отредактировать каждое существующее описание макетов.
У Описания макета области есть следующие свойства:
- Имя - необходимо для идентификации макета, в том числе, в Теле Макета компоновки данных.
- Макет - собственно, содержит все данные об оформлении и содержании выводимых данных. Стандартный тип объекта для табличного отчета - МакетОбластиКомпоновкиДанных, но могут быть и другие типы при выводе диаграмм и др.
- Параметры - содержит перечень параметров, используемых в представленном Макете. Есть 2 типа параметров - выражение и расшифровка. Мы можем, например, поменять выражение, определенное из настроек, можем добавить дополнительный параметр, результат которого мы будем использовать при выводе области по данному макету, и пр.
МакетОбластиКомпоновкиДанных представляет собой массив описаний строк области, каждое из которых содержит перечень ячеек (суть, колонок), каждая из которых содержит:
- Перечень элементов ПолеОбластиКомпоновкиДанных с перечнем значений, выводимых в ячейку, с указанием правил оформления по каждому значению.
- Принципы оформления ячейки области, в том числе, с указанием на параметр расшифровки, с указанием принципов объединения и т.д.
Таким образом код МакетКомпоновкиДанных.Макеты["Макет7"].Макет[0].Ячейки[0].Элементы[0].Значение покажет текст верхней левой ячейки шапки таблицы.
Элемент результата компоновки данных
При поэлементном выводе отчета в табличный документ, мы (как показано выше в "расширенном" программном формировании) на каждом шаге получаем объект типа ЭлементРезультатаКомпоновкиДанных. Посмотрим какие у него есть свойства:
Свойства Элемента результата компоновки данных
- Макет - имя макета, который используется при выводе данного элемента в отчет;
- ЗначенияПараметров - массив значений параметров, определенных в Описании макетов областей компоновки данных;
- ТипЭлемента
Возможные значения: Начало / Конец / Начало и конец
Элементы с типом Начало / Конец не служат для вывода данных, а нужны только для фиксации того что начинается (заканчивается) вывод нижестоящей группировки по Телу отчета.
Первый элемент будет всегда с типом Начало и фиксирует начало вывода отчета.
Подсчитывая количество начатых и завершенных элементов можно определить какая позиция Тела Макета компоновки в настоящий момент выводится.
- Макеты - перечень Описаний макетов областей компоновки данных, используемых текущим элементом или нижестоящими элементами (только если тип элемента - Начало).
В типовой ситуации данное свойство заполнено только у первого Элемента, и в нем приведены все описания макетов, определенные в МакетКомпоновкиДанных.Макеты.
При необходимости, для отдельных элементов или группировок можно переопределить используемое Описание макетов, на что-то индивидуальное.
- РасположениеВложенныхЭлементов - актуально только для элементов с типом Начало. Определяет горизонтальный или вертикальный вывод подчиненных элементов. Используется, например, при выводе колонок отчета вида Сводная таблица.
- ПроцентВывода - определяет выводимый процент от завершения формирования отчета.
Далее я приведу несколько примеров, показывающих как можно использовать данные механики СКД для "допилки" отчетов.
Все примеры сформированы для реализации выдуманного отчета вида Оборотно-сальдовая ведомость для 1С:Бухгалтерия 3.0. Такой пример использован по причине актуальности приведенных примеров в рамках одного отчета.
Для каждого примера используется абсолютно простая СКД с запросом к регистру Хозрасчетный.ОстаткиИОбороты. СКД можете найти в приложенных к статье файлах или сделать свою.
Настройка компоновки для примеров
Пример 1: Приведение шапки отчета к "нормальному" виду
Это часто встречающаяся проблема, когда не хватает возможностей настроек СКД. В том числе, использование макетов из настроек СКД не всегда помогает, например, по причине использования широких пользовательских настроек в итоговом отчете.
В примере выводим ОСВ с показателями БУ и НУ, выводящимся в вертикальной последовательности. Считаем, что в данной ОСВ пользователь сможет настраивать группировки, в том числе с выводом в нескольких колонках.
Хотим преобразовать шапку следующим образом:
Для такого преобразования можно программно отредактировать соответствующий макет в МакетКомпоновкиДанных.Макеты.
Программный код модуля объекта:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
/////////////////////////////////////////////////////////
//Обрабатываем шапку отчета приводя ее к желаемому виду
//Шапка таблицы отчета будет находиться в предпоследнем элементе Тела, т.к. отчет содержит только одну таблицу
ИмяМакетаШапки = МакетКомпоновкиДанных.Тело[МакетКомпоновкиДанных.Тело.Количество()-2].Макет;
ОписаниеМакетаШапки = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаШапки);
//Ищем номер колонки первого поля - ресурса, в котором у нас всегда будет значение "Показатели"
НомерКолонкиПервогоРесурса = 0;
Для Каждого ЯчейкаТаблицыОбласти Из ОписаниеМакетаШапки.Макет[0].Ячейки Цикл
НомерКолонкиПервогоРесурса = НомерКолонкиПервогоРесурса + 1;
Если ЯчейкаТаблицыОбласти.Элементы.Количество() и ЯчейкаТаблицыОбласти.Элементы[0].Значение = "Показатели" Тогда
Прервать;
КонецЕсли;
КонецЦикла;
//Определяем сколько необходимо строк в шапке для вывода имен группировок
КолвоСтрокСИменамиГруппировок = 0;
Для НКолонки = 1 По НомерКолонкиПервогоРесурса-1 Цикл
Для НСтроки = 1 По ОписаниеМакетаШапки.Макет.Количество() Цикл
Если НЕ ОписаниеМакетаШапки.Макет[НСтроки-1].Ячейки[0].Элементы.Количество() Тогда
Прервать;
КонецЕсли;
КолвоСтрокСИменамиГруппировок = Макс(КолвоСтрокСИменамиГруппировок, НСтроки);
КонецЦикла;
КонецЦикла;
//Удаляем лишние строки (для ресурсов надо 2, для группировок выяснили ранее)
НадоСтрокДляШапки = Макс(КолвоСтрокСИменамиГруппировок, 2);
Для й = НадоСтрокДляШапки+1 По ОписаниеМакетаШапки.Макет.Количество() Цикл
ОписаниеМакетаШапки.Макет.Удалить(ОписаниеМакетаШапки.Макет.Количество()-1);
КонецЦикла;
//Центрируем весь текст во всех ячейках шапки
Для Каждого Строка Из ОписаниеМакетаШапки.Макет Цикл
Для Каждого Ячейка Из Строка.Ячейки Цикл
Ячейка.Оформление.УстановитьЗначениеПараметра("ГоризонтальноеПоложение", ГоризонтальноеПоложение.Центр);
Ячейка.Оформление.УстановитьЗначениеПараметра("ВертикальноеПоложение", ВертикальноеПоложение.Центр);
КонецЦикла;
КонецЦикла;
//Очищаем текст во всех ячейках колонок-ресурсов начиная со 2й строки и объединяем их с верхними
Для НСтроки = 3 По ОписаниеМакетаШапки.Макет.Количество() Цикл
СтрокаМакета = ОписаниеМакетаШапки.Макет[НСтроки-1];
Для НКолонки = НомерКолонкиПервогоРесурса По СтрокаМакета.Ячейки.Количество() Цикл
Ячейка = СтрокаМакета.Ячейки[НКолонки-1];
Ячейка.Элементы.Очистить();
Ячейка.Оформление.УстановитьЗначениеПараметра("ОбъединятьПоВертикали", Истина);
КонецЦикла;
КонецЦикла;
//Объединяем ячейки в колонке с надписью Показатели
Для НСтроки = 2 По ОписаниеМакетаШапки.Макет.Количество() Цикл
Ячейка = ОписаниеМакетаШапки.Макет[НСтроки-1].Ячейки[НомерКолонкиПервогоРесурса-1];
Ячейка.Элементы.Очистить();
Ячейка.Оформление.УстановитьЗначениеПараметра("ОбъединятьПоВертикали", Истина);
КонецЦикла;
///////////////////////////////////////////////////////////
//Далее - типовой вывод
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Пример 2: Различные элементы группировки отчета выводим по-разному
В нашем ОСВ выводятся показатели БУ и НУ в вертикальной последовательности. Т.е. по каждой строке группировки получаем 2 строки в таблице отчета.
Но не все счета учитываются по НУ, соответственно, по ним не имеет смысла выводить показатель НУ.
В типовых это решено через установку максимальной высоты = 1 в условном оформлении, что, как мне кажется, не лучший вариант.
Должно выводиться следующим образом:
Для упрощения программного кода реализации примера, предполагаем, что в отчете может быть только одна группировка - по счетам с иерархией, и расшифровка невозможна. Исключить данные ограничения не сложно самостоятельно, или можете посмотреть в приложенном к статье отчете.
Алгоритм реализации (укрупнено):
Программный код модуля объекта:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
/////////////////////////////////////////////////////////
//Обрабатываем Настройки компоновки
//Нам нужно добавить обязательный расчет поля Счет.НалоговыйУчет, причем и для элементов и для иерархии
//Это можно сделать, например, добавив элемент условного оформления, который ничего не будет делать
НовоеУсловноеОформление = ИтоговыеНастройки.УсловноеОформление.Элементы.Добавить();
НовоеУсловноеОформление.Использование = Истина;
НовыйЭлементОтбора = НовоеУсловноеОформление.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлементОтбора.Использование = Истина;
НовыйЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Счет.НалоговыйУчет");
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйЭлементОтбора.ПравоеЗначение = Ложь;
/////////////////////////////////////////////////////////
//Продолжаем вывод
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
/////////////////////////////////////////////////////////
//Обрабатываем МакетКомпоновкиДанных
//Группировка (таблица) отчета будет находиться в последнем элементе Тела, т.к. отчет содержит только одну таблицу
ГруппировкаМакетаТаблицы = МакетКомпоновкиДанных.Тело[МакетКомпоновкиДанных.Тело.Количество()-1];
//Определяем макеты строк отчета, предполагая что есть только иерархическая группировка по счетам
ИмяМакетаГруппировки = ГруппировкаМакетаТаблицы.Тело[0].Макет;
ОписаниеМакетаГруппировки = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаГруппировки);
ИмяМакетаГруппировкиИерархии = ГруппировкаМакетаТаблицы.ТелоИерархии[0].Макет;
ОписаниеМакетаГруппировкиИерархии = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаГруппировкиИерархии);
//В макетах строк отчета добавляем параметр для определения, что счет относиться к НУ
НовыйПараметр = ОписаниеМакетаГруппировки.Параметры.Добавить(Тип("ПараметрОбластиВыражениеКомпоновкиДанных"));
НовыйПараметр.Имя = "ВыводитьНУ";
НовыйПараметр.Выражение = "НаборДанных1.Счет.НалоговыйУчет";
НовыйПараметр = ОписаниеМакетаГруппировкиИерархии.Параметры.Добавить(Тип("ПараметрОбластиВыражениеКомпоновкиДанных"));
НовыйПараметр.Имя = "ВыводитьНУ";
НовыйПараметр.Выражение = "СчетИерархия.Счет.НалоговыйУчет";
//Формируем макеты для строк отчета, у которых не будет выводиться показатель НУ
НовоеОписаниеМакета = МакетКомпоновкиДанных.Макеты.Добавить();
НовоеОписаниеМакета.Имя = ИмяМакетаГруппировки+"БезНУ";
СкопироватьОписаниеМакета(НовоеОписаниеМакета, ОписаниеМакетаГруппировки);
НовоеОписаниеМакета.Макет.Удалить(1);
НовоеОписаниеМакета = МакетКомпоновкиДанных.Макеты.Добавить();
НовоеОписаниеМакета.Имя = ИмяМакетаГруппировкиИерархии+"БезНУ";
СкопироватьОписаниеМакета(НовоеОписаниеМакета, ОписаниеМакетаГруппировкиИерархии);
НовоеОписаниеМакета.Макет.Удалить(1);
/////////////////////////////////////////////////////////
//Продолжаем вывод
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
/////////////////////////////////////////////////////////
//Формируем отчет поэлементно
//Отслеживаем вывод строк отчета и при необходимости меняем используемый макет
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
//Убираем строки НУ, в случае если по счету не ведется налоговый учет
Если ЭлементРезультата.Макет = ИмяМакетаГруппировки Тогда
Если НЕ ЭлементРезультата.ЗначенияПараметров.ВыводитьНУ.Значение Тогда
ЭлементРезультата.Макет = ИмяМакетаГруппировки+"БезНУ";
КонецЕсли;
ИначеЕсли ЭлементРезультата.Макет = ИмяМакетаГруппировкиИерархии Тогда
Если НЕ ЭлементРезультата.ЗначенияПараметров.ВыводитьНУ.Значение Тогда
ЭлементРезультата.Макет = ИмяМакетаГруппировкиИерархии+"БезНУ";
КонецЕсли;
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры
Процедура СкопироватьОписаниеМакета(НовоеОписаниеМакета, ИсходноеОписаниеМакет)
НовоеОписаниеМакета.Макет = СкопироватьОбъектЧерезСериализациюXML(ИсходноеОписаниеМакет.Макет);
Для Каждого ИсхПараметр Из ИсходноеОписаниеМакет.Параметры Цикл
ТипПараметра = ТипЗнч(ИсхПараметр);
НовыйПараметр = НовоеОписаниеМакета.Параметры.Добавить(ТипПараметра);
ЗаполнитьЗначенияСвойств(НовыйПараметр, ИсхПараметр);
Если ТипПараметра = Тип("ПараметрОбластиРасшифровкаКомпоновкиДанных") Тогда
Для Каждого ИсхВыражение Из ИсхПараметр.ВыраженияПолей Цикл
НовоеВыражение = НовыйПараметр.ВыраженияПолей.Добавить();
ЗаполнитьЗначенияСвойств(НовоеВыражение, ИсхВыражение);
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//Служит для создания копии программного объекта, в случаях отсутствия у него конструктора
Функция СкопироватьОбъектЧерезСериализациюXML(ИсходныйОбъект)
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ИсходныйОбъект);
ТекстXML = ЗаписьXML.Закрыть();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Возврат СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
КонецФункции
Пример 3: Выводим дополнительную информацию для отдельных элементов группировки
Реализуем в нашем ОСВ контроль отрицательных остатков. Т.е. чтобы на активных счетах было только дебетовое сальдо, а на пассивных только кредитовое, а также проконтролируем отсутствие отрицательного количества, если счет количественный.
Выглядеть это должно следующим образом:
Алгоритм реализации (укрупнено):
Программный код модуля объекта:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
/////////////////////////////////////////////////////////
//Обрабатываем Схему компоновки данных
//Все измерения, по которым будем контролировать остатки, должны быть в итоговом запросе
//Установим по всем полям, используемым для контроля, признак Обязательный
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("СуммаНачальныйОстаток").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("СуммаКонечныйОстаток").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("КоличествоНачальныйОстаток").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("КоличествоКонечныйОстаток").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("Организация").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("Субконто1").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("Субконто2").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("Субконто3").Роль.Обязательное = Истина;
//Конечно это можно сделать в графическом режиме при настройке схемы
//Обрабатываем Настройки компоновки
//Нам нужно добавить обязательный расчет поля Счет.Количественный
//Это можно сделать, например, добавив элемент условного оформления, который ничего не будет делать
НовоеУсловноеОформление = ИтоговыеНастройки.УсловноеОформление.Элементы.Добавить();
НовоеУсловноеОформление.Использование = Истина;
НовыйЭлементОтбора = НовоеУсловноеОформление.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлементОтбора.Использование = Истина;
НовыйЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Счет.Количественный");
НовыйЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйЭлементОтбора.ПравоеЗначение = Ложь;
/////////////////////////////////////////////////////////
//Продолжаем вывод
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
/////////////////////////////////////////////////////////
//Обрабатываем МакетКомпоновкиДанных
//Нам нужно добавить расчет служебного параметра для определения отрицательного остатка по счетам
//Группировка (таблица) отчета будет находиться в последнем элементе Тела, т.к. отчет содержит только одну таблицу
ГруппировкаМакетаТаблицы = МакетКомпоновкиДанных.Тело[МакетКомпоновкиДанных.Тело.Количество()-1];
//Определяем макет строк отчета, предполагая что есть только иерархическая группировка по счетам
//Нам нужны только счета - элементы. Для групп проверять остатки не имеет смысла.
ИмяМакетаГруппировки = ГруппировкаМакетаТаблицы.Тело[0].Макет;
ОписаниеМакетаГруппировки = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаГруппировки);
//В макете добавляем служебный параметр для определения отрицательных остатков
НовыйПараметр = ОписаниеМакетаГруппировки.Параметры.Добавить(Тип("ПараметрОбластиВыражениеКомпоновкиДанных"));
НовыйПараметр.Имя = "КонтрольОстатков";
//Определяем отрицательные остатки на начало и конец периода по сумме и по количеству
//В качестве результата у нас будет возвращена таблица значений с представлениями аналитик
НовыйПараметр.Выражение =
"ВычислитьВыражениеСГруппировкойТаблицаЗначений(
|""Представление(НаборДанных1.Субконто1) КАК Субконто1, Представление(НаборДанных1.Субконто2) КАК Субконто2, Представление(НаборДанных1.Субконто3) КАК Субконто3"",
|""НаборДанных1.Счет, НаборДанных1.Организация, НаборДанных1.Субконто1, НаборДанных1.Субконто2, НаборДанных1.Субконто3"",
|,
|""ВЫБОР НаборДанных1.Счет.Вид
| КОГДА ЗНАЧЕНИЕ(ВидСчета.Активный)
| ТОГДА Сумма(НаборДанных1.СуммаНачальныйОстаток) < 0 или Сумма(НаборДанных1.СуммаКонечныйОстаток) < 0
| КОГДА ЗНАЧЕНИЕ(ВидСчета.Пассивный)
| ТОГДА Сумма(НаборДанных1.СуммаНачальныйОстаток) > 0 или Сумма(НаборДанных1.СуммаКонечныйОстаток) > 0
| ИНАЧЕ Ложь
|КОНЕЦ ИЛИ
|ВЫБОР
| КОГДА НаборДанных1.Счет.Количественный
| ТОГДА Сумма(НаборДанных1.КоличествоНачальныйОстаток) < 0 или Сумма(НаборДанных1.КоличествоКонечныйОстаток) < 0
| ИНАЧЕ Ложь
|КОНЕЦ"")";
//А если добавить группировку ПериодДень, то контроль будет выполняться по каждому дню за выбранный период
//В макете добавляем служебный параметр содержащий данные для расшифровки описания ошибки
// далее его можно будет обрабатывать, например, для открытия дополнительного отчета
НовыйПараметр = ОписаниеМакетаГруппировки.Параметры.Добавить(Тип("ПараметрОбластиРасшифровкаКомпоновкиДанных"));
НовыйПараметр.Имя = "РасшифровкаКонтроляОстатков";
НовоеПолеРасшифровки = НовыйПараметр.ВыраженияПолей.Добавить();
НовоеПолеРасшифровки.Поле = "КонтрольОстатковПоСчету";
НовоеПолеРасшифровки.Выражение = "НаборДанных1.Счет";
НовыйПараметр.ОсновноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет;
/////////////////////////////////////////////////////////
//Продолжаем вывод
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
/////////////////////////////////////////////////////////
//Формируем отчет поэлементно
//Отслеживаем вывод строк отчета и при необходимости выводим данные по контролю остатков
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
Если ЭлементРезультата.Макет = ИмяМакетаГруппировки
И ЭлементРезультата.ЗначенияПараметров.КонтрольОстатков.Значение.Количество()
Тогда
//Обнаружили наличие отрицательных остатков
ОтрицательныеОстатки = ЭлементРезультата.ЗначенияПараметров.КонтрольОстатков.Значение;
//Сформируем текст описания ошибок, содержащего перечень аналитик
ТекстОписанияОшибки = "По счету есть отрицательные остатки по аналитикам:";
Для й=1 По Мин(3, ОтрицательныеОстатки.Количество()) Цикл
АналитикиСтроки = ОтрицательныеОстатки[й-1];
ТекстОписанияОшибки = ТекстОписанияОшибки+"
| - " + АналитикиСтроки.Субконто1 + "; " + АналитикиСтроки.Субконто2 + "; " + АналитикиСтроки.Субконто3;
КонецЦикла;
Если ОтрицательныеОстатки.Количество() > 3 Тогда
ТекстОписанияОшибки = ТекстОписанияОшибки+"
| - ... (всего "+ОтрицательныеОстатки.Количество()+" аналитик)";
КонецЕсли;
//Сформируем значение расшифровки, по которому мы сможем вывести какой-нибудь дополнительный отчет
РасшифровкаОписанияОшибки = ЭлементРезультата.ЗначенияПараметров.РасшифровкаКонтроляОстатков.Значение;
//Для вывода описания добавим под счетом дополнительную строку,
// для чего можно переопределить выводимый макет непосредственно в выводимом элементе
СформироватьМакетСДобавлениемСтрокиДляВыводаОписанияТекстаОшибок(ЭлементРезультата, ОписаниеМакетаГруппировки, ТекстОписанияОшибки, РасшифровкаОписанияОшибки);
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры
Процедура СформироватьМакетСДобавлениемСтрокиДляВыводаОписанияТекстаОшибок(ЭлементРезультата, ИсходноеОписаниеМакета, ТекстОписанияОшибки, РасшифровкаОписанияОшибки)
НовыйОписаниеМакета = ЭлементРезультата.Макеты.Добавить();
НовыйОписаниеМакета.Имя = ЭлементРезультата.Макет;
НовыйОписаниеМакета.Макет = СкопироватьОбъектЧерезСериализациюXML(ИсходноеОписаниеМакета.Макет);
ИндексПоследнейСтроки = НовыйОписаниеМакета.Макет.Количество()-1;
СтрокаИсходная = НовыйОписаниеМакета.Макет[ИндексПоследнейСтроки];
НоваяСтрокаМакета = НовыйОписаниеМакета.Макет.Добавить(Тип("СтрокаТаблицыОбластиКомпоновкиДанных"));
НоваяСтрокаМакета.ИдентификаторТаблицы = НовыйОписаниеМакета.Макет[0].ИдентификаторТаблицы;
//Оформление новой строки будет совпадать с предыдущей
//Текст описания ошибок в остатках будет в первой следующей колонке после группировок
//Заполняем оформление ячеек группировок
Для НомКолонки = 1 По СтрокаИсходная.Ячейки.Количество() Цикл
ЯчейкаИсходная = СтрокаИсходная.Ячейки[НомКолонки-1];
ЗначениеОбъединения = ЯчейкаИсходная.Оформление.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ОбъединятьПоВертикали"));
Если НЕ ЗначениеОбъединения = Неопределено
И ЗначениеОбъединения.Использование
И ЗначениеОбъединения.Значение = Истина
Тогда
//Ячейка присоеденена к верхней, а значит относиться к группировке
Иначе
Прервать;
КонецЕсли;
НоваяЯчейка = НоваяСтрокаМакета.Ячейки.Добавить();
СкопироватьКоллекциюЗначенийПараметровОформления(НоваяЯчейка.Оформление.Элементы, ЯчейкаИсходная.Оформление.Элементы);
КонецЦикла;
НомерКолонкиСТекстомОписания = НомКолонки;
//Заполняем оформление ячейки с текстом описания ошибки
НоваяЯчейка = НоваяСтрокаМакета.Ячейки.Добавить();
СкопироватьКоллекциюЗначенийПараметровОформления(
НоваяЯчейка.Оформление.Элементы,
СтрокаИсходная.Ячейки[НомерКолонкиСТекстомОписания-1].Оформление.Элементы,
"ЦветФона, ЦветГраницы, СтильГраницы, Шрифт");
НоваяЯчейка.Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("ЦветТекста"), WebЦвета.Красный);
//Заполняем оформление остальных ячеек
Для НомКолонки = (НомерКолонкиСТекстомОписания+1) По СтрокаИсходная.Ячейки.Количество() Цикл
ЯчейкаИсходная = СтрокаИсходная.Ячейки[НомКолонки-1];
НоваяЯчейка = НоваяСтрокаМакета.Ячейки.Добавить();
СкопироватьКоллекциюЗначенийПараметровОформления(
НоваяЯчейка.Оформление.Элементы,
ЯчейкаИсходная.Оформление.Элементы,
"ЦветФона, ЦветГраницы, СтильГраницы, Шрифт");
НоваяЯчейка.Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("ОбъединятьПоГоризонтали"), Истина);
КонецЦикла;
//Выводим текст и расшифровку описания ошибок в остатках
ПолеТекстаОшибки = НоваяСтрокаМакета.Ячейки[НомерКолонкиСТекстомОписания-1].Элементы.Добавить(Тип("ПолеОбластиКомпоновкиДанных"));
ПолеТекстаОшибки.Значение = ТекстОписанияОшибки;
НоваяСтрокаМакета.Ячейки[НомерКолонкиСТекстомОписания-1].Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("Расшифровка"), РасшифровкаОписанияОшибки);
КонецПроцедуры
Процедура СкопироватьКоллекциюЗначенийПараметровОформления(Приемник, Источник, ОграничитьПараметры="", ИсключаяПараметры="")
Для Каждого ЭлементИсходный Из Источник Цикл
Если НЕ ЭлементИсходный.Использование Тогда
Продолжить;
ИначеЕсли НЕ ПустаяСтрока(ОграничитьПараметры) и СтрНайти(ОграничитьПараметры, Строка(ЭлементИсходный.Параметр)) = 0 Тогда
Продолжить;
ИначеЕсли СтрНайти(ИсключаяПараметры, Строка(ЭлементИсходный.Параметр)) > 0 Тогда
Продолжить;
КонецЕсли;
НовыйЭлемент = Приемник.Найти(ЭлементИсходный.Параметр);
НовыйЭлемент.Использование = Истина;
НовыйЭлемент.Значение = ЭлементИсходный.Значение;
СкопироватьКоллекциюЗначенийПараметровОформления(НовыйЭлемент.ЗначенияВложенныхПараметров, ЭлементИсходный.ЗначенияВложенныхПараметров);
КонецЦикла;
КонецПроцедуры
//Служит для создания копии программного объекта, в случаях отсутствия у него конструктора
Функция СкопироватьОбъектЧерезСериализациюXML(ИсходныйОбъект)
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ИсходныйОбъект);
ТекстXML = ЗаписьXML.Закрыть();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ТекстXML);
Возврат СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
КонецФункции
Пример 4: Выводим диаграммы в ячейках отчета
Для большей информативности о динамике финансовых показателей, добавим в наш ОСВ вывод графиков со значениями сальдо на каждый день по каждому счету.
Выглядеть это будет следующим образом:
Для упрощения программного кода реализации примера, добавим поле "График сальдо" в графическом режиме настройки СКД. Для этого, добавим пустое вычисляемое поле, сделаем его ресурсом и выведем в отчет первым показателем.
Кроме того, будем считать, что в отчете может быть только одна группировка - по счетам с иерархией, и расшифровка невозможна.
Исключить данные ограничения не сложно самостоятельно, или можете посмотреть в приложенном к статье отчете.
Алгоритм реализации (укрупнено):
Программный код модуля объекта:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ИтоговыеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
/////////////////////////////////////////////////////////
//Обрабатываем Схему компоновки данных
//Поля сальдо и день должны быть в итоговом запросе
//Установим по ним признак Обязательный
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("ПериодДень").Роль.Обязательное = Истина;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("СуммаНачальныйОстаток").Роль.Обязательное = Истина;
//Т.к. для поля СуммаНачальныйОстаток по умолчанию устанавливается роль остатка, мы ее должны снять,
// как и у симметричного поля СуммаКонечныйОстаток
// Если этого не сделать, то при формировании макета будет выведена ошибка,
// т.к. система не понимает как поля преобразовать с учетом роли
// ведь использование полей мы пропишем программно уже в сформированном макете.
// Роль, в данном случае, по этим полям нам не нужна.
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("СуммаНачальныйОстаток").Роль.Остаток = Ложь;
СхемаКомпоновкиДанных.НаборыДанных[0].Поля.Найти("СуммаКонечныйОстаток").Роль.Остаток = Ложь;
//Конечно, все это можно сделать в графическом режиме при настройке схемы
/////////////////////////////////////////////////////////
//Продолжаем вывод
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, ИтоговыеНастройки, ДанныеРасшифровки);
/////////////////////////////////////////////////////////
//Обрабатываем МакетКомпоновкиДанных
//Нам нужно добавить расчет служебного параметра для получения сальдо на каждый день
//Группировка (таблица) отчета будет находиться в последнем элементе Тела, т.к. отчет содержит только одну таблицу
ГруппировкаМакетаТаблицы = МакетКомпоновкиДанных.Тело[МакетКомпоновкиДанных.Тело.Количество()-1];
//Определяем макеты строк отчета, предполагая что есть только иерархическая группировка по счетам
ИмяМакетаГруппировки = ГруппировкаМакетаТаблицы.Тело[0].Макет;
ОписаниеМакетаГруппировки = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаГруппировки);
ИмяМакетаГруппировкиИерархии = ГруппировкаМакетаТаблицы.ТелоИерархии[0].Макет;
ОписаниеМакетаГруппировкиИерархии = МакетКомпоновкиДанных.Макеты.Найти(ИмяМакетаГруппировкиИерархии);
//В макетах элементов и иерархии добавляем служебный параметр с расчетом сальдо на каждый день
ВыражениеРасчетаСальдо =
"ВычислитьВыражениеСГруппировкойТаблицаЗначений(
|""НаборДанных1.ПериодДень КАК ПериодДень, Сумма(НаборДанных1.СуммаНачальныйОстаток) КАК Сальдо"",
|""НаборДанных1.ПериодДень"",
|,
|)";
НовыйПараметр = ОписаниеМакетаГруппировки.Параметры.Добавить(Тип("ПараметрОбластиВыражениеКомпоновкиДанных"));
НовыйПараметр.Имя = "СальдоНаКаждыйДень";
НовыйПараметр.Выражение = ВыражениеРасчетаСальдо;
НовыйПараметр = ОписаниеМакетаГруппировкиИерархии.Параметры.Добавить(Тип("ПараметрОбластиВыражениеКомпоновкиДанных"));
НовыйПараметр.Имя = "СальдоНаКаждыйДень";
НовыйПараметр.Выражение = ВыражениеРасчетаСальдо;
//В макетах настраиваем ячейки, где будут выводиться диаграммы
//Исходя из настроек компоновки, для вывода диаграммы используется вторая колонка отчета
ОписаниеМакетаГруппировки.Макет[0].Ячейки[1].Элементы.Очистить();
ОписаниеМакетаГруппировки.Макет[0].Ячейки[1].Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("РазмерКартинки"), РазмерКартинки.Пропорционально);
ОписаниеМакетаГруппировки.Макет[0].Ячейки[1].Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("Картинка"), Новый ПараметрКомпоновкиДанных("КартинкаДиаграммыПоСтроке"));
ОписаниеМакетаГруппировкиИерархии.Макет[0].Ячейки[1].Элементы.Очистить();
ОписаниеМакетаГруппировкиИерархии.Макет[0].Ячейки[1].Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("РазмерКартинки"), РазмерКартинки.Пропорционально);
ОписаниеМакетаГруппировкиИерархии.Макет[0].Ячейки[1].Оформление.УстановитьЗначениеПараметра(
Новый ПараметрКомпоновкиДанных("Картинка"), Новый ПараметрКомпоновкиДанных("КартинкаДиаграммыПоСтроке"));
//Указанный параметр КартинкаДиаграммыПоСтроке мы установим уже в элементе результата (см. далее)
/////////////////////////////////////////////////////////
//Продолжаем вывод
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
/////////////////////////////////////////////////////////
//Формируем отчет поэлементно
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
Прервать;
КонецЕсли;
Если ЭлементРезультата.Макет = ИмяМакетаГруппировки
ИЛИ ЭлементРезультата.Макет = ИмяМакетаГруппировкиИерархии
Тогда
//Добавляем значение параметра, из которого в ячейку будет устанавливаться картинка
ЗначениеПараметраКартинки = ЭлементРезультата.ЗначенияПараметров.Добавить();
ЗначениеПараметраКартинки.Имя = "КартинкаДиаграммыПоСтроке";
ЗначениеПараметраКартинки.Значение = ПолучитьКартикуДиаграммы(ЭлементРезультата.ЗначенияПараметров.СальдоНаКаждыйДень.Значение);
КонецЕсли;
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();
КонецПроцедуры
Функция ПолучитьКартикуДиаграммы(ДанныеГрафика)
Диаграмма = Новый Диаграмма;
Диаграмма.СерииВСтроках = Ложь;
Диаграмма.ТипДиаграммы = ТипДиаграммы.ГрафикСОбластями;
Диаграмма.ИсточникДанных = ДанныеГрафика;
Диаграмма.ОбластьЗаголовка.Расположение = РасположениеОбластиЗаголовкаДиаграммы.Нет;
Диаграмма.ОбластьЛегенды.Расположение = РасположениеЛегендыДиаграммы.Нет;
Диаграмма.ОбластьПостроения.ЛинииШкал = Новый Линия(ТипЛинииДиаграммы.НетЛинии);
Диаграмма.ОбластьПостроения.ШкалаТочек.ОтображениеЗаголовка = ОтображениеЗаголовкаШкалыДиаграммы.НеОтображать;
Диаграмма.ОбластьПостроения.ШкалаТочек.ПоложениеПодписейШкалы = ПоложениеПодписейШкалыДиаграммы.Нет;
Диаграмма.ОбластьПостроения.ШкалаЗначений.ОтображениеЗаголовка = ОтображениеЗаголовкаШкалыДиаграммы.НеОтображать;
Диаграмма.ОбластьПостроения.ШкалаЗначений.ПоложениеПодписейШкалы = ПоложениеПодписейШкалыДиаграммы.Нет;
Возврат Диаграмма.ПолучитьКартинку(60,30);
//Размеры картинки подобрал экспериментально
КонецФункции
Отчёт, прикрепленный к статье
В отчёте собраны все приведенные здесь примеры, но с возможностями группировки и расшифровки по периоду и субконто, и, в целом, реализованные в несколько более универсальном виде.
Отчет проверен на 1С: Бухгалтерия 3.0 версии 3.0.79.14 на платформе 8.3.16.1063. Но должен работать на любой Бухгалтерии 3.0 и ERP.
Прикрепленные файлы отличаются только количеством СМ. Кто хочет отблагодарить таким образом - я против не буду.