Регистрируйтесь на бесплатный онлайн-митап по 1С EDT + GIT
запросы в 1С скд

Работа с запросами в 1С СКД. Язык выражений СКД и подмена запросов

Хотя эта статья называется «Работа с запросами в 1С СКД» нельзя не упомянуть про язык выражений СКД. Да – у системы компоновки данных (СКД) есть свой язык! Это не язык платформы 1С, это не язык запросов. Это еще один язык, который используется 1С в СКД для обработки полученного набора (ов) данных.
То есть с помощью языка запросов СКД получает данные (например) с сервера СУБД и затем производится обработку (на сервере приложений) с помощью языка выражений СКД. Элементы этого языка могут использоваться:
1
В схеме компоновки - для описания вычисляемых полей, выражений ресурсов, выражений связи наборов данных
2
В пользовательских полях
3
При вычислении параметров макетов
Документацию по данному языку можно найти в справке к платформе (не синтаксис помощник) – в конфигураторе вызов через F1.
Язык выражений СКД
Самый интересный раздел, безусловно, это «Функции языка выражений системы компоновки данных», а также «Агрегатные функции». Использование этих функций мы рассматривали в нашем курсе по 1С СКД. Важно знать об этом разделе хотя бы, потому что в языке выражений СКД есть функции, которых (к сожалению) пока нет в языке запросов 1С. Например, округление числа «Окр» или длина строки «ДлинаСтроки» и другие. Также язык выражений СКД позволяет использовать функции общих модулей.
На закуску интересная статья про функцию «Представление» и про то, какие ошибки возникают из-за разной реализации данной функции в языке запросов и в языке выражений системы компоновки данных (СКД).

Обманываем СКД!

Иногда в отчетах на СКД возникает необходимость изменить текст запроса, заданный в наборе данных в зависимости от некоторых условий. При этом нужно сохранить все настройки параметров, отборов, условного оформления и т.п.
В этом случае можно воспользоваться возможность изменить текст запроса в схеме компоновки данных при программном формировании отчета в процедуре модуля объекта «ПриКомпоновкеРезультата».
Разберем на таком простом примере. Необходимо сделать отчет, который будет выводить все документы в базе. Допустим номер, дата, признак проведения. Плохой отчет, но хороший образец для демонстрации. Понятно, что включать в текст запроса набора данных все документы идея так себе. А если учесть, что документы могут добавляться или удаляться – вообще не реализуемая. Поэтому в наборе данных мы добавим запрос только по одному виду документа (будем считать, что этот документ будет в базе всегда). И добавим отбор по периоду (через отбор).
Далее подменяем в модуле отчета текст запроса:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных"); // Получаем схему компоновки данных

СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос = ""; // Очищаем запрос в наборе данных

ДокументыКонфигурации = Метаданные.Документы; // Получаем коллекцию метаданных документов

КоличествоДокументов = ДокументыКонфигурации.Количество(); // Определяем общее количество документов в конфигурации

Сч = 1;
ТекстЗапроса = "";
Для Каждого Док Из ДокументыКонфигурации Цикл
ТекстЗапроса = ТекстЗапроса + // Для каждого документа формируем текст запроса к его таблице

"ВЫБРАТЬ
| Док.Номер КАК Номер,
| Док.Дата КАК Дата,
| Док.Проведен КАК Проведен
|ИЗ
| Документ."+Док.Имя+" КАК Док"; // В текст запроса нам необходимо лишь подставить имя таблицы документа в дереве метаданных

Если Сч < КоличествоДокументов Тогда // Если документ не последний в коллекции - добавляем инструкцию "ОБЪЕДИНИТЬ ВСЕ" для

ТекстЗапроса = ТекстЗапроса + // объединения результатов запросов по документам в единый список

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

На этом закончим разбор этой темы и перейдем к более интересной теме в которой раскроем особенности работы запросов в 1С СКД.