Дополнительные возможности параметров, передаваемых в запросе

26.06.14

Разработка - Запросы

Как из переданного параметра ссылочного типа в запросе получить различные поля объекта конфигурации

На днях писал запрос и наткнулся на интересную особенность при использовании параметров. Если передать параметры ссылочных типов, то к ним можно обращаться как к объектам конфигурации -  через оператор "точка". Например: нам необходимо выбрать документы "исполнительные листы" по какой-либо организации. Причем если в качестве параметра передается организация с кодом "01", нам нужно выбрать документы относящееся к организациям с кодами "01", "02", "03", иначе выбрать документы по переданной организации:

Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
|ИсполнительныйЛист.Организация КАК Организация,
|ИсполнительныйЛист.Физлицо КАК Сотрудник,
|ИсполнительныйЛист.Предел КАК СуммаВсего
| 
|ИЗ
|Документ.ИсполнительныйЛист КАК ИсполнительныйЛист
|			
|ГДЕ
|ВЫБОР КОГДА (ВЫРАЗИТЬ((&Организация).Код КАК СТРОКА(2))= "01" )
|	 ТОГДА ВЫРАЗИТЬ(ИсполнительныйЛист.Организация.Код КАК СТРОКА(2)) В ("01","02","53")
|	 ИНАЧЕ
|    	 ИсполнительныйЛист.Организация = &Организация
|КОНЕЦ";
Запрос.УстановитьПараметр("Организация", Справочник.Организации.НайтиПоКоду("01"));
 

В этом запросе мы обращаемся к параметру ссылочного типа "&Организация", мы можем извлечь из этого параметра любую информацию, например: наименование (&Организация.Наименование) или ИНН (&Организация.ИНН), словом все те реквизиты, которые есть в справочнике "Организации". При попытке открыть этот запрос в конструкторе запросов будет выдаваться ошибка, т.к. конструктор считает, что к параметру нельзя так обращаться, но на самом деле запрос РАБОТАЕТ!

 

Параметры Запрос

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    122172    670    389    

714

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5746    KawaNoNeko    23    

23

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2000    2    Yashazz    0    

29

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6286    31    mkalimulin    25    

50

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1742    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5388    user1923546    26    

43

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16186    skovpin_sa    14    

98
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. GH0STexe 12 27.06.14 06:14 Сейчас в теме
Норм. Не знал,что так можно. Типа недокументированная фича что ли ?
2. TMV 14 27.06.14 08:42 Сейчас в теме
(0), Интересная находка, но все же предпочитаю, чтобы конструктор запроса не выдавал ошибок о невозможности чтения текста запроса.
3. ShantinTD 91 27.06.14 10:15 Сейчас в теме
О_о. Прикольно. И иногда (насколько часто?) полезно. Сам тоже предпочитаю конструкторопригодный запрос, так что согласен с (2). Но на заметку возьму!
6. Yashazz 4709 30.06.14 13:12 Сейчас в теме
(2) Конструктор иногда сам, например, сгенерит текст, и сам же его открыть не может. Так что в (5) правильно сказано - всякими строковыми играми можно его обмануть и выкрутиться.
11. 7OH 69 02.07.14 13:04 Сейчас в теме
Хм.
А не легче ли пользоваться левым соединением, чем писать нечитаемые запросы ?
Ну или
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
|ИсполнительныйЛист.Организация КАК Организация,
|ИсполнительныйЛист.Физлицо КАК Сотрудник,
|ИсполнительныйЛист.Предел КАК СуммаВсего
| 
|ИЗ
|Документ.ИсполнительныйЛист КАК ИсполнительныйЛист
|            
|ГДЕ
|ВЫБОР КОГДА (&другаяОрганизация = &Организация01 )
|     ТОГДА ВЫРАЗИТЬ(ИсполнительныйЛист.Организация.Код КАК СТРОКА(2)) В ("01","02","53")
|     ИНАЧЕ
|         ИсполнительныйЛист.Организация = &Организация
|КОНЕЦ";
Запрос.УстановитьПараметр("Организация01", Справочник.Организации.НайтиПоКоду("01"));
Запрос.УстановитьПараметр("Организация", другаяОрганизация);
Показать
12. ShantinTD 91 02.07.14 14:11 Сейчас в теме
(11) 7OH, Какова судьба параметра &другаяОрганизация ?

Еще пример: есть справочник, у него в реквизитах хранятся 2 даты - начало и конец периода (за который предполагается провести некую оценку). Так вот предложенный в (8) приём позволит передать всего один параметр, и спокойно работать с его реквизитами.
Выбрать 
 *
ИЗ 
 РегистрНакопления.ПродажиПоДисконтнымКартам КАК ПродажиПоДисконтнымКартам
ГДЕ
 ПродажиПоДисконтнымКартам.Период МЕЖДУ ВЫРАЗИТЬ(&ПризнакРассылки КАК Справочник.ПризнакСМСРассылки).НачалоПродаж И ВЫРАЗИТЬ(&ПризнакРассылки КАК Справочник.ПризнакСМСРассылки).КонецПродаж


Использование лишней временной таблицы, соединение, и все сопутствующие навороты навряд ли добавит читаемости запросу, и, сдается мне, негативно скажется на времени выполнения запроса.

А по поводу Вашего "ну или": в (0) вопрос ставился именно о том, чтобы передавать параметр и обращаться к его реквизитам. В (8) было предложено как при этом сделать запрос пригодным для редактирования конструктором (да и на глаз он сильно страдает). В предложенном Вами варианте нет обращения к реквизитам параметра. В чем "дополнительная возможность использования параметра"? В варианте с "левым соединением" аналогично не будет обращения к реквизитам параметра, да еще и усложнение запроса убавит его читаемости и добавит узких мест (в том смысле, что на лишнем соединении больше шансов накосячить). Кстати: если в том месте, где появится это самое "лишнее" соединение и без того уже есть соединение (нужное, не лишнее), то вероятность накосячить в соединениях многократно возрастает. А обращение к реквизитам параметра позволит спокойно описать все нужные условия или связи.

Хотя могу и заступиться за Ваш способ с соединением: реквизиты параметра (из которого получается таблица из целой одной записи) доступны конструктором. При простом обращении к реквизитам параметра придется писать реквизиты руками, а конструктор будет лишь ругаться, что не нашел такого при неправильном написании, не предлагая правильных вариантов.
19. qwinter 671 09.07.14 11:00 Сейчас в теме
(12) ShantinTD, учитывайте, что при каждом обращении через точку, будет еще одна (и одну ли?) временная таблица.
Использование лишней временной таблицы, соединение, и все сопутствующие навороты навряд ли добавит читаемости запросу, и, сдается мне, негативно скажется на времени выполнения запроса.
использование временной таблице скажется хорошо на времени выполнения запроса. Как минимум 1С не придется самой дописывать в запрос эту временную таблицу (а она любит несколько подзапросов строить, для вытаскивания всех данных). К тому же эти подзапросы будут построены на каждое такое обращение.
Еще пример: есть справочник, у него в реквизитах хранятся 2 даты - начало и конец периода (за который предполагается провести некую оценку). Так вот предложенный в (8) приём позволит передать всего один параметр, и спокойно работать с его реквизитами.
Только передаваемый параметр у вас и так в кеше есть, и его реквизиты уже прочитаны в тот момент, когда вы его передаете.
4. mr.Kot 27.06.14 11:38 Сейчас в теме
Интересная вещь, не знаю, запомню ли, т.к. для применения они вряд ли будет часто нужна. Но применять может, к сожалению, только в простых запросах, которые легко читать глазами и вручную (без конструктора) исправлять, что, кстати, для программистом с ещё не большим опытом тяжело.
5. ShantinTD 91 30.06.14 09:12 Сейчас в теме
Для возможности редактирования запроса с применением такого приема могу предложить комбинировать его с приемом замены текста.
Поясню: в приведенном в (0) запросе можно написать &Организация_Код, и запрос можно будет открыть редактором. Если произвести в тексте запроса замену (самым простым СтрЗаменить(...)) на &Организация.Код, то получим запрос "с хитростью". А можно и не подменять ничего, а просто передать в запрос несколько "лишних" параметров. Для новичков это должно быть проще, чем редактировать запрос "руками".
А если запрос уже отлажен, "вылизан", и редактировать его больше не предполагается, то можно смело заменить непосредственно в тексте запроса "лишние" параметры так, как предложено в (0).
loy; bird21; SCRIPT91; +3 Ответить
7. asved.ru 36 02.07.14 04:12 Сейчас в теме
Сама по себе идея отбора по реквизиту "через точку" - лишнее соединение. Причем справочник "Организации", как правило, невелик, а значит, читаться будет scan'ом.

В то же время когда мы передаем в параметр массив ссылок, соединения с таблицей справочника Организации не будет вообще.
AlexanderKai; +1 Ответить
8. danila_zlt 02.07.14 06:34 Сейчас в теме
ВЫРАЗИТЬ(&Организация как Справочник.Организации).Код

И конструктор не будет ругаться.
boln; Nuobu; ixijixi; Рамзес; echo77; Puk2; loy; wolfsoft; BigB; serg_gres; Yimaida; bird21; ShantinTD; vde69; +14 Ответить
10. vde69 925 02.07.14 07:42 Сейчас в теме
рекомендую использовать (8) так как (0) грозит запросом к метаданным строк этак на 500.

Вообще любые нетипизированые вещи в запросе - зло, именно по этому рекомендуется использовать типизированые ТЗ в качестве параметров.
anchovy; Ish_2; Dach; ShantinTD; Makushimo; +5 Ответить
9. МимохожийОднако 141 02.07.14 07:03 Сейчас в теме
Кто-нибудь делал замер подобной конструкции по сравнению со стандартным запросом? Подход любопытный, но как это влияет на производительность и какой результирующий запрос будет к SQL-серверу?
13. bird21 42 02.07.14 14:35 Сейчас в теме
Любопытно, не сталкивался раньше с таким.
14. Damian 909 04.07.14 09:08 Сейчас в теме
Книга "Язык запросов 1С:Предприятие 8" от Хрусталевой и Радченко (2013 год) в разделе про оптимизацию запросов настоятельно рекомендует воздержаться от применения каких-либо функций к передаваемым в запрос параметрам. Лучше все необходимое вычислить снаружи и передать в запрос уже константы.
Даже банальное "НАЧАЛОПЕРИОДА(&ДатаОстатков,ДЕНЬ)" не советуют использовать в тексте запроса.
17. asved.ru 36 04.07.14 11:50 Сейчас в теме
(14) Damian, это общая рекомендация. На самом деле так делать можно, если понимаешь, что делаешь и сколько раз будет выполнено вычисление значения.
15. bforce 481 04.07.14 10:54 Сейчас в теме
По хорошему такие запросы нужно писать так.

Способ 1. Получаем нужные данные в коде, а не в запросе.
|ВЫБОР
| КОГДА &Организация = &ОсобаяОрганизация
| ТОГДА ИсполнительныйЛист.Организация В (&МассивОгранизаций)
| ИНАЧЕ
| ИсполнительныйЛист.Организация = &Организация
|КОНЕЦ

Запрос.УстановитьПараметр("Организация", Документ.Огранизация);
Запрос.УстановитьПараметр("ОсобаяОрганизация", Справочник.Организации.НайтиПоКоду("01")); // А лучше здесь завести константу или обращаться к регистру сведений.
Запрос.УстановитьПараметр("МассивОгранизаций", СписокОгранизаций);

Способ 2. Избавляемся от сложной конструкции в условии ГДЕ (для СУБД так будет легче).

|ГДЕ
| ИсполнительныйЛист.Организация В (&МассивОгранизаций)

Запрос.УстановитьПараметр("МассивОгранизаций", УжеПодготовленныйСписокВашихОрганизаций);

Способ 3. Для тех, случаев, когда избежать обращения через точку не удается.

|ВЫБОР
| КОГДА
| ВЫРАЗИТЬ (&Организация КАК Справочник.Организации).ИНН ПОДОБНО "68465_"
|КОНЕЦ

Хотя, я, наверное, излишне помешан на оптимизации. Работа такая. Приношу извинения.
16. asved.ru 36 04.07.14 11:48 Сейчас в теме
bforce,

| ВЫРАЗИТЬ (&Организация КАК Справочник.Организации).ИНН ПОДОБНО "68465_"(15)


Применение ВЫРАЗИТЬ здесь никакой смысловой нагрузки не несет, т.к. платформа определяет тип параметра, и он у нас в данном случае простой.

ВЫРАЗИТЬ применяется к полю составного типа для ограничения типов (а следовательно, количества соединений) данных, которые требуют обращения через точку.

Грубо говоря, если у нас есть поле составного типа Регистратор {ДокументСсылка.Реализация, ДокументСсылка.Поступление}
и мы пишем "ВЫБРАТЬ Регистратор.Дата" то запрос будет состоять из двух соединений:
1) Наша исходная таблица с таблицей Документ.Поступление по равенству поля Ссылка
1) Наша исходная таблица с таблицей Документ.Реализация по равенству поля Ссылка

А если мы напишем "ВЫБРАТЬ ВЫРАЗИТЬ(Регистратор КАК Документ.Реализация).Дата",
то соединение будет только одно:
Наша исходная таблица с таблицей Документ.Реализация по равенству поля Ссылка

второе соединение будет отфильтровано именно применением оператора ВЫРАЗИТЬ
18. bforce 481 04.07.14 12:13 Сейчас в теме
(16), ВЫРАЗИТЬ здесь имеет смысл потому, что я привожу параметр к определенному типу и гарантированно не получу ошибки в запросе при обращении к реквизиту объекта. Кроме того, запрос в конструкторе нормально открывается (автору это, кажется, было важно).
Если вы предпочитаете такую конструкцию
ВЫРАЗИТЬ((&Организация).Код КАК СТРОКА(2)
,
то должны в полной мере понимать что это за собой может повлечь.

Про составной тип я не стал грузить, хотя в этом случае приведение к типу для получения значения реквизита стоит использовать почти всегда.

(14), и правильно пишут, причем? не только они. Здесь, под заголовком "Эффективные планы запросов", как раз такой пример и приводится. Хотя, кого это интересует? Лучше ж "на коленке" написать и не думать о последствиях! Если у разработчика база с тремя пользователями, то такое, конечно же, прокатит, и он не заметит разницы.
20. omut 15.07.14 01:54 Сейчас в теме
Интересный момент. По кэшу: на сколько помню, получение ссылки не означает чтение реквизитов. В связи с этим, нужно смотреть контекст выполнения запроса. Если до выполнения реквизиты прочитаны, то смысла изгаляться подобным образом нет. Вред один. А вот если не прочитаны, то потенциально можно получить даже увеличение производительности. Поправьте, если не прав.
21. qwinter 671 15.07.14 09:12 Сейчас в теме
(20) omut, насколько помню при получении ссылки в кеш сразу считываются кэшируемые показатели, будем считать, что эти два не кэшируемые. В этом случае в кеш будет считаны все реквизиты ссылки при обращении к первому реквизиту (максимум один запрос в любом случаее). Второй будет считан из кеша. При передачи одного параметра в запрос, при каждом обращении через точку будет добавлен подзапрос. То минимум будет два дополнительных запроса (на каждый реквизит) + столько запросов, сколько раз вы к этим реквизитам обратитесь в запросе.
22. Cthulhu 1 02.02.21 20:55 Сейчас в теме
однако ни "(&СсылкаДокумент).Дата" ни "ВЫРАЗИТЬ(&СсылкаДокумент КАК Документ.КакоНибудь).Дата" не годится для указания в параметре виртуальной таблицы, например... и чо делать?.. а ведь бывает надо и нередко.
Оставьте свое сообщение