Универсальная функция для программного выполнения СКД

Часто встречаются вопросы на форумах о программном формировании СКД. Вроде и информации много по этому поводу, но… Все как всегда 🙂
Собственно, в описании без лишних слов выложен текст общей функции, в которую, для выполнения отчета, нужно передать (минимум 2 параметра): СКД и ТабличныйДокумент.

Передаваемые параметры описаны в комментарии к процедуре.
Функция возвращает ДанныеРасшифровкиКомпоновкиДанных.

Из БСП используется только общая процедура:
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора() 

Собственно сама общая функция.

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

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


Для каждого ТекущийПараметр Из СтруктураПараметров Цикл

ОбщегоНазначенияКлиентСервер.УстановитьПараметрСКД(СКД.Параметры, ТекущийПараметр.Ключ, ТекущийПараметр.Значение, ОграничениеИспользованияПараметров);

КонецЦикла;

Если ПустаяСтрока(ИмяВариантаНастроек) Тогда
Настройки = СКД.НастройкиПоУмолчанию;
Иначе
НайденныйВариант = СКД.ВариантыНастроек.Найти(ИмяВариантаНастроек);
Если НайденныйВариант = Неопределено Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Не найден вариант настроек " + НайденныйВариант);
Возврат Неопределено;
КонецЕсли;
Настройки = НайденныйВариант.Настройки;
КонецЕсли;

Отбор = Настройки.Отбор;

Для каждого ТекущийПараметр Из Настройки.ПараметрыДанных.Элементы Цикл
// Надеюсь, временный костыль. Нужно перебрать параметры варианта и установить их.

ИмяПараметра        = Строка(ТекущийПараметр.Параметр);
ЗначениеПараметра   = Неопределено;
Если СтруктураПараметров.Свойство(ИмяПараметра, ЗначениеПараметра) Тогда
ТекущийПараметр.Использование   = Истина;
ТекущийПараметр.Значение        = ЗначениеПараметра;
КонецЕсли;

КонецЦикла;

Для каждого ТекущийОтбор Из СтруктураОтборов Цикл

Если ТекущийОтбор.Ключ = "СложныйОтбор" Тогда
// Если в качестве ключа строка "СложныйОтбор", значит установка отбора через общие процедуры:
//  ОбщиеПроцедуры.УстановитьУниверсальныйОтбор(Отбор);

Выполнить ТекущийОтбор.Значение;

Иначе

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

Для каждого ТекущийПараметрОтбора Из МассивПараметровОтбора Цикл

Если ТекущийОтбор.Значение.Свойство(ТекущийПараметрОтбора) Тогда

СтруктураПараметровПроцедуры.Вставить(ТекущийПараметрОтбора, ТекущийОтбор.Значение[ТекущийПараметрОтбора]);

КонецЕсли;

КонецЦикла;

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

КонецЕсли;

КонецЦикла;


КомпоновщикМакетаКомпоновкиДанных = Новый КомпоновщикМакетаКомпоновкиДанных;
ДанныеРасшифровкиКомпоновкиДанных = Новый ДанныеРасшифровкиКомпоновкиДанных;
МакетКомпоновкиДанных = КомпоновщикМакетаКомпоновкиДанных.Выполнить(СКД, Настройки, ДанныеРасшифровкиКомпоновкиДанных);

ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
Если Не СтруктураИсточниковДанных = Неопределено Тогда
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, СтруктураИсточниковДанных, ДанныеРасшифровкиКомпоновкиДанных);
Иначе
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновкиДанных, , ДанныеРасшифровкиКомпоновкиДанных);
КонецЕсли;

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);

СтруктураВозврата = Новый Структура;
СтруктураВозврата.Вставить("ДанныеРасшифровкиКомпоновкиДанных", ДанныеРасшифровкиКомпоновкиДанных);

Возврат СтруктураВозврата;

КонецФункции // ВыполнитьСКД

 Спасибо, Yashazz, за то что нашел использование общей процедуры УстановитьПараметрСКД()(которую я не описал).

// Поиск и установка значения параметра схемы компоновки данных
// Параметры:
//  ПараметрыСКД  - ПараметрыСхемыКомпоновкиДанных - Параметры СКД
//  ИмяПараметра  - Строка  - Имя параметра
//  ЗначениеПараметра - Произвольное - Устанавливаемое значение параметра
//
Процедура УстановитьПараметрСКД(ПараметрыСКД, ИмяПараметра, ЗначениеПараметра, ОграничениеИспользования = Неопределено) Экспорт

НайденныйПараметр = ПараметрыСКД.Найти(ИмяПараметра);
Если НайденныйПараметр = Неопределено Тогда
Возврат;
КонецЕсли;

НайденныйПараметр.Значение  = ЗначениеПараметра;

Если Не ОграничениеИспользования = Неопределено Тогда
НайденныйПараметр.ОграничениеИспользования = ОграничениеИспользования;
КонецЕсли;

КонецПроцедуры // УстановитьПараметрСКД
 

18 Comments

  1. zqzq

    Уже было http://infostart.ru/public/80164/ причем без использования внешних функций из БСП и с возможностью выгрузки в таблицу значений. Также лучше передавать не ИмяВариантаНастроек, а сам вариант настроек: при наличии компоновщика настроек Компоновщик.ПолучитьНастройки() возвращает настройки с учетом пользовательских настроек компоновщика, по имени варианта вы их не получите.

    Reply
  2. dj_serega

    (1) zqzq, Спасибо за ссылку на статью. Но в ней нет возможности установить отборы (поэтому и используется общая процедура). Получается по ссылке мы можем только выполнить СКД.

    Вот рабочий пример выполнения с параметрами, отборами и вариантом.

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

    Показать

    Reply
  3. zqzq

    (2) пользуюсь той процедурой. При необходимости отбора, его можно установить в настройке и передать саму настройку. Тут, наверное, удобнее.

    Reply
  4. Yashazz

    Чудовищный баян. Но, вероятно, те, кому лень почитать пару абзацев у Хрусталёвой, рады возможности воспользоваться халявой, чем и объясняется рейтинг статьи.

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

    Из БСП используется только общая процедура:

    ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбора()

    Полагаю, каждый более-менее грамотный специалист давно для себя сделал пакетники для работы с СКД и пользуется ими.

    p.s. не говоря уж о том, что предложенное ещё и не универсально. Вывода в таблицу значений нет, а бывает очень надо. Действительно профессиональным подходом было бы сделать общий механизм — в табличный документ, таблицу, дерево.

    …жаль, не нашёл, где минуснуть можно.

    Reply
  5. dj_serega

    (4) Yashazz, Извиняюсь за указанную общую процедуру не из БСП. Уже приложил к публикации.

    Автор, видимо, не в курсе возможности такой вещи, как КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра, поэтому делает какие-то странные костыли,

    Вкурсе-вкурсе.

    1. Читаем СП:

    Описание:

    Устанавливает значение параметра и включает свойство Использование. Если параметр с указанным именем не найден, будет вызвано исключение.

    .

    Обрабатывать исключения попыткой нет желания 😉

    2. КомпоновщикНастроек есть в отчетах. А я эту функцию вызываю из справочников, документов и при программном формировании скд.

    3.

    p.s. не говоря уж о том, что предложенное ещё и не универсально. Вывода в таблицу значений нет, а бывает очень надо. Действительно профессиональным подходом было бы сделать общий механизм — в табличный документ, таблицу, дерево.

    В будущем планировал реализовать вывод в таблицу значений.

    Текущий вариант функции взят с рабочего механизма. После написания этой функции, не приходилось выводить в ТЗ. Поэтому и не реализовано.

    Чудовищный баян.

    И почему баян так еще и чудовищный?

    Reply
  6. Yashazz

    (5)

    КомпоновщикНастроек есть в отчетах. А я эту функцию вызываю из справочников, документов и при программном формировании скд.

    Да что вы говорите? А вот это уже отменили, да?

     комп=Новый КомпоновщикНастроекКомпоновкиДанных;
    комп.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(мояСКД));
    комп.ЗагрузитьНастройки(мояСКД.НастройкиПоУмолчанию);
    

    спокойно юзается, где только в голову взбредёт.

    Обрабатывать исключения попыткой нет желания 😉

    А использовать циклы там, где не надо, желание есть?

    Я у себя уж лет пять назад всё сделал, и в таблицу значений, и куда угодно…

    Reply
  7. dj_serega

    (6) Yashazz,

    Да что вы говорите? А вот это уже отменили, да?

    Не злитесь 😉

    А использовать циклы там, где не надо, желание есть?

    Как по мне то цикл с одной итерацией лучше чем инициализировать компоновщик и загружать настройки.

    Я у себя уж лет пять назад всё сделал, и в таблицу значений, и куда угодно…

    Можно увидеть ссылку на публикацию?

    Reply
  8. Yashazz

    (7) а вы возьмите любую из моих публикаций, где мне ругались в комментах на отсутствие функций «СоздатьСКД» или «ПревращениеИмениВНаименование». Я это пихаю почти везде, а запостить вместе с основным кодом иногда забываю)))

    upd: если очень надо, могу через прям щас запузырить сюда все свои основные блоки на эту тему

    Reply
  9. dj_serega

    (8) Yashazz,

    если очень надо, могу через прям щас запузырить сюда все свои основные блоки на эту тему

    А может Офигенную публикацию по своим основным блокам сделаете? 😉

    Reply
  10. Yashazz
    Reply
  11. Yashazz

    Вообще, тенденция пугающая. Стабильно большой популярностью пользуются куцые, слабо структурированные, откровенно копипащенные, мутно и отрывочно изложенные «публикации», выложенные средненько знающими для совсем слабо знающих. За счёт рейтинга такие горе-публикации легко обходят действительно профессиональные разработки, стоившие несоизмеримо больше ресурсов их авторам. Энтузиазм профи-авторов, таким образом, не получает должной оценки. Так на первый план ИС выходят не профессиональные разработки, как хотелось бы, а убогие исходники или псевдо-учебные фрагменты (редко-редко можно видеть действительно качественный учебник, буде то справочник или пошаговик). В результате ИС становится «лягушатником» для начинающих, которые и жёлтых книжек-то не читали, не то что материалов ИТС, а в «лучших» публикациях болтается такое позорище, что уж не знаю, как Доржи перед 1С не стыдно.

    пы.сы. Себя отношу не к профи, а к средненько знающим. Именно посмотрев на ситуацию и рейтинг, резко перестал выкладывать «статьи». Мне хватило печального опыта с XPath и модальностями/асинхроном. Жаль, что автору этой публикации самокритики недостаёт.

    Reply
  12. dj_serega

    (11) Yashazz,

    Стабильно большой популярностью пользуются куцые, слабо структурированные, откровенно копипащенные, мутно и отрывочно изложенные «публикации», выложенные средненько знающими для совсем слабо знающих.

    Такие публикации не всегда вырываются в перед.

    Так на первый план ИС выходят не профессиональные разработки, как хотелось бы

    Да ну. Вот взять к примеру ildarovich‘а. Его публикации всегда пользуются популярностью. И очень часто на первых местах.

    Жаль, что автору этой публикации самокритики недостаёт.

    Жаль что Вы так считаете.

    Именно посмотрев на ситуацию и рейтинг, резко перестал выкладывать «статьи».

    А Вы не сдавайтесь, выкладывайте свои Стоящие статьи. С интересом почитаю.

    Reply
  13. gigapevt

    (12) Согласен с автором, тоже с удовольствием почитаю !

    Reply
  14. alon

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

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

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

    Вы же не предъявляете к ребенку на уроке рисования те же требования, что и к выпускнику художественного училища? То же самое и тут.

    Reply
  15. IamIvan

    Программное выполнение это здорово.

    А кто-нибудь решал задачку такого рода:

    Есть внешние отчеты на СКД. Надо из одной конфигурации выполнить их в другой и отобразить.

    Я ничего кроме как выполнить запрос через ком и подставь в таблицу набора не придумал.

    Reply
  16. tristarr1

    (15) IamIvan, А данные нужны с расшифровками? если без, то можно выполнять их и передавать табличный документ.

    Reply
  17. akor77

    (5) не поддавайся на провокации!

    Процветай и преуспевай!

    http://www.scientology.ru/videos/category/twth/twth-film-precept-21.html#/videos/category/twth/twth-film-precept-21

    Вспомни, как меня на корню хотел один тип задавить.

    Начал, продолжай, развивай!

    Reply
  18. cleaner_it

    (14) Больше двух лет прошло — до сих пор актуально)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *