[ПОЛЕЗНОСТИ] по СКД и запросам (обновлено 14.11.11)
Вы задумываетесь, как использовать такой мощный механизм, как СКД, в своих разработках? Как удобней и быстрее получать необходимые данные? Трудности с написанием запросов? Тогда Вам нужно заглянуть в эту статью…
- Описание
- Подробнее
Описание
Данная статья задумывалась как небольшие полезности по СКД. Я надеюсь, что программисты, прочитав эту статью, не махнут рукой: «А, это фигня, все равно я делаю лучше (проще)». А задумались над возможностями и нашли способы реализации! Убедительная просьба, у кого есть возможность, прочитать хорошую литературу по СКД, например, Хрусталева Е.Ю. Разработка сложных отчетов в 1С Предприятии 8, а данная статья написана в большей мере, чтобы заинтересовать читателя, тут будут собираться наиболее неочевидные и интересные моменты работы с СКД.
Когда СКД только появилась, я задавал себе вопрос: «СКД для отчетов — замечательная вещь! Может быть, как-то можно ее использовать в работе и в других областях? Вместо запросов». С одной стороны, СКД — очень мощный инструмент, с другой стороны — как-то не совсем удобно или понятно его использовать (там же надо что-то куда-то вставлять, чтобы получить данные), а запрос написал и выгрузил в таблицу или дерево. Все разрешилось само собой (методом проб и ошибок, конечно), когда я стал решать реальные задачи. Сейчас я даже простые данные получаю с помощю СКД… спросите, почему? Есть одна, но очень серьезная причина:
Легкость написания, а главное, отладки запроса (в любой консоли). Те, кто сталкивался с запросами, знают, что некоторые запросы очень сложно отлаживать. Приходится использовать дополнительные обработки, чтобы «на лету» изменить параметры и посмотреть, что получится. К тому же в тех обработках, что я знаю, данные представляются как таблица значений, и понять, какое дерево значений получится в итоге, довольно сложно. Используя же СКД, мы получаем полное визульное представление о получаемых данных (за исключением иерархических данных, СКД при выгрузке, например, в дерево их просто выгрузит в развернутом виде, по каждому полю, но и это решаемо. Тут есть статьи, как это сделать, найду ссылку — добавлю сюда), а потом просто копируем настройки СКД в свою обработку.
Все же остается вопрос: как проще, быстрее и удобнее использовать СКД? Ведь тут, казалось бы, написание простых запросов имеет преимущество (хотя бы по времени написания)… Лично для меня многие вопросы закрылись после написания шаблонов. Надеюсь, что и для Вас они будут полезны.
//****************************************************************************
// ШАБЛОНЫ ДЛЯ ИСПОЛЬЗОВАНИЯ СКД
// {{
//****************************************************************************
// Заполняет переданный объект на основани СКД
//
// Параметры
//
// СКД – собствеено настройки СКД
//
// ОбъектДляЗагрузки – объект в который выгружаются данные, таблица значений, дерево значений, табличный документ
//
// ИсполняемыеНастройки – Пользовательские настройки СКД если не указаны будут использованы настроки СКД по умолчанию
//
// СтруктураПараметров — Структура – Передаваемые для СКД параметры
//
// краткий лекбез, поправлю позже
//
Процедура ПолучитьДанныеНаОснованииСКД(СКД, ОбъектДляЗагрузки, ИсполняемыеНастройки = Неопределено, СтруктураПараметров = Неопределено, РасшифровкаСКД = Неопределено, МакетКомпоновки = Неопределено, ВнешниеНаборыДанных = Неопределено) Экспорт
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Если ТипЗнч(ОбъектДляЗагрузки) = Тип(«ПолеТабличногоДокумента») ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип(«ТабличныйДокумент») Тогда
ТипГенератора = Тип(«ГенераторМакетаКомпоновкиДанных»);
Иначе
ТипГенератора = Тип(«ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений»);
КонецЕсли;
Если ИсполняемыеНастройки = Неопределено Тогда
ИсполняемыеНастройки = СКД.НастройкиПоУмолчанию;
КонецЕсли;
Если СтруктураПараметров <> Неопределено Тогда
КоллекцияЗначенийПараметров = ИсполняемыеНастройки.ПараметрыДанных.Элементы;
Для каждого Параметр Из СтруктураПараметров Цикл
НайденноеЗначениеПараметра = КоллекцияЗначенийПараметров.Найти(Параметр.Ключ);
Если НайденноеЗначениеПараметра <> Неопределено Тогда
НайденноеЗначениеПараметра.Использование = Истина;
НайденноеЗначениеПараметра.Значение = Параметр.Значение;
КонецЕсли;
КонецЦикла;
КонецЕсли;
МакетКомпоновкиСКД = КомпоновщикМакета.Выполнить(СКД, ИсполняемыеНастройки, РасшифровкаСКД, МакетКомпоновки, ТипГенератора);
ПроцессорКомпановки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпановки.Инициализировать(МакетКомпоновкиСКД, ВнешниеНаборыДанных, РасшифровкаСКД);
Если ТипЗнч(ОбъектДляЗагрузки) = Тип(«ПолеТабличногоДокумента») ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип(«ТабличныйДокумент») Тогда
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ОбъектДляЗагрузки);
Иначе
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ОбъектДляЗагрузки);
КонецЕсли;
ПроцессорВывода.ОтображатьПроцентВывода = Истина;
ПроцессорВывода.Вывести(ПроцессорКомпановки, Истина);
КонецПроцедуры // ПолучитьДанныеНаОснованииСКД()
//****************************************************************************
// }}
//****************************************************************************
вставляем данный код в модуль своей обработки, отчета или даже конфигурации и используем, где потребуется.
Например, получение данных сводится к трем простым действиям:
1. Написать запрос и настроить СКД в любой консоли, позволяющей это сделать.
2. Выгрузить настройки из консоли и загрузить в макет
3. Написать в необходимом месте код типа:
ДеревоЗначений = Новый ДеревоЗначений;
СхемаКомпоновкиДанных = ПолучитьМакет(«ОсновнаяСхемаКомпоновкиДанных»);
СтруктураПараметров = Новый Структура(«ДатаОтчета», НашаДата);
ПолучитьДанныеНаОснованииСКД(СхемаКомпоновкиДанных, ДеревоЗначений, СхемаКомпоновкиДанных.НастройкиПоУмолчанию, СтруктураПараметров);
Про запросы:
Далее собраны моменты, которые периодически пригождаются, и лично я все время забываю про них, так что для меня это будет как напоминалка. 
Нюансы
* Если при написании запроса конструктор пишет ошибки типа «Неоднозначное поле…» или подобное, и вы не можете понять, почему, не отчаивайтесь, если имя таблицы или имя вложенного запроса совпадает с именем объекта метаданных (любого), то возникают такие «глюки». Попробуйте изменить на имя, которое заведомо не может быть в метаданных.
Как вывести (рассчитать) процент для группировок?
Данный пример будет полезен, так как мне он кажется неочевидным, то есть понять, как это сделать правильно, можно не сразу.
Для большего понимания того, о чем пойдет речь, загрузите пример настроек СКД из этой статьи, имя файла Procent.xml (пример написан для УТ)
Итак, поставим задачу: Необходимо вывести процент наценки: ПроцентНаценки = 100*(СтоимостьПродажи — Себестоимость) / Себестоимость.
Для строк без иерерхии данная задача решается просто. Расчетом процента в запросе. Но вот вопрос: если у нас иерархическая структура отчета и вообще неизвестно, какая она будет… как считать проценты и выводить их нормально?
Признаюсь честно, доходил до конечного результата я долго, к тому же недавно опять возникла необходимость это сделать и, оказывается, я забыл, как же правильно делать… пришлось лезть в старую разработку, а делается все очень просто:
Первое, что необходимо, это написать запрос по регистрам для получения стоимости и себестоимости. Этот момент мы опустим, кстати, в моем запросе могут быть ошибки (писалось на скорую руку), но это и не столь важно в данном контексте, лишь бы что-то выводил отчет.
Переходим к настройкам самого СКД и процента:
1. Первое, что надо сделать, это зайти на закладку «Вычисляемые поля» и занести наше имя поля в колонку «Путь к данным» заголовок и будущий формат нашего поля

2. Занести это поле в ресурсы на закладке «Ресурсы», выражение исправить на что-то типа
ВЫБОР
КОГДА СУММА(Себестоимость) = 0
ТОГДА 0
ИНАЧЕ 100*(СУММА(Стоимость)-СУММА(Себестоимость))/СУММА(Себестоимость)
КОНЕЦ

3. Ну и, конечно, добавить это поле в выбранные поля там, где это нужно, с чем, думаю, Вы очень просто справитесь.
Как выводить ресурсы (или как вывести начальные и конечные остатки и данные по произвольным периодам)?
Я наткнулся сразу на несколько постов на форуме где задают примерно один и тот же вопрос. Так как не хотелось всем отвечать решил быстренько наваять пример с описанием в этом посте.
Итак задача: необходимо вывести отчет примерно такой формы

Можно скачать пример в этой статье, называется: «Пример вывода ресурсов в СКД».
Итак написать сам запрос не составит особых трудов, и он зависит от конкретной задачи.
Далее выбираем ресурсы:

Вся остальная настройка, занимающая совсем немного времени, показана на следующих 2х скриншотах.


Если возникнут те или иные вопросы по выводу данных в СКД, задавайте вопросы, постараюсь ответить, и самые интересные задачи попадут в этот пост.
Удачи!
Статья будет дополняться…

