|   |   | 
| 
 | Как избежать рваного запроса | ☑ | ||
|---|---|---|---|---|
| 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) Мне в таких ситуациях тоже нравится использовать построитель запроса. В этом случае можно использовать конструктор запросов, код более понятный становится. Ниже пример процедуры, которая сама формирует текст запроса.
 ТекстЗапроса = "ВЫБРАТЬ | Номенклатура.Ссылка КАК Ссылка |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.Ссылка <> &ИсключаемаяНоменклатура |{ГДЕ | Номенклатура.СтавкаНДС.* КАК СтавкаНДС, | Номенклатура.Производитель.*, | Номенклатура.Наименование}"; ДинамическиеОтборы = Новый Структура; Если ИспользоватьОтбор_СтавкаНДС Тогда ПараметрыОтбора = Новый Структура; ПараметрыОтбора.Вставить("ВидСравнения", ВидСравнения.ВСписке); ПараметрыОтбора.Вставить("Значение", СписокСтавокНДС); ДинамическиеОтборы.Вставить("СтавкаНДС", ПараметрыОтбора); КонецЕсли; Если ИспользоватьОтбор_Производитель Тогда ДинамическиеОтборы.Вставить("Производитель", Производитель); КонецЕсли; Если ИспользоватьОтбор_Наименование Тогда ПараметрыОтбора = Новый Структура; ПараметрыОтбора.Вставить("ВидСравнения", ВидСравнения.НеСодержит); ПараметрыОтбора.Вставить("Значение", "Поддон"); ДинамическиеОтборы.Вставить("Наименование", ПараметрыОтбора); КонецЕсли; ФиксированныеПараметры = Новый Структура; ФиксированныеПараметры.Вставить("ИсключаемаяНоменклатура", ИсключаемаяНоменклатура); Запрос = СформироватьЗапросПоДинамическимУсловиям(ТекстЗапроса, ДинамическиеОтборы, ФиксированныеПараметры); // Создает объект "запрос", используя расширение языка запроса // // Параметры: // ТекстЗапроса - Строка - Текст запроса, в котором может содержаться расширение языка запроса // ДинамическиеПараметры - Структура - Значение необязательных параметров запроса, где: // * Ключ - Строка - Имя параметра из расширения языка запросов // * Значение - произвольное значение параметра или Структура, где: // * ВидСравнения - ВидСравнения - содержит вид сравнения // * Значение - произвольное значение параметра // ФиксированныеПараметры - Структура - Значение обязательных параметров запроса, где: // * Ключ - Строка - Содержит имя параметра запроса // * Значение - Произвольное - Значение параметра // // Возвращаемое значение: // Запрос - Объект "Запрос" - Запрос с установленными параметрами и текстом запроса. // Функция СформироватьЗапросПоДинамическимУсловиям(ТекстЗапроса, Знач ДинамическиеПараметры = Неопределено, Знач ФиксированныеПараметры = Неопределено) Экспорт Если ДинамическиеПараметры = Неопределено Тогда ДинамическиеПараметры = Новый Структура; КонецЕсли; Если ФиксированныеПараметры = Неопределено Тогда ФиксированныеПараметры = Новый Структура; КонецЕсли; ПостроительЗапроса = Новый ПостроительЗапроса; ПостроительЗапроса.Текст = ТекстЗапроса; Для Каждого КлючИЗначение Из ФиксированныеПараметры Цикл ПостроительЗапроса.Параметры.Вставить(КлючИЗначение.Ключ, КлючИЗначение.Значение); КонецЦикла; ТипыСКоллекциями = Новый Массив; ТипыСКоллекциями.Добавить(Тип("Массив")); ТипыСКоллекциями.Добавить(Тип("СписокЗначений")); Для Каждого КлючИЗначение Из ДинамическиеПараметры Цикл ЭлОтбора = ПостроительЗапроса.Отбор.Добавить(КлючИЗначение.Ключ); ЭлОтбора.Использование = Истина; Тип_ЗначениеОтбора = ТипЗнч(КлючИЗначение.Значение); Если Тип_ЗначениеОтбора = Тип("Структура") Тогда ПараметрыЭлОтбора = КлючИЗначение.Значение; ЭлОтбора.ВидСравнения = ПараметрыЭлОтбора.ВидСравнения; ЭлОтбора.Значение = ПараметрыЭлОтбора.Значение; Иначе ЗначениеОтбора = КлючИЗначение.Значение; Если ТипыСКоллекциями.Найти(Тип_ЗначениеОтбора)<>Неопределено Тогда ЭлОтбора.ВидСравнения = ВидСравнения.ВСписке; КонецЕсли; Если Тип_ЗначениеОтбора = Тип("Массив") Тогда ЗначениеОтбора = Новый СписокЗначений; ЗначениеОтбора.ЗагрузитьЗначения(КлючИЗначение.Значение); КонецЕсли; ЭлОтбора.Значение = ЗначениеОтбора; КонецЕсли; КонецЦикла; Запрос = ПостроительЗапроса.ПолучитьЗапрос(); Возврат Запрос; КонецФункции | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |