Нюансы преобразования запроса СКД
Попытаюсь изложить некоторые встреченные нюансы парсинга текста запроса в СКД — т.е. каким образом преобразуется в приведенных примерах текст запроса, написанный в окне Запроса закладки Наборы данных в СКД — далее просто ТЗ СКД. Для примеров используется конфигурация Управление торговлей, редакция 11.3.
Известно, что СКД создана в том числе и для минимизации действий кодировщика и проделывает за него некоторые скрытые действия, которые не всегда оказываются очевидными.
1. Поведение соединений к основной таблице
Создаю новый внешний отчет, для него создаю основную схему компоновки данных. Пишу в ней такой ТЗ СКД
Фигурные скобки в ТЗ СКД означают для соединений и условий то, что данная часть ТЗ СКД будет включаться в результирующий текст запроса только при определенных пользовательских настройках.
Для того, чтобы увидеть результат преобразования в модуле отчета создаю следующую процедуру:
Вывожу параметр ДатаОтчета на форму, создаю простую настройку с одной группировкой "Номенклатура" без каких либо полей и запускаю формирование отчета — вначале с отключенной галочкой отбора по параметру. В окне сообщений получаю результирующий запрос, который будет использоваться системой для получения необходимых для отчета данных:
Видно, что внутреннее соединение из ТЗ СКД отсутствует, т.к. ни в фильтре, ни в полях настройки нигде эта таблица не требуется.
Если установить фильтр по дата, то получаем результирующий запрос
Внутреннее соединение появилось. То же самое произойдет если не включать фильтр по дате, а попробовать в настройках вывести поле Дата:
Теперь дописываю ТЗ СКД, включая еще одно соединение — со справочником Партнеры:
Текст запроса СКД
Формирую с условием по партнеру, но без условия по дате и без полей-группировок по дате в запросе. В результирующем запросе получаю не совсем то, что ожидал:
Для избежания подобного результата нужно либо убирать фигурные скобки в первом соединении — тогда оно будет включатся в результирующий запрос всегда, либо оба соединения заключать в общие фигурные скобки — тогда оба соединения будут включены в текст запроса в случаях, когда в пользовательских настройках требуется либо получение даты либо получение партнера. Четкой рекомендации для подобных случаев дать не могу, кроме как просматривать результирующий текст запроса при отладке отчета при разных вариантах настроек.
2. Неочевидное включение фильтров
В приведенном примере требуется показать номенклатуру из документов Реализация по определенному складу и вывести дополнительно остаток по номенклатуре по всем складам суммарно. Пишу следующий ТЗ СКД:
Текст запроса СКД
формирую отчет с фильтром по складу и получаю результирующий запрос в таком виде:
Здесь видно, что система сама включила фильтр по складу во виртуальную таблицу остатков. Не очень ожидаемое действие. Приходится для избежания этого назначать другое имя переменной для фильтра по складу документа:
Тогда отбор в виртуальной таблице уже отсутствует.
3. Управление формированием временных таблиц
Случается, что для организации фильтра удобно использование временных таблиц. Опишу, каким образом удобно включать/отключать формирование временной таблицы только тогда, когда она требуется по текущим настройкам пользователя. ТЗ СКД:
Выбрать Номенклатура
Поместить ТаблицаОстаткиНоменклатуры
из РегистрНакопления.ТоварыНаСкладах.Остатки(,
<Склад.* Как СкладОстатков,Номенклатура.* Как Номенклатура>
) КАК ТоварыНаСкладахОстатки
где ТоварыНаСкладахОстатки.ВНаличииОстаток>0
индексировать по Номенклатура
;
ВЫБРАТЬ
РеализацияТоваровУслугТовары.Ссылка,
ДокРеализация.Дата,
РеализацияТоваровУслугТовары.Номенклатура,
РеализацияТоваровУслугТовары.КоличествоУпаковок,
РеализацияТоваровУслугТовары.Цена,
РеализацияТоваровУслугТовары.Сумма
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
<
внутреннее соединение Документ.РеализацияТоваровУслуг ДокРеализация по ДокРеализация.Ссылка=РеализацияТоваровУслугТовары.Ссылка
>
<где
//РеализацияТоваровУслугТовары.Номенклатура.* Как Номенклатура,
ДокРеализация.Дата = &ДатаОтчета,
&ВключенаВременнаяТаблицаТаблицаОстаткиНоменклатуры и РеализацияТоваровУслугТовары.Номенклатура в (Выбрать Номенклатура из ТаблицаОстаткиНоменклатуры)
>
Источник
Новые функции языка запросов и системы компоновки данных
Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.
Планируется в версии 8.3.20Пробовать
Когда мы пишем запросы и создаем отчёты, нередко бывает нужно не просто показать данные в том виде, в котором они лежат в БД, а произвести над ними какие-то операции. Например, посчитать разницу между двумя датами или округлить число до нужной разрядности. Хорошо, если нужная функция есть в языке запросов (или в языке СКД) — тогда мы можем сделать с данными то, что хотим, на уровне запроса / СКД, а потом просто отобразить результат. Если же нужная функция в языке запросов не реализована – приходится делать постобработку запроса в языке 1С, проходясь в цикле по результатам запроса и выполняя нужные операции. Что приводит к разрастанию кода конфигурации и может снизить производительность.
К нам довольно часто обращаются разработчики с пожеланиями о добавлении дополнительных функций в язык запросов и язык СКД. Мы внимательно проанализировали пожелания и выделили список наиболее востребованных функций, которые планируем реализовать в версии 8.3.20.
Язык запросов
В язык запросов добавляются функции:
Строка(String) – преобразует значение в примитивного типа в строку с учетом национальных установок.
Тригонометрические функции Sin, Cos, Tan, ASin, ACos, ATan (все вычисления производятся в радианах)
Exp — вычисляет результат возведения основания натурального логарифма (числа e) в степень
Log — вычисляет натуральный логарифм числа.
Log10 — вычисляет десятичный логарифм числа.
Pow — вычисляет возведение в степень.
Sqrt – вычисляет квадратный корень.
Окр(Round) — округляет исходное число до нужной разрядности
Цел(Int) — вычисляет целую часть переданного числа, полностью отсекая дробную часть.
ДлинаСтроки(StringLength) – вычисляет длину строки.
СокрЛ(TrimL) – отбрасывает незначащие пробелы слева.
СокрП(TrimR) – отбрасывает незначащие пробелы справа.
СокрЛП(TrimAll) – отбрасывает незначащие пробелы слева и справа.
Лев(Left) – получает первые слева символы строки.
Прав(Right) – получает первые справа символы строки.
СтрНайти(StrFind) – находит первую позицию подстроки в строке (без учета регистра).
ВРег(Upper) – преобразует все символы строки в верхний регистр.
НРег(Lower) – преобразует все символы строки в нижний регистр.
СтрЗаменить(StrReplace) – заменяет все вхождения подстроки на другую подстроку (без учета регистра).
РазмерХранимыхДанных(StoredDataSize) – возвращает размер данных в байтах, которые занимают данные параметра.
Система компоновки данных
В язык выражений системы компоновки данных добавлены новые функции:
СокрЛ(TrimL) – отбросить незначащие пробелы слева.
СокрП(TrimR) – отбросить незначащие пробелы справа.
СокрЛП(TrimAll) – отбросить незначащие пробелы слева и справа.
Лев(Left) – получить первые слева символы строки.
Прав(Right) – получить первые справа символы строки.
СтрНайти(StrFind) – найти подстроку в строке (без учета регистра).
ВРег(Upper) – преобразует все символы строки в верхний регистр.
НРег(Lower) – преобразует все символы строки в нижний регистр.
СтрЗаменить(StrReplace) – заменяет все вхождения подстроки на другую подстроку (без учета регистра).
НСтр(NStr) – получает строку на языке пользователя (аналогично тому, как работает метод НСтр глобального контекста). Параметры:
Источник
Один и тот же запрос возвращает разные данные в консольке и СКД
В 1С-Рарус пытаюсь вытащить контрагента-поставщика из последней партии для отчета по остаткам, т.е. чтобы отчет по остаткам показывал мне контрагента из последнего поступления. Необходимо видеть прошлого поставщика для номенклатуры, которая двигалась через регистраторы типа «инвентаризация» или «ввод остатков».
Собственно сам пациент:
Выполняю запрос через консоль запросов — всё отлично, у каждой номенклатуры есть контрагент.
Засовываю запрос в СКД — контрагент отображается, но не для всех.
СКД в зависимости от настроек может модифицировать исходный текст запроса. Наверняка в настройках схемы на вкладке «Наборы данных» включено «Автозаполнение». В этом случае конструктор автоматически заполнит поля наборов и параметры. Некоторые автопараметры имеют определенные наименования. Как например, «НачалоПериода» и «КонецПериода» для виртуальных таблиц оборотов и остатков и оборотов. И если в запросе СКД для одной таблицы они явно заданы в виде параметров, то во вторую они подставятся при генерации макета компоновки. Для получения финального текста запроса можно использовать консоль компоновки данных (ИТС), либо написать свой обработчик компоновки в модуле отчета. Например:
Пример запроса, параметры явно заданы только для ТоварыНаСкладах.ОстаткиИОбороты:
Финальный текст запроса, компоновщик подставил параметры и в таблицу ТоварыНаСкладах.Обороты:
В данном случае можно использовать в запросе наименования явных параметров, отличные от автопараметров, например «НачалоПериодаОтбор» и «КонецПериодаОтбор». Либо отключить «автозаполнение» и выполнить настройку СКД самостоятельно.
Источник
СКД меняет текст запроса
Всем привет. Делаю отчет, который берет данные из регистра продаж. Запрос сделал, проверил в косоли запросов, данные выводятся корректно.
Вот сам текст запроса.
[1C]ВЫБРАТЬ
ПродажиОбороты.Контрагент КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты
ИЗ
РегистрНакопления.Продажи.Обороты(ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&НачалоПериода, ГОД, -1), ГОД), МЕСЯЦ, 4), ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&НачалоПериода, ГОД, -1), ГОД), МЕСЯЦ, 11), , ) КАК ПродажиОбороты
ИНДЕКСИРОВАТЬ ПО
Контрагент
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПродажиОбороты.Контрагент.Родитель КАК ГоловнойКонтрагент,
ПродажиОбороты.Номенклатура.НоменклатурнаяГруппа КАК ТМ,
ПродажиОбороты.Период КАК Период,
ПродажиОбороты.КоличествоОборот,
ПродажиОбороты.СтоимостьОборот,
"Старый" КАК НовыйСтарыйКонтрагент,
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивДивизионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ КАК Дивизион,
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивРегионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ КАК Регион
ПОМЕСТИТЬ ВТ_ИтоговыеДанные
ИЗ
РегистрНакопления.Продажи.Обороты(
&НачалоПериода,
&КонецПериода,
Месяц,
Контрагент В
(ВЫБРАТЬ
ВТ_Контрагенты.Контрагент
ИЗ
ВТ_Контрагенты КАК ВТ_Контрагенты)) КАК ПродажиОбороты
ВЫБРАТЬ
ПродажиОбороты.Контрагент.Родитель,
ПродажиОбороты.Номенклатура.НоменклатурнаяГруппа,
ПродажиОбороты.Период,
ПродажиОбороты.КоличествоОборот,
ПродажиОбороты.СтоимостьОборот,
"Новый",
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивДивизионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ,
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивРегионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ
ИЗ
РегистрНакопления.Продажи.Обороты(
&НачалоПериода,
&КонецПериода,
Месяц,
НЕ Контрагент В
(ВЫБРАТЬ
ВТ_Контрагенты.Контрагент
ИЗ
ВТ_Контрагенты КАК ВТ_Контрагенты)) КАК ПродажиОбороты
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВТ_ИтоговыеДанные.ГоловнойКонтрагент КАК ГоловнойКонтрагент,
ВТ_ИтоговыеДанные.ТМ КАК ТМ,
ВТ_ИтоговыеДанные.Период,
СУММА(ВТ_ИтоговыеДанные.КоличествоОборот) КАК КоличествоОборот,
СУММА(ВТ_ИтоговыеДанные.СтоимостьОборот) КАК СтоимостьОборот,
ВТ_ИтоговыеДанные.НовыйСтарыйКонтрагент,
ВТ_ИтоговыеДанные.Дивизион,
ВТ_ИтоговыеДанные.Регион
ИЗ
ВТ_ИтоговыеДанные КАК ВТ_ИтоговыеДанные
<ГДЕ
(ВТ_ИтоговыеДанные.Дивизион = &Дивизон) КАК Поле2>
СГРУППИРОВАТЬ ПО
ВТ_ИтоговыеДанные.ГоловнойКонтрагент,
ВТ_ИтоговыеДанные.ТМ,
ВТ_ИтоговыеДанные.Период,
ВТ_ИтоговыеДанные.НовыйСтарыйКонтрагент,
ВТ_ИтоговыеДанные.Дивизион,
ВТ_ИтоговыеДанные.Регион
[1C]
В СКД каверкаются параметры в первой временной таблице.
[1C]ВЫБРАТЬ
Продажи.Контрагент КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты
ИЗ
РегистрНакопления.Продажи.Обороты(&П, &П2, , ) КАК Продажи
ИНДЕКСИРОВАТЬ ПО
Контрагент
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ПродажиОбороты.Контрагент.Родитель КАК ГоловнойКонтрагент,
ПродажиОбороты.Номенклатура.НоменклатурнаяГруппа КАК ТМ,
ПродажиОбороты.Период КАК Период,
ПродажиОбороты.КоличествоОборот КАК КоличествоОборот,
"Старый" КАК НовыйСтарыйКонтрагент,
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивДивизионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ КАК Дивизион,
ВЫБОР
КОГДА ПродажиОбороты.Подразделение В (&МассивРегионов)
ТОГДА ПродажиОбороты.Подразделение
КОНЕЦ КАК Регион
ПОМЕСТИТЬ ВТ_ИтоговыеДанные
ИЗ
РегистрНакопления.Продажи.Обороты(
&П,
&П2,
Месяц,
Контрагент В
(ВЫБРАТЬ
ВТ_Контрагенты.Контрагент
ИЗ
ВТ_Контрагенты КАК ВТ_Контрагенты)) КАК ПродажиОбороты
ОБЪЕДИНИТЬ ВСЕ
. [1C]
Она подставляет туда те же параметры, что и во вторую, а это неверно, т.к. в первой параметры рассчетные. Соответственно данные выводятся в отчете неверно.
Что делать в этой ситуации кто-нибудь знает?
Отчет в СКД получил через консоль отчетов.
Источник