[ПОЛЕЗНОСТИ] по СКД и запросам (обновлено 14.11.11)


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

Данная статья задумывалась как небольшие полезности по СКД. Я надеюсь, что программисты, прочитав эту статью, не махнут рукой: "А, это фигня, все равно я делаю лучше (проще)". А задумались над возможностями и нашли способы реализации! Убедительная просьба, у кого есть возможность, прочитать хорошую литературу по СКД, например, Хрусталева Е.Ю. Разработка сложных отчетов в 1С Предприятии 8, а данная статья написана в большей мере, чтобы заинтересовать читателя, тут будут собираться наиболее неочевидные и интересные моменты работы с СКД.

Когда СКД только появилась, я задавал себе вопрос: "СКД для отчетов - замечательная вещь! Может быть, как-то можно ее использовать в работе и в других областях? Вместо запросов". С одной стороны, СКД - очень мощный инструмент, с другой стороны - как-то не совсем удобно или понятно его использовать (там же надо что-то куда-то вставлять, чтобы получить данные), а запрос написал и выгрузил в таблицу или дерево. Все разрешилось само собой (методом проб и ошибок, конечно), когда я стал решать реальные задачи. Сейчас я даже простые данные получаю с помощю СКД... спросите, почему? Есть одна, но очень серьезная причина:

Легкость написания, а главное, отладки запроса (в любой консоли). Те, кто сталкивался с запросами, знают, что некоторые запросы очень сложно отлаживать. Приходится использовать дополнительные обработки, чтобы "на лету" изменить параметры и посмотреть, что получится. К тому же в тех обработках, что я знаю, данные представляются как таблица значений, и понять, какое дерево значений получится в итоге, довольно сложно. Используя же СКД, мы получаем полное визульное представление о получаемых данных (за исключением иерархических данных, СКД при выгрузке, например, в дерево их просто выгрузит в развернутом виде, по каждому полю, но и это решаемо. Тут есть статьи, как это сделать, найду ссылку - добавлю сюда), а потом просто копируем настройки СКД в свою обработку.

Все же остается вопрос: как проще, быстрее и удобнее использовать СКД? Ведь тут, казалось бы, написание простых запросов имеет преимущество (хотя бы по времени написания)... Лично для меня многие вопросы закрылись после написания шаблонов. Надеюсь, что и для Вас они будут полезны.

 

//****************************************************************************
// ШАБЛОНЫ ДЛЯ ИСПОЛЬЗОВАНИЯ СКД
// {{
//****************************************************************************
// Заполняет переданный объект на основани СКД
//
// Параметры
//
//  СКД – собствеено настройки СКД
//
//  ОбъектДляЗагрузки – объект в который выгружаются данные, таблица значений, дерево значений, табличный документ
//
//  ИсполняемыеНастройки – Пользовательские настройки СКД если не указаны будут использованы настроки СКД по умолчанию
//
//  СтруктураПараметров - Структура – Передаваемые для СКД параметры
//
//  краткий лекбез, поправлю позже
//
Процедура ПолучитьДанныеНаОснованииСКД(СКД, ОбъектДляЗагрузки, ИсполняемыеНастройки = Неопределено, СтруктураПараметров = Неопределено, РасшифровкаСКД = Неопределено, МакетКомпоновки = Неопределено, ВнешниеНаборыДанных = Неопределено) Экспорт

   
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

    Если
ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда
       
ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанных");
    Иначе
       
ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений");
    КонецЕсли;

    Если
ИсполняемыеНастройки = Неопределено Тогда

       
ИсполняемыеНастройки = СКД.НастройкиПоУмолчанию;

    КонецЕсли;

    Если
СтруктураПараметров <> Неопределено Тогда

       
КоллекцияЗначенийПараметров = ИсполняемыеНастройки.ПараметрыДанных.Элементы;

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

           
НайденноеЗначениеПараметра = КоллекцияЗначенийПараметров.Найти(Параметр.Ключ);

            Если
НайденноеЗначениеПараметра <> Неопределено Тогда

               
НайденноеЗначениеПараметра.Использование = Истина;

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

            КонецЕсли;

        КонецЦикла;

    КонецЕсли;

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

   
ПроцессорКомпановки = Новый ПроцессорКомпоновкиДанных;

   
ПроцессорКомпановки.Инициализировать(МакетКомпоновкиСКД, ВнешниеНаборыДанных, РасшифровкаСКД);

    Если
ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда

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

       
ПроцессорВывода.УстановитьДокумент(ОбъектДляЗагрузки);

    Иначе

       
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;

       
ПроцессорВывода.УстановитьОбъект(ОбъектДляЗагрузки);

    КонецЕсли;

   
ПроцессорВывода.ОтображатьПроцентВывода = Истина;

   
ПроцессорВывода.Вывести(ПроцессорКомпановки, Истина);

КонецПроцедуры
// ПолучитьДанныеНаОснованииСКД()

//****************************************************************************
// }}
//****************************************************************************

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

 

Например, получение данных сводится к трем простым действиям:

1. Написать запрос и настроить СКД в любой консоли, позволяющей это сделать.

2. Выгрузить настройки из консоли и загрузить в макет

3. Написать в необходимом месте код типа:


    ДеревоЗначений = Новый ДеревоЗначений;
   
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
   
СтруктураПараметров = Новый Структура("ДатаОтчета", НашаДата);
   
ПолучитьДанныеНаОснованииСКД(СхемаКомпоновкиДанных, ДеревоЗначенийСхемаКомпоновкиДанных.НастройкиПоУмолчанию, СтруктураПараметров);


Про запросы:

Далее собраны моменты, которые периодически пригождаются, и лично я все время забываю про них, так что для меня это будет как напоминалка. Cool

Нюансы

* Если при написании запроса конструктор пишет ошибки типа "Неоднозначное поле..." или подобное, и вы не можете понять, почему, не отчаивайтесь, если имя таблицы или имя вложенного запроса совпадает с именем объекта метаданных (любого), то возникают такие "глюки". Попробуйте изменить на имя, которое заведомо не может быть в метаданных.

 

Как вывести (рассчитать) процент для группировок?

Данный пример будет полезен, так как мне он кажется неочевидным, то есть понять, как это сделать правильно, можно не сразу.

Для большего понимания того, о чем пойдет речь, загрузите пример настроек СКД из этой статьи, имя файла Procent.xml (пример написан для УТ)

Итак, поставим задачу: Необходимо вывести процент наценки: ПроцентНаценки = 100*(СтоимостьПродажи - Себестоимость) / Себестоимость.

Для строк без иерерхии данная задача решается просто. Расчетом процента в запросе. Но вот вопрос: если у нас иерархическая структура отчета и вообще неизвестно, какая она будет... как считать проценты и выводить их нормально?

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

Первое, что необходимо, это написать запрос по регистрам для получения стоимости и себестоимости. Этот момент мы опустим, кстати, в моем запросе могут быть ошибки (писалось на скорую руку), но это и не столь важно в данном контексте, лишь бы что-то выводил отчет.

Переходим к настройкам самого СКД и процента:

1. Первое, что надо сделать, это зайти на закладку "Вычисляемые поля" и занести наше имя поля в колонку "Путь к данным" заголовок и будущий формат нашего поля

2. Занести это поле в ресурсы на закладке "Ресурсы", выражение исправить на что-то типа

ВЫБОР

       КОГДА СУММА(Себестоимость) = 0

             ТОГДА 0

       ИНАЧЕ 100*(СУММА(Стоимость)-СУММА(Себестоимость))/СУММА(Себестоимость)

КОНЕЦ

3. Ну и, конечно, добавить это поле в выбранные поля там, где это нужно, с чем, думаю, Вы очень просто справитесь.

&nb

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

-