запросы в 1С СКД

Работа с запросами в 1С СКД. Особенности работы запросов в СКД. Часть 3

Добавление отбора ко всем таблицам пакета

В предыдущем разделе, посвященном расширению языка запросов 1С для СКД, мы разбирали пример, в котором нам нужно было получить список расходных накладных и связанных по номенклатуре приходных накладных.
Я обещал разобрать, почему при отборе по контрагенту наш отчет работает неправильно. Посмотрим на примере другого отчета, в котором нам нужно выбрать данные из расходных накладных и связанные с номенклатурой данные по ВСЕМ заявкам. Вот такой исходный запрос будет в нашем отчете:
1С СКД
Если в отчете не установлен отбор по заказу покупателя, то выполняемый запрос получается верный:
1С СКД
Если же нам нужно установить отбор по заказу расходной накладной (для этого в последнем запросе пакета мы с помощью расширения языка запросов указали, что пользователь может устанавливать отбор по заказу накладной), то запрос получается неверный:
1С СКД
Здесь мы видим, что в результате замены текста запроса система компоновки данных добавила в параметры виртуальной таблицы отбор по заказу покупателя. Что не соответствует логике работы нашего отчета. Мы уже рассматривали один из способов как можно исправить данную ошибку – отключаем опцию «Автозаполнение», настраиваем с помощью расширения языка запросов поля для условий и место применения этих условий, настраиваем также список выбираемых полей (так как автозаполнение мы отключили). Можно решить эту проблему проще. Для этого мы установим алиас для поля «ЗаказПокупателя» в секции «ГДЕ», а также установим ограничение использования в условии для поля «ЗаказПокупателя»:
1С СКД
Как видно на картинке, при установке алиаса, в поля набора добавляется новое поле с именем равным алиасу. Это поле может использоваться только в условии. Если не установить ограничения на использование в условии для поля «ЗаказПокупателя», то пользователь сможет установить отбор по этому полю, и отчет снова будет формироваться неверно. В таком подходе есть один минус – если выключить автозаполнение и снова его включить, установленные вами ограничения не сохранятся. Поэтому, какой вариант решения использовать – выбирать вам.

Добавление отбора в объединение

Кроме добавления отбора во все запросы пакета системы компоновки данных (СКД) добавляет отбор также в части запроса выполненного с помощью оператора «ОБЪЕДИНИТЬ». Рассмотрим такой исходный запрос:
1С СКД
Если установить отбор по номенклатуре, то получим такой запрос:
Если установить отбор по полю расход, то получим вот такой запрос:
Такая замена производится при включенном автозаполнении. При включенном автозаполнении и при использовании отбора по реквизиту одного из полей производится такая замена:
Здесь видно, чтоб отбор был добавлен только в ту часть запроса, в которой склад не NULL. Замена работает согласно документации 1С:
При отключенном автозаполнении в таком исходном запросе и при установленных отборах:
Получим такой выполняемый запрос:
Такое поведение платформы работает, начиная с релиза 1С 8.3.14. До этого релиза даже при отключенной опции «Автозаполнение», отбор по полю со значением NULL (склад в нашем случае) добавлялся и в первую часть объединения (что не всегда бывает необходимо и при отключенной опции ожидалось, что отбор будет срабатывать как указано).

Отборы в наборах

При использовании связанных наборов имеется также особенность работы СКД при установке отбора. В документации 1С написано:
"При использовании в схеме нескольких наборов данных, если в главном отборе накладывается условие на поле некоторого дочернего набора данных, то в сгенерированном макете компоновки данных дочерний набор данных будет связан с родительским набором данных с типом связи "Внутренняя".
Здесь важно понимать, что:
1
По умолчанию в 1С СКД есть главный набор (источник связи) и подчиненный (приемник связи или дочерний набор) и связаны они левым соединением
2
Поле дочернего набора в этом случае (при установке отбора) не просто «некоторое», а отсутствующее в главном наборе. Только в этом случае связь из левого превращается во внутреннюю. Причем связываются наборы не на уровне запросов, а самой системой компоновки данных.
Посмотрим на примере такого отчета:

Посмотрим на примере такого отчета:

Набор главный (Заказы):
Дочерний наборы данных (Остатки):
Связь наборов:
В анализе данной ситуации нам может помочь только консоль компоновки данных от 1С (о консолях в следующем разделе). Проанализируем в консоли выполняемые запросы и связь наборов без установленного отбора:
Здесь мы получаем все позиции из заказов. Сами запросы нам не интересны там ничего необычного. Интересно как установлена связь наборов:
Теперь установим отбор по полю «КоличествоОстаток» набора «Остатки»:
Если не знать особенность работы системы компоновки данных (СКД), мы будем ожидать, что из главного набора будут выбираться все записи, затем к дочернему набору применится отбор, и наборы будут связаны между собой левым соединением. В итоге в отчет должны попасть все строки из заказов, в колонке остаток остаться только числа больше 30. Но мы получаем другой результат:
В отчет попали только заказы, по которым есть соответствующий остаток. Посмотрим снова в консоли связь наборов:
Здесь мы видим, что связь наборов, которую выполняет сама СКД, стала внутренней. Причем как я уже писал выше такое поведение получается только при установке отбора по полям дочернего набора, которых нет в главном наборе. Если установить отбор по полю «Номенклатура» соединение наборов останется левым.

Глобальный отбор и отбор на группировках

До сих пор мы рассматривали так называемый глобальный отбор – отбор, который устанавливается на уровне всего отчета. Такой отбор обычно система компоновки данных (СКД) переносит в текст запроса. Исключением может быть, например, отбор по вычисляемому полю. Кроме глобального отбора в системе компоновки данных имеется возможность накладывать отборы на уровне группировки. Такие отборы в 1С СКД обрабатывает самостоятельно и соответственно не переносит в текст запроса.
В платформе 1С до релиза 8.3.14 в запросе, который мы уже рассматривали, но с другой структурой отбора данный отбор не переносится в текст запроса для платформы (и соответственно выполняется СКД после получения результата запроса):
Важное отличие здесь в том, что отборы включены в группу.
Видно, что в итоговом запросе условия не включены:
При этом если условия находятся вне группы, то они включаются в текст запроса:
В релизе 1С 8.3.14 условия включаются в текст запроса платформы независимо от того расположены они в группе или нет.

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