Работа с запросами в 1С СКД. Язык выражений СКД и подмена запросов.
С помощью языка запросов СКД получает данные (например) с сервера СУБД и затем производится обработку (на сервере приложений) с помощью языка выражений СКД. Элементы этого языка могут использоваться:
- В схеме компоновки - для описания вычисляемых полей, выражений ресурсов, выражений связи наборов данных.
- В пользовательских полях.
- При вычислении параметров макетов.
Документацию по данному языку можно найти в справке к платформе (не синтаксис помощник) – в конфигураторе вызов через F1.
Самый интересный раздел, безусловно, это «Функции языка выражений системы компоновки данных», а также «Агрегатные функции». Использование этих функций мы рассматривали в нашем курсе по СКД. Важно знать об этом разделе хотя бы, потому что в языке выражений СКД есть функции, которых (к сожалению) пока нет в языке запросов 1С. Например, округление числа «Окр» или длина строки «ДлинаСтроки» и другие. Также язык выражений СКД позволяет использовать функции общих модулей.
На закуску интересная статья про функцию «Представление» и про то, какие ошибки возникают из-за разной реализации данной функции в языке запросов и в языке выражений СКД.
Обманываем СКД!
Иногда в отчетах на СКД возникает необходимость изменить текст запроса, заданный в наборе данных в зависимости от некоторых условий. При этом нужно сохранить все настройки параметров, отборов, условного оформления и т.п.
В этом случае можно воспользоваться возможность изменить текст запроса в схеме компоновки данных при программном формировании отчета в процедуре модуля объекта «ПриКомпоновкеРезультата».
Разберем на таком простом примере. Необходимо сделать отчет, который будет выводить все документы в базе. Допустим номер, дата, признак проведения. Плохой отчет, но хороший образец для демонстрации. Понятно, что включать в текст запроса набора данных все документы идея так себе. А если учесть, что документы могут добавляться или удаляться – вообще не реализуемая. Поэтому в наборе данных мы добавим запрос только по одному виду документа (будем считать, что этот документ будет в базе всегда). И добавим отбор по периоду (через отбор).
Далее подменяем в модуле отчета текст запроса:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); // Получаем схему компоновки данных
СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос = ""; // Очищаем запрос в наборе данных
ДокументыКонфигурации = Метаданные.Документы; // Получаем коллекцию метаданных документов
КоличествоДокументов = ДокументыКонфигурации.Количество(); // Определяем общее количество документов в конфигурации
Сч = 1;
ТекстЗапроса = "";
Для Каждого Док Из ДокументыКонфигурации Цикл
ТекстЗапроса = ТекстЗапроса + // Для каждого документа формируем текст запроса к его таблице
"ВЫБРАТЬ
| Док.Номер КАК Номер,
| Док.Дата КАК Дата,
| Док.Проведен КАК Проведен
|ИЗ
| Документ."+Док.Имя+" КАК Док"; // В текст запроса нам необходимо лишь подставить имя таблицы документа в дереве метаданных
Если Сч < КоличествоДокументов Тогда // Если документ не последний в коллекции - добавляем инструкцию "ОБЪЕДИНИТЬ ВСЕ" для
ТекстЗапроса = ТекстЗапроса + // объединения результатов запросов по документам в единый список
"
|ОБЪЕДИНИТЬ ВСЕ
|";
КонецЕсли;
Сч = Сч + 1;
КонецЦикла;
СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос = ТекстЗапроса;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,КомпоновщикНастроек.ПолучитьНастройки(),ДанныеРасшифровки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,,ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры
Через метаданные обходим все документы в конфигурации и через «ОБЪЕДИНИТЬ ВСЕ» соединяем запрос к каждому документу в один. Установим отбор по дате начала и посмотрим, что при этом происходит, остановившись в отладчике после получения макета компоновки, и изучим одно из его свойств:
Здесь мы видим реальный запрос, который СКД передает для выполнения платформе. С уже установленным отбором. Причем отбор установлен для каждого документа автоматически как нам и было нужно (по этой причине я выбрал выборку за период через отбор, а не через параметры). Об этом (как СКД меняет текст запроса) мы поговорим в следующем разделе.
Но это не все. Вам может показаться, что это какой-то искусственно придуманный пример и в реальной жизни не нужен. Давайте заглянем в отчет «ОстаткиИДоступностьТоваров» из УТ 11.4. В основном наборе отчета есть такой параметр:
Посмотрим теперь модуль отчета процедуру «ПриКомпоновкеРезультата»:
Здесь видно, что параметр, объявленный в наборе, заменяется с помощью вызова функции «ТекстЗапросаВесУпаковки» на запрос, получающий вес упаковки через единицу и номенклатуру из основного набора. Если посмотреть текст этой функции (запрос, возвращаемый функцией, занимает один экран), то становится понятно, почему этот код не был включен в основной набор – тогда текст запроса в основном наборе получился бы совершенно нечитаемым.
Серия статей по СКД
Предыдущая статься .., Следующая статья ..
Автор курсов образовательного проекта Profession Store. Павел Шемякин