|
Как избежать рваного запроса | ☑ | ||
---|---|---|---|---|
0
golem14
20.07.21
✎
06:24
|
Мне нужно добавить в запрос условие которое может быть включено иди выключено.
Где Документ.Валюта = &Рубли Я сделал через динамическое построение текста запроса: + ДопУсловие + ну и установка параметра Запрос.УстановитьПараметр("Рубли", Справочники.Валюты.НайтиПоНаименованию("RUB")); Но я не хочу чтобы запрос собирался из кусочков, это неудобно для дальнейшей разработки и отладки. Как можно сделать это динамическое условие более удобным и понятным? |
|||
1
dubolom
20.07.21
✎
06:29
|
Если СКД, то фигурные скобки.
Если нет, то ГДЕ &ЕстьВалюта = ЛОЖЬ ИЛИ Документ.Валюта = &Рубли И передаёте дополнительный параметр, включающий/выключающий условие. |
|||
2
ILM
модератор
20.07.21
✎
06:32
|
ВЫБОР - вот ваш выбор!
Например условие в секции запроса "ГДЕ": ГДЕ ВЫБОР КОГДА &Рубли = НЕОПРЕДЕЛЕНО ТОГДА ИСТИНА ИНАЧЕ Документ.Валюта =&Рубли КОНЕЦ |
|||
3
spectre1978
20.07.21
✎
06:33
|
Внутри запроса допустим комментарий //.
Можно в тексте сделать закомментированное условие, а в случае необходимости выпонить СтрЗаменить (ТекстЗапроса, '//', ''). Добавив после // некое ключевое слово, это можно без проблем расширить на множество условий. |
|||
4
Адинэснег
20.07.21
✎
06:39
|
(0) Схема запроса
Привет из 2018 |
|||
5
ILM
модератор
20.07.21
✎
06:39
|
(3) Это не удобно, давно в 2006 году это было нормой в УПП. Потом сделали отдельные запросы, так как при работе с конструктором запросов все комментарии удаляются.
|
|||
6
Адинэснег
20.07.21
✎
06:41
|
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(Запрос.Текст); // ковыряем запрос как объект Запрос.Текст = СхемаЗапроса.ПолучитьТекстЗапроса(); |
|||
7
Адинэснег
20.07.21
✎
06:45
|
если принципиально через запрос, то передавай параметр "... ГДЕ &НужноВключитьОтбор И Документ.Валюта = &Рубли"
Запрос.УстановитьПараметр("НужноВключитьОтбор ", ОтборВключаем); |
|||
8
golem14
20.07.21
✎
06:49
|
сделал так:
&ТолькоРублевыеПлатежи = Ложь ИЛИ ЗнРДС.Валюта = &Рубли |
|||
9
golem14
20.07.21
✎
06:49
|
(6) а что за схема запроса? чем это отличается от того что я просто буду править текст запроса как строку?
|
|||
10
ДенисЧ
20.07.21
✎
06:51
|
(9) Это будет стильно и модно.
|
|||
11
golem14
20.07.21
✎
06:55
|
(10) и чем оно тогда отличается от построения через СКД?
|
|||
12
Адинэснег
20.07.21
✎
07:06
|
(9) когда запрос нужно будет изменить не в 2х, а 22х местах
(11) СКД то тут причем? 🤣 |
|||
13
ДедМорроз
20.07.21
✎
07:08
|
А теперь представьте,что у вас таких условий несколько.
Поэтому,или использовать СКД с автовключением условий или строить текст запроса из частей - например - все условия,которые применяются в массив,а потом СтрСоединить. |
|||
14
Документовед
20.07.21
✎
07:08
|
Запрос.УстановитьПараметр("спСтатейЗатратИсключений", Отчет.спСтатейЗатратИсключений);
Запрос.УстановитьПараметр("ЕстьспСтатейЗатратИсключений", Отчет.спСтатейЗатратИсключений.Количество()>0); Запрос.УстановитьПараметр("Организация", Отчет.Организация); Запрос.УстановитьПараметр("ЕстьОрганизация", ЗначениеЗаполнено(Отчет.Организация)); | ВЫБОР | КОГДА &ЕстьОрганизация | ТОГДА Организация = &Организация | ИНАЧЕ ИСТИНА | КОНЕЦ, | И ВЫБОР | КОГДА &ЕстьспСтатейЗатратИсключений | ТОГДА НЕ Субконто2 В ИЕРАРХИИ (&спСтатейЗатратИсключений) | ИНАЧЕ ИСТИНА | КОНЕЦ, |
|||
15
Документовед
20.07.21
✎
07:09
|
+ можно проще: Организация = &Организация или не &ЕстьОрганизация
Но так хуже читается |
|||
16
Адинэснег
20.07.21
✎
07:11
|
(14)(15) главное - вовремя
|
|||
17
Малыш Джон
20.07.21
✎
07:15
|
(0) Или, как выше советуют, делать составное условие,
Или в тексте запроса поставить "ГДЕ &МоеУсловие", а потом в коде ТекстЗапроса = СтрЗаменить(ТекстЗапроса,"&МоеУсловие", "...то условие которое нужно...") Плюс второго способа, что условие запроса получается проще и в конструкторе такой текст запроса тоже открывается. |
|||
18
golem14
20.07.21
✎
07:36
|
(6) Запрос как объект это таки интересно, буду пробовать, а говорят ещё что язык 1С не объектный :-)
В типовой ERP вижу много мест где это используется, но похоже кроме писателей типовых это никому не сдалось и только запутывает. |
|||
19
golem14
20.07.21
✎
07:44
|
схема запроса это просто
https://infostart.ru/upload/iblock/89a/shema_m.jpg |
|||
20
TormozIT
гуру
20.07.21
✎
08:32
|
Олды в доме. Они приносят древнюю магию.
Построитель запроса для таких целей оптимален. Допустим есть запрос выбрать т.Регистратор из РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто как т ГДЕ 12 <> т.ВидСубконтоДт2 И надо условно добавить условие т.Сумма > 100 Делай выбрать т.Регистратор из РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто как т ГДЕ 12 <> т.ВидСубконтоДт2 {ГДЕ (т.Сумма > 100) КАК ТолькоБольшиеСуммы } Дальше в настройках построителя условно добавляешь отбор по полю ТолькоБольшиеСуммы построитель = Новый ПостроительЗапроса; построитель.Текст = "выбрать т.Регистратор из РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто как т |ГДЕ 12 <> т.ВидСубконтоДт2 |{ГДЕ | (т.Сумма > 100) КАК ТолькоБольшиеСуммы |}"; построитель.ЗаполнитьНастройки(); Если 1=1 Тогда построитель.Отбор.Добавить("ТолькоБольшиеСуммы").Установить(Истина); КонецЕсли; Запрос = построитель.ПолучитьЗапрос(); и при добавленном элементе отбора получаешь запрос ВЫБРАТЬ т.Регистратор КАК Регистратор ИЗ РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК т ГДЕ 12 <> т.ВидСубконтоДт2 И т.Сумма > 100 = &Параметр1 https://i.imgur.com/pG91Urp.png а без добавленного элемента отбора получаешь запрос ВЫБРАТЬ т.Регистратор КАК Регистратор ИЗ РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК т ГДЕ 12 <> т.ВидСубконтоДт2 https://i.imgur.com/DlnlR6M.png |
|||
21
TormozIT
гуру
20.07.21
✎
08:41
|
(20) Компоновка отработает по той же схеме и более современна, но потребует больше писать кода.
|
|||
22
TormozIT
гуру
20.07.21
✎
08:44
|
(20) Такой подход правда годится только для условий в верхней группе "И".
|
|||
23
TormozIT
гуру
20.07.21
✎
09:08
|
А самым универсальным подходом конечно является СтрЗаменить(). Вставляем в запрос нейтральный уникальный фрагмент в группу условий и к нему привязываем условные вставки динамических фрагментов
Например для группы "И" можно применять фрагмент - {И "ТочкаВставкиИ1" = "ТочкаВставкиИ1"}, а для группы "ИЛИ" - {ИЛИ "ТочкаВставкиИ1" = 0}. При этом для повышения надежности вставки контролируем наличие опорного фрагмента. Текст = "выбрать т.Регистратор из РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто как т |ГДЕ 12 <> т.ВидСубконтоДт2 Или ""ТочкаВставкиИЛИ1"" = 0 ИЛИ (11 <> т.ВидСубконтоДт2 И ""ТочкаВставкиИ1"" = ""ТочкаВставкиИ1"")"; Текст = ирОбщий.СтрЗаменитьЛкс(Текст, """ТочкаВставкиИЛИ1"" = 0", " ИЛИ Т.Сумма > 100", Истина); Текст = ирОбщий.СтрЗаменитьЛкс(Текст, """ТочкаВставкиИ1"" = ""ТочкаВставкиИ1""", " И Т.Сумма > 200", Истина); Функция СтрЗаменитьЛкс(Знач ГдеЗаменять, Знач ЧтоЗаменять, Знач НаЧтоЗаменять, ОставитьЧтоЗаменять = Ложь, ВыброситьИсключениеПриОтсутствии = Истина) Экспорт Если ВыброситьИсключениеПриОтсутствии И Найти(ГдеЗаменять, ЧтоЗаменять) < 1 Тогда ВызватьИсключение "Шаблонная строка """ + ЧтоЗаменять + """ не найдена в тексте"; КонецЕсли; Если ОставитьЧтоЗаменять Тогда НаЧтоЗаменять = ЧтоЗаменять + НаЧтоЗаменять; КонецЕсли; Результат = СтрЗаменить(ГдеЗаменять, ЧтоЗаменять, НаЧтоЗаменять); Возврат Результат; КонецФункции |
|||
24
TormozIT
гуру
20.07.21
✎
09:09
|
(23) Ошибся. Надо
для группы "ИЛИ" - {ИЛИ "ТочкаВставкиИЛИ1" = 0} |
|||
25
Документовед
20.07.21
✎
09:28
|
(23)
Почему вместо "{ИЛИ "ТочкаВставкиИ1" = 0}" не вставить: "ИЛИ &ТочкаВставкиИ1" А потом уже Текст = ирОбщий.СтрЗаменитьЛкс(Текст, "&ТочкаВставкиИ1", " ИЛИ Т.Сумма > 100", Истина); Не так вырвиглазно выглядит. |
|||
26
TormozIT
гуру
20.07.21
✎
09:31
|
(25) Тогда придется в запросе еще устанавливать служебные параметры "ТочкаВставки*" с правильными значениями Истина/Ложь. Дело вкуса.
|
|||
27
Галахад
гуру
20.07.21
✎
09:34
|
(23) А что за постфик "Лкс"?
|
|||
28
TormozIT
гуру
20.07.21
✎
09:35
|
(27) "Лучший Код Старыха"
|
|||
29
Галахад
гуру
20.07.21
✎
09:39
|
(28) :-)
|
|||
30
Cyberhawk
20.07.21
✎
09:50
|
(26) В варианте из (25) в запросе не остается служебных параметров, поэтому их устанавливать не требуется
|
|||
31
1CnikPetya
20.07.21
✎
09:50
|
Мне нравится такой вариант, его и применяю:
Запрос.Текст = "ВЫБРАТЬ ... ИЗ Таблица ГДЕ &УсловиеНаВлюту"; Потом уже постобработка по тексту: Если НуженОтборПоВалюте Тогда СтрЗаменить(ТекстЗапроса, "&УсловиеНаВлюту", "Таблилца.Валюта = &Рубль"); Запрос.УстановитьЗначениеПараметра("Рубль", Рубль); Иначе СтрЗаменить(ТекстЗапроса, "&УсловиеНаВлюту", "ИСТИНА"); КонецЕсли; В итоге запрос открывается конструктором, хорошо читаем, не передаются лишние параметры и не пишутся лишние условия. |
|||
32
TormozIT
гуру
20.07.21
✎
09:57
|
(30) Не понял тебя. Замена же выполняется условно, т.е. может не применяться.
|
|||
33
ManyakRus
20.07.21
✎
09:58
|
(31) Текст запроса должен быть такой чтоб его легко можно было скопировать в консоль запросов.
Такой код ужасный для консоли отчётов. Надо писать комментарии в запросе а потом заменять комментарий на текст (и не пользоваться конструктором никогда) |
|||
34
TormozIT
гуру
20.07.21
✎
10:00
|
(33) Условие можно быть полностью динамическое, т.е. заранее не известна строка, на которую заменять будем.
|
|||
35
TormozIT
гуру
20.07.21
✎
10:01
|
(33) Ну и запрет использования конструктора - сразу минус 5 к универсальности.
|
|||
36
arsik
гуру
20.07.21
✎
10:02
|
(31) Так же делаю.
|
|||
37
1CnikPetya
20.07.21
✎
10:05
|
(33) Конструктором пользуюсь, чтобы накидать основу запроса и проверить его синтаксис. Мне не нравится форматирование конструктора, но понимаю тех, кто им пользуется. Так же удобно смотреть структуру запросов на несколько экранов.
По подстановке параметров (34) правильно сказал. А в моем варианте можно этот параметр поставить ИСТИНА и будет в консоли вариант без его учета. А дальше уже крути от потребностей. |
|||
38
TormozIT
гуру
20.07.21
✎
10:05
|
(31) Опасность тут в том, что потом можно дописать к этому условию " ИЛИ Сумма = 0" и тогда работать итоговое условие будет не так, как ожидалось. Поэтому надо в имени точки привязки лучше обозначать ее тип (Истина/Ложь/И/Или).
|
|||
39
1CnikPetya
20.07.21
✎
10:16
|
(38) Имеешь ввиду
"ГДЕ &УсловиеНаВлюту ИЛИ Сумма = 0" или СтрЗаменить(ТекстЗапроса, "&УсловиеНаВлюту", "Таблилца.Валюта = &Рубль ИЛИ Сумма = 0")? Немного не понимаю, в чем риск. |
|||
40
TormozIT
гуру
20.07.21
✎
10:20
|
(39) Текст = "... ГДЕ &УсловиеНаВлюту ИЛИ Сумма = 0"
СтрЗаменить(ТекстЗапроса, "&УсловиеНаВлюту", "ИСТИНА"); |
|||
41
1CnikPetya
20.07.21
✎
10:28
|
(40) Ну, вот тут я не согласен. Просто по тексту запроса получается вполне явно: условие на валюту проверяем при ненулевой сумме документа. А какое условие на валюту - это уже отдельный вопрос.
|
|||
42
DeeK
20.07.21
✎
12:07
|
если запрос простой и нужно маленький кусочек в нем динамически вставить то проблем с отладкой не будет, а когда по 30 временных таблиц, то юзаю менеджер, там все тоже можно удобно посмотреть
|
|||
43
SiAl-chel
20.07.21
✎
14:44
|
(2) Лучше через ИЛИ, читается легче.
&Рубли = НЕОПРЕДЕЛЕНО ИЛИ Документ.Валюта = &Рубли |
|||
44
Документовед
20.07.21
✎
16:02
|
(43) откуда там «неопределено» там будет пустая ссылка на справочник.
|
|||
45
Документовед
20.07.21
✎
16:03
|
(43) читается проще через условие
|
|||
46
Вафель
20.07.21
✎
16:07
|
Пиши не + ДоУсловие +, а &ДопУсловие
А остальное все так же |
|||
47
OldCondom
20.07.21
✎
16:15
|
(46) + 100. Также использую &ТекстФильтра.
|
|||
48
Кирпич
20.07.21
✎
16:15
|
Так пишу
|
|||
49
АнализДанных
21.07.21
✎
10:14
|
(0) (20) Мне в таких ситуациях тоже нравится использовать построитель запроса. В этом случае можно использовать конструктор запросов, код более понятный становится. Ниже пример процедуры, которая сама формирует текст запроса.
ТекстЗапроса = "ВЫБРАТЬ | Номенклатура.Ссылка КАК Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Ссылка <> &ИсключаемаяНоменклатура |{ГДЕ | Номенклатура.СтавкаНДС.* КАК СтавкаНДС, | Номенклатура.Производитель.*, | Номенклатура.Наименование}"; ДинамическиеОтборы = Новый Структура; Если ИспользоватьОтбор_СтавкаНДС Тогда ПараметрыОтбора = Новый Структура; ПараметрыОтбора.Вставить("ВидСравнения", ВидСравнения.ВСписке); ПараметрыОтбора.Вставить("Значение", СписокСтавокНДС); ДинамическиеОтборы.Вставить("СтавкаНДС", ПараметрыОтбора); КонецЕсли; Если ИспользоватьОтбор_Производитель Тогда ДинамическиеОтборы.Вставить("Производитель", Производитель); КонецЕсли; Если ИспользоватьОтбор_Наименование Тогда ПараметрыОтбора = Новый Структура; ПараметрыОтбора.Вставить("ВидСравнения", ВидСравнения.НеСодержит); ПараметрыОтбора.Вставить("Значение", "Поддон"); ДинамическиеОтборы.Вставить("Наименование", ПараметрыОтбора); КонецЕсли; ФиксированныеПараметры = Новый Структура; ФиксированныеПараметры.Вставить("ИсключаемаяНоменклатура", ИсключаемаяНоменклатура); Запрос = СформироватьЗапросПоДинамическимУсловиям(ТекстЗапроса, ДинамическиеОтборы, ФиксированныеПараметры); // Создает объект "запрос", используя расширение языка запроса // // Параметры: // ТекстЗапроса - Строка - Текст запроса, в котором может содержаться расширение языка запроса // ДинамическиеПараметры - Структура - Значение необязательных параметров запроса, где: // * Ключ - Строка - Имя параметра из расширения языка запросов // * Значение - произвольное значение параметра или Структура, где: // * ВидСравнения - ВидСравнения - содержит вид сравнения // * Значение - произвольное значение параметра // ФиксированныеПараметры - Структура - Значение обязательных параметров запроса, где: // * Ключ - Строка - Содержит имя параметра запроса // * Значение - Произвольное - Значение параметра // // Возвращаемое значение: // Запрос - Объект "Запрос" - Запрос с установленными параметрами и текстом запроса. // Функция СформироватьЗапросПоДинамическимУсловиям(ТекстЗапроса, Знач ДинамическиеПараметры = Неопределено, Знач ФиксированныеПараметры = Неопределено) Экспорт Если ДинамическиеПараметры = Неопределено Тогда ДинамическиеПараметры = Новый Структура; КонецЕсли; Если ФиксированныеПараметры = Неопределено Тогда ФиксированныеПараметры = Новый Структура; КонецЕсли; ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = ТекстЗапроса; Для Каждого КлючИЗначение Из ФиксированныеПараметры Цикл ПостроительЗапроса.Параметры.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; ТипыСКоллекциями = Новый Массив; ТипыСКоллекциями.Добавить(Тип("Массив")); ТипыСКоллекциями.Добавить(Тип("СписокЗначений")); Для Каждого КлючИЗначение Из ДинамическиеПараметры Цикл ЭлОтбора = ПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ); ЭлОтбора.Использование = Истина; Тип_ЗначениеОтбора = ТипЗнч(КлючИЗначение.Значение); Если Тип_ЗначениеОтбора = Тип("Структура") Тогда ПараметрыЭлОтбора = КлючИЗначение.Значение; ЭлОтбора.ВидСравнения = ПараметрыЭлОтбора.ВидСравнения; ЭлОтбора.Значение = ПараметрыЭлОтбора.Значение; Иначе ЗначениеОтбора = КлючИЗначение.Значение; Если ТипыСКоллекциями.Найти(Тип_ЗначениеОтбора)<>Неопределено Тогда ЭлОтбора.ВидСравнения = ВидСравнения.ВСписке; КонецЕсли; Если Тип_ЗначениеОтбора = Тип("Массив") Тогда ЗначениеОтбора = Новый СписокЗначений; ЗначениеОтбора.ЗагрузитьЗначения(КлючИЗначение.Значение); КонецЕсли; ЭлОтбора.Значение = ЗначениеОтбора; КонецЕсли; КонецЦикла; Запрос = ПостроительЗапроса.ПолучитьЗапрос(); Возврат Запрос; КонецФункции |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |