Использование отборов в СКД
Расширение языка запросов для системы компоновки данных
Расширение языка запросов для системы компоновки данных осуществляется при помощи специальных синтаксических инструкций, заключаемых в фигурные скобки и помещаемых непосредственно в текст запроса.
Синтаксические элементы расширения языка запросов системы компоновки данных
ВЫБРАТЬ
В этом предложении описываются поля, которые пользователь сможет выбирать для вывода. После данного ключевого слова через запятую перечисляются псевдонимы полей из основного списка выборки запроса, которые будут доступными для настройки.
После псевдонима поля может находиться комбинация символов «.*», что обозначает возможность использования дочерних полей от данного поля.
Например, запись Номенклатура.* обозначает возможность использования дочерних полей поля «Номенклатура» (например, поля «Номенклатура.Код»). Элемент ВЫБРАТЬ может присутствовать только в первом запросе объединения.
Описываются поля, на которые пользователь сможет накладывать отбор. В данном предложении используются поля таблиц. Использование псевдонимов полей списка выборки недопустимо. Каждая часть объединения может содержать собственный элемент ГДЕ.
Нехитрый пример
Необходимо получить продажи за период + вывести всю номенклатуру, независимо от того были ли продажи или нет. То есть, необходимо выбрать данные из таблицы оборотов регистра Продажи, данные из справочника номенклатура. Опустим вопрос зачем нам нужна вся номенклатура.
Для решения задачи можно составить запрос соединяющий левым соединением номенклатуру и таблицу оборотов Продажи, в результате, для номенклатуры, которая не продавалась в выбранном периоде мы получим значения полей Контрагент, Договор, Количество, Сумма = Null. Такой запрос:
Контрагент | Договор | Номенклатура | Количество | Сумма |
null | null | _Тест1 | null | null |
ООО «Рога и копыта» | Договор1 | Тапочки | 10 | 1200 |
ОАО «Газпром» | Клевый договор | Сапоги | 5 | 13000 |
null | null | Галоши | null | null |
null | null | Сланцы | null | null |
— в данном примере не было продаж номенклатуры: «Галоши» и «Сланцы»
И все бы ничего, если мы сгруппируем выборку по контрагенту то вся не продаваемая номенклатура попадет в отдельную группировку, где Контрагент = Null, но клиент хочет иметь в отчете произвольный отбор по полю контрагент(естественно имеется ввиду контрагент из регистра Продажи). Как быть? Ведь по сути нам нужно фильтровать только таблицу Продажи. Если мы используем автозаполнение в конструкторе СКД, то в доступные поля отбора попадет поле Контрагент, все вроде бы хорошо, но при исполнении отчета с отбором по контрагенту мы потеряем все записи из соединения с номенклатурой. Например, установим отбор: Контрагент = ООО «Рога и копыта». Результат будет выглядеть так:
Контрагент | Договор | Номенклатура | Количество | Сумма |
ООО «Рога и копыта» | Договор1 | Тапочки | 10 | 1200 |
— совсем не то что нам нужно, правда?
Для решения задачи можно конечно добавить параметр в запрос, например в параметры виртуальной таблицы ПродажиОбороты, но при этом теряется гибкость настройки вида сравнения.
Решение есть: для этого в конструкторе запросов на вкладке Компоновка данных => Таблицы добавим поле-условие в условия виртуальной таблицы ПродажиОбороты и сменим ему псевдоним на КонтрагентОтбор
Для того чтобы не путать пользователя с полями отбора, отключим поле-условие Контрагент и сменим заголовок для поля КонтрагентОтбор
В результате выполнения данной схемы с включенным отбором по полю контрагент результирующий запрос примет вид:
И соответственно результат:
Контрагент | Договор | Номенклатура | Количество | Сумма |
null | null | _Тест1 | null | null |
ООО «Рога и копыта» | Договор1 | Тапочки | 10 | 1200 |
null | null | Сапоги | null | null |
null | null | Галоши | null | null |
null | null | Сланцы | null | null |
К публикации прикреплена схема XML-схема отчета, использовавшегося в публикации. Схему создавал в Комплексной автоматизации, но думаю, все будет прекрасно работать и в УПП и в УТ 10
Подведение итогов
Данный пример показывает каким образом создать свои настройки отборов в СКД и отключить автосоздаваемые, если вы конструируете схему с включенным флагом Автозаполнение.
Разбираемся с параметрами редактирования СКД
Вступление
В конструкторе СКД на некоторых вкладках есть колонка Параметры редактирования (или Параметры ввода, что то же самое по сути).
Настройка этого значения выполняется через специальное окно с одноименным названием.
Некоторые элементы списка этих параметров не имеют конструкторов, а также имеют неочевидные названия.
Настройка этих параметров может вызывать трудности.
Достаточно подробного описания данного механизма с доступными примерами мне найти не удалось, поэтому разбирался самостояетельно.
Самые простые параметры редактирования
Наиболее простыми для использования являются следующие параметры: Формат редактирования, Быстрый выбор, Выбор групп и элементов. С ними все понятно, поэтому их пропустим.
Связи параметров выбора
Настраиваются через специальное окно Редактирование связей параметров выбора.
Рассмотрим на примере как заполнять поля этой формы.
Пример 1
Тогда достаточно в поле Параметр выбора указать имя реквизита из справочника Договоры контрагентов, в нашем случае это Владелец, поэтому запишем: Отбор.Владелец.
Зачем добавлять слово Отбор, опишу ниже.
Теперь, если у параметра Контрагент стоит флаг Использование и контрагент выбран, то при выборе договора, будет накладываться отбор по владельцу.
Если же Контрагент не выбран или флаг у контрагента не установлен, то при выборе договора будут отображаться все договоры.
Поле Изменение значения влияет на то, очищать ли договор, если пользователь выбрал другого контрагента или не очищать.
Параметры выбора
Настраиваются через специальное окно Редактирование параметров выбора.
Рассмотрим на примере как заполнять поля этой формы.
Пример 2
Поля Контрагент и Договор из первого примера.
Мы хотим, чтобы пользователь мог выбрать только договор с видом С покупателем или Прочее и не помеченный на удаление.
Добавляем два параметра:
1. Параметр выбора = Отбор.ПометкаУдаления; Значение = ЛОЖЬ
2. Параметр выбора = Отбор.ВидДоговора; Значение = список из двух элементов : С покупателем, Прочее
Эти два параметра будут устанавливаться всегда независимо от выбранности/невыбранности параметра Контрагент.
Зачем нужно слово Отбор?
Почему в поле Параметр выбора необходимо использовать приставку Отбор? Какие еще параметры можно указывать и на что это влияет?
Это один из ключевых вопросов данной статьи, который и стал поводом к ее написанию.
Для ответа на этот вопрос предположим, что у нас есть независимая обработка без СКД с реквизитами Контрагент и Договор.
Какой код нам потребовалось бы написать, чтобы при подборе в поле Договор на нашей обработке устанавливались нужные отборы и передавались параметры?
Один из вариантов этого кода выглядит следующим образом.
Чтобы получше разобраться поэкспериментируем
Пример 3
Добавим по два параметра в Параметры выбора и в Связи параметров выбора.
Поставим точку останова в форме выбора при создании на сервере
Видим, что параметры, переданные без точек пришли как отдельные, а параметры, имеющие точки пришли в виде структуры.
Связь по типу
В настройке данного параметра сбивает с толку наличие поля Элемент связи с типом число.
Чтобы понять как его настраивать разберем два примера.
Пример 4
Создадим в СКД параметр Счет.
И еще три параметра Субконто1, Субконто2, Субконто3.
Мы хотим, чтобы если выбран Счет, то во параметре СубконтоN автоматически устанавливался отбор со значениями соответствующего субконто.
В этом случае для параметра Субконто1 настраиваем Связь по типу:
Поле = Счет (ПараметрыДанных.Счет), Элемент связи = 1 (номер субконто)
Для остальных двух параметров аналогично, только Элемент связи будет 2 и 3.
Теперь при выбранном параметре Счет, в полях СубконтоN будут доступны только значения, соответствующие типу субконто
Пример 5
Создадим в СКД параметры Вид субконто и Субконто.
Мы хотим, чтобы при выборе вида, были доступны только значения соответствующие виду субконто.
В этом случае для параметра Субконто1 настраиваем Связь по типу:
Поле = ВидСубконто (ПараметрыДанных.ВидСубконто), Элемент связи = 0 (не имеет значение в данном случае)
Заключение
Данный механизм в СКД аналогичен тому, который позволяет настраивать параметры реквизитов в справочниках, документах и т.д.
Но такие связи приходится настраивать довольно редко, и часто в таких случаях проще решить задачу с помощью кода, чем разбираться как это все настраивается.
Думаю, что данное описание поможет разобраться в этом механизме и начать его применять.
Теперь, когда я выбираю одного Контрагента, то выбирается список его договоров, но когда я открываю 2-х и более Контрагентов, то вываливается весь список договоров, без какого-либо отбора.
Вопрос: Как настроить связь, что бы при выборе нескольких Контрагентов выдавался список Договоров только этих Контрагентов?
(2) Rothschild, Подправил описание. Формы управляемые.
(7) Восьмой, зачем такие сложности?
В КомпоновщикНастроекПользовательскиеНастройки формы СКД событий предостаточно, или они с отборами не дружат?
(13) ikar-nikolay, я имел ввиду вот с этим шаманство:
Для выполнения пункта 1 написал процедуру
ЗЫ
можно разве что
попытаться сделать предлагаемый механизм чуток универсальней.
Я пошутил выше по поводу сохранения значений в параметры. )))
Сделал универсально, но не максимально универсально. если найдется деятель, который форму созданную физически создаст кодами конфигуратора и закрепит обработчики событий, то это будет максимальная универсация.
Форма выбора открывается, когда и у Подчиненного и у Владельца указан тип значения (ВСписке).
Для реализации нам требуется:
1) создать произвольную форму в СКД с названием «ФормаВыбораПодчинения»
и следующими реквизитами (соответственно реквизиты ВладелецВыбор и ПодчиненныйВыбор должны иметь правильную ссылку)
В коде формы необходимо подставить название справочника подчиненных элементов в переменную строкаСпрПодчинененныхЭлементов (например «Договоры»)
Все остальное без изменений. В коде дал подробные разъяснения что и зачем.
2) В КомпоновщикНастроекПользовательскиеНастройки (см. пост выше) на ПередНачаломИзменения вешаем приведенный ниже обработчик.
Все, что нам тут необходимо ввести, это строковое название Реквизита владельца и подчиненного в переменные НазваниеРеквизитаВладельца, НазваниеРеквизитаПодчиненного.
В созданной форме выбора можно будет добавить список Владельцев, по которым необходимо делать отборы и после завершения подбора, выбранные значения Владельцев автоматически попадут в настройки.
Работа с запросами в 1С СКД. Особенности работы запросов в СКД. Часть 3
Добавление отбора ко всем таблицам пакета
В предыдущем разделе, посвященном расширению языка запросов 1С для СКД, мы разбирали пример, в котором нам нужно было получить список расходных накладных и связанных по номенклатуре приходных накладных.
Я обещал разобрать, почему при отборе по контрагенту наш отчет работает неправильно. Посмотрим на примере другого отчета, в котором нам нужно выбрать данные из расходных накладных и связанные с номенклатурой данные по ВСЕМ заявкам.
Вот такой исходный запрос будет в нашем отчете:
Если в отчете не установлен отбор по заказу покупателя, то выполняемый запрос получается верный:
Если же нам нужно установить отбор по заказу расходной накладной (для этого в последнем запросе пакета мы с помощью расширения языка запросов указали, что пользователь может устанавливать отбор по заказу накладной), то запрос получается неверный:
Здесь мы видим, что в результате замены текста запроса система компоновки данных добавила в параметры виртуальной таблицы отбор по заказу покупателя. Что не соответствует логике работы нашего отчета. Мы уже рассматривали один из способов как можно исправить данную ошибку – отключаем опцию «Автозаполнение», настраиваем с помощью расширения языка запросов поля для условий и место применения этих условий, настраиваем также список выбираемых полей (так как автозаполнение мы отключили).
Можно решить эту проблему проще. Для этого мы установим алиас для поля «ЗаказПокупателя» в секции «ГДЕ», а также установим ограничение использования в условии для поля «ЗаказПокупателя»:
Как видно на картинке, при установке алиаса, в поля набора добавляется новое поле с именем равным алиасу. Это поле может использоваться только в условии. Если не установить ограничения на использование в условии для поля «ЗаказПокупателя», то пользователь сможет установить отбор по этому полю, и отчет снова будет формироваться неверно.
В таком подходе есть один минус – если выключить автозаполнение и снова его включить, установленные вами ограничения не сохранятся. Поэтому, какой вариант решения использовать – выбирать вам.
Добавление отбора в объединение
Кроме добавления отбора во все запросы пакета СКД добавляет отбор также в части запроса выполненного с помощью оператора «ОБЪЕДИНИТЬ». Рассмотрим такой исходный запрос:
Если установить отбор по номенклатуре, то получим такой запрос:
Если установить отбор по полю расход, то получим вот такой запрос:
Такая замена производится при включенном автозаполнении.
При включенном автозаполнении и при использовании отбора по реквизиту одного из полей производится такая замена:
Здесь видно, чтоб отбор был добавлен только в ту часть запроса, в которой склад не NULL. Замена работает согласно документации 1С:
При отключенном автозаполнении в таком исходном запросе и при установленных отборах:
Получим такой выполняемый запрос:
Такое поведение платформы работает, начиная с релиза 1С 8.3.14. До этого релиза даже при отключенной опции «Автозаполнение», отбор по полю со значением NULL (склад в нашем случае) добавлялся и в первую часть объединения (что не всегда бывает необходимо и при отключенной опции ожидалось, что отбор будет срабатывать как указано).
При использовании связанных наборов имеется также особенность работы СКД при установке отбора. В документации 1С написано:
«При использовании в схеме нескольких наборов данных, если в главном отборе накладывается условие на поле некоторого дочернего набора данных, то в сгенерированном макете компоновки данных дочерний набор данных будет связан с родительским набором данных с типом связи «Внутренняя»».
Здесь важно понимать, что:
Посмотрим на примере такого отчета:
Набор главный (Заказы):
Дочерний наборы данных (Остатки):
В анализе данной ситуации нам может помочь только консоль компоновки данных от 1С (о консолях в следующем разделе). Проанализируем в консоли выполняемые запросы и связь наборов без установленного отбора:
Здесь мы получаем все позиции из заказов. Сами запросы нам не интересны там ничего необычного. Интересно как установлена связь наборов:
Теперь установим отбор по полю «КоличествоОстаток» набора «Остатки»:
Если не знать особенность работы СКД, мы будем ожидать, что из главного набора будут выбираться все записи, затем к дочернему набору применится отбор, и наборы будут связаны между собой левым соединением. В итоге в отчет должны попасть все строки из заказов, в колонке остаток остаться только числа больше 30. Но мы получаем другой результат:
В отчет попали только заказы, по которым есть соответствующий остаток. Посмотрим снова в консоли связь наборов:
Здесь мы видим, что связь наборов, которую выполняет сама СКД, стала внутренней. Причем как я уже писал выше такое поведение получается только при установке отбора по полям дочернего набора, которых нет в главном наборе. Если установить отбор по полю «Номенклатура» соединение наборов останется левым.
Глобальный отбор и отбор на группировках
До сих пор мы рассматривали так называемый глобальный отбор – отбор, который устанавливается на уровне всего отчета. Такой отбор обычно СКД переносит в текст запроса. Исключением может быть, например, отбор по вычисляемому полю. Кроме глобального отбора в системе компоновки данных имеется возможность накладывать отборы на уровне группировки. Такие отборы в 1С СКД обрабатывает самостоятельно и соответственно не переносит в текст запроса.
В платформе 1С до релиза 8.3.14 в запросе, который мы уже рассматривали, но с другой структурой отбора данный отбор не переносится в текст запроса для платформы (и соответственно выполняется СКД после получения результата запроса):
Важное отличие здесь в том, что отборы включены в группу.
Видно, что в итоговом запросе условия не включены:
При этом если условия находятся вне группы, то они включаются в текст запроса:
В релизе 1С 8.3.14 условия включаются в текст запроса платформы независимо от того расположены они в группе или нет.