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