Не провоцируйте СКД, или пример "как не надо"

Пример того, что не нужно использовать в запросах, чтобы не провоцировать СКД.

В данной заметке разберём конкретный пример конструкции, которую лучше не использовать в запросах, чтобы не удивляться результату СКД.

 

СКД — это волшебная система. Каждый раз удивляемся, сколько можно сэкономить времени, с умом используя её возможности. Однако, как известно, есть у неё и разные «особенности». И их тоже лучше знать.

 

Возьмём, к примеру, такую ситуацию.

ВЫБРАТЬ
    Валюты.Ссылка КАК Ссылка,
    Валюты.Наименование КАК Наименование,
    Валюты.Код КАК Код,
    Валюты.Наименование = "" ИЛИ Валюты.Код = "" КАК ОшибкаЗаполнения
ИЗ
    Справочник.Валюты КАК Валюты

 

Есть справочник с наименованием и кодом. Мы хотим вывести его элементы. И по каждому выводим колонку «ОшибкаЗаполнения» (булево). Колонка будет содержать значение Истина, когда Наименование или Код пустое.

Результат выполнения:

Вроде всё хорошо. Но предположим, что нам нужно теперь в полученном отчёте вывести только те записи, у которых «Ошибка заполнения» = Нет.

Накладываем отбор и выводим:

Неожиданный результат, верно?

 

Но для начала на таком простом запросе лучше самому попробовать добавить условие отбора. Не будем сейчас соревноваться в красоте запроса, а просто представим себя на месте СКД. Как бы она подставила наш отбор «Ошибка заполнения» = Нет?

 

  1. Выносим поле в секцию ГДЕ:
    ГДЕ Валюты.Наименование = "" ИЛИ Валюты.Код = ""

  2. Оборачиваем в скобки:
    ГДЕ (Валюты.Наименование = "" ИЛИ Валюты.Код = "")

  3. Сравниваем с значением отбора:
    ГДЕ (Валюты.Наименование = "" ИЛИ Валюты.Код = "") = ЛОЖЬ

 

Получаем такой текст запроса. Это то, чего мы ожидаем увидеть от СКД.

 

ВЫБРАТЬ
    Валюты.Наименование КАК Наименование,
    Валюты.Код КАК Код,
    Валюты.Наименование = "" ИЛИ Валюты.Код = "" КАК ОшибкаЗаполнения
ИЗ
    Справочник.Валюты КАК Валюты
ГДЕ
    (Валюты.Наименование = "" ИЛИ Валюты.Код = "") = ЛОЖЬ

Теперь же нам нужно отловить «реальный» текст запроса. Для этого добавляем в наш отчёт кусочек примитивного кода:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

КомпоновщикМакета   = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки     = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки());
НаборДанных         = МакетКомпоновки.НаборыДанных.Получить(0);

КонецПроцедуры

 

Ставим точку останова в конце процедуры, запускаем отладчик, переоткрываем отчёт и снова формируем его с наложенным отбором «Ошибка заполнения» = Нет

 

В результате в переменной НаборДанных можно увидеть свойство «Запрос».

Мы для наглядности в самом тексте запроса заменили автоматически генерируемый параметр на его значение, которое можно увидеть в переменной МакетКомпоновки.ЗначенияПараметров.

ВЫБРАТЬ
    Валюты.Наименование КАК Наименование,
    Валюты.Код КАК Код,
    Валюты.Наименование = "" ИЛИ Валюты.Код = "" КАК ОшибкаЗаполнения
ИЗ
    Справочник.Валюты КАК Валюты
ГДЕ
    (Валюты.Наименование = "" ИЛИ Валюты.Код = "" = ЛОЖЬ)

В чём ошибка?

 

Если вернуться к нашим шагам наложения условия, можно понять, что СКД пропустила шаг 2.

 

  1. Выносим поле в секцию ГДЕ:
    ГДЕ Валюты.Наименование = "" ИЛИ Валюты.Код = ""

  2. Оборачиваем в скобки:
    ГДЕ (Валюты.Наименование = "" ИЛИ Валюты.Код = "")

  3. Сравниваем с значением отбора:
    ГДЕ (Валюты.Наименование = "" ИЛИ Валюты.Код = "") = ЛОЖЬ

 

Выходит, что логика СКД была такая:

 

  1. Выносим поле в секцию ГДЕ:
    ГДЕ Валюты.Наименование = "" ИЛИ Валюты.Код = ""

  2. Сравниваем с значением отбора:
    ГДЕ Валюты.Наименование = "" ИЛИ Валюты.Код = "" = ЛОЖЬ

 

Однако, без оборачивания в скобки, СКД полностью меняет смысл условия. В результате мы и видим такой результат. В поле формула отрабатывает нормально, но вот фильтрация работает неверно.

Интересно, что если данное поле убрать из запроса и вынести в вычисляемые поля СКД, то такой ошибки не будет.

 

 

 

Но что, если вынести поле в вычисляемые для нас не выход? Всё просто, применяем другую конструкцию и вместо:

Валюты.Наименование = ""
ИЛИ Валюты.Код = "" КАК ОшибкаЗаполнения

пишем

ВЫБОР
   КОГДА Валюты.Наименование = "" ИЛИ Валюты.Код = ""
        ТОГДА ИСТИНА
   ИНАЧЕ ЛОЖЬ
КОНЕЦ КАК ОшибкаЗаполнения

Не так красиво, но зато теперь СКД точно не накосячит, ведь просто подставит сравнение к концу поля.

Возможно, Вам больше понравится иначе изменить условие запроса, но в данный момент это не принципиально. Главное, при написании подобных запросов помнить про эту «особенность». Ведь лучше не провоцировать СКД.

 

Замечено давненько. Но сейчас протестировано на платформах: 8.3.12.1595, 8.3.14.1779.

86 Comments

  1. VmvLer

    Я не понял где косячит СКД, как-то сумбурно написано.

    Условия в тесте статьи сами по себе кривоваты, да и использование

    ИЛИ в условиях я видел только в типовом коде современных конфигураций.

    Если запрос пишет человек с опытом, то никаких ИЛИ в запросе не будет.

    Reply
  2. VmvLer

    Логически верным будет выражение поля

        ВЫБОР
    КОГДА Валюты.Наименование = «»
    ТОГДА ИСТИНА
    КОГДА Валюты.Код = «»
    ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ОшибкаЗаполнения
    

    т.к. первое условие выбора наиболее вероятно

    я не знаю кому приходит в голову такое выражение поля

    Валюты.Наименование = «» ИЛИ Валюты.Код = «» КАК ОшибкаЗаполнения

    ЗЫ: неполадка из ничего, никто так выражение поля не пишет — вы первый у кого я увидел такой нонсенс.

    СКД права, что дала по рукам.

    Reply
  3. SeiOkami

    (1) это простейший пример того, когда СКД неверно накладывает отбор на поле.

    Приемлимость использования в запросах приставки ИЛИ — это другой вопрос. Но однозначно СКД должна корректно накладывать отбор, несмотря на религиозные предпочтения разработчика.

    Reply
  4. SeiOkami

    (2) СКД не дала по рукам, а сломала запрос. Вы пытаетесь похвастаться праведностью своих запросов, а не вникать в суть проблемы.

    Reply
  5. Wern03

    Причем тут ИЛИ. С тем же успехом можно поставить И и будет та же ошибка. Ошибка интересная, спасибо. возьму на заметку.

    Reply
  6. echo77

    (0)Похоже на баг компоновщика макета СКД. В 1С уже написали?

    Reply
  7. Mortum

    Если не ошибаюсь, то возможность писать такое условие в выбранных полях появилось в платформе не сразу. А в скд просто забыли этот случай обработать.

    Reply
  8. Mortum

    (2) писать 7 строк вместо одной с точно таким же смыслом. Вам платят за объём кода?

    Reply
  9. qwinter

    (9), (4) такой документированной возможности не было и нет. Логические операции нельзя использовать в выражениях. В документации черным по белому написано:

    Во многих конструкциях языка запросов могут использоваться выражения. Выражения языка запросов описываются следующим набором правил:

    <Выражение>

    <Разыменование поля> |

    <Агрегатная функция> |

    <Встроенная функция> |

    <Операция выбора> |

    <Приведение типа>[.<Разыменование поля>] |

    <Значение> |

    <Выражение> <Бинарная операция> <Выражение> |

    <Унарная операция> <Выражение> |

    ( <Выражение> )

    <Бинарная операция>

    + | — | * | /

    <Унарная операция>

    — | +

    Показать

    https://its.1c.ru/db/v8310doc#bookmark:dev:TI000000494

    Когда же 1Сники начнут ну хоть немного документацию читать.

    Reply
  10. SeiOkami

    (11)

    В выражениях к значениям соответствующих типов могут применяться бинарные и унарные операции.

    Не вижу ни противоречий, ни запретов использования конструкции, ни предупреждений, что СКД их сломает. При этом в вычисляемых полях они обрабатываются без проблем.

    P.S.: Эта статья как раз и нужна для того, чтобы показать конструкцию, которую «не надо». Именно потому, что среднестатистический разработчик нигде не видел такого предупреждения, посему может наткнуться на особенность СКД уже в проде.

    Reply
  11. qwinter

    (12)

    ни запретов использования конструкции

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

    ни предупреждений

    предупреждение, что недокументированное использование функций будет отрабатывать неверно??? Вы сейчас серьезно?????? С таким подходом только к врачу… Очень жаль ваших клиентов.

    Reply
  12. SeiOkami

    (13) вы пытаетесь привязаться к бумажкам, я же говорю, что обычному разработчику эта конструкция не покажется чем-то неизведанным и недокументированным. Простые логические операции. И программист может их использовать, не подозревая, что это приведёт к ошибке СКД. Мне, как автору статьи, важно донести эту особенность, а не решать, кто виноват.

    Reply
  13. Lucifer93

    Автор, тут дело в том, что Вы показываете пример плохого кода и говорите, что СКД его неправильно обработала. Для того, чтобы демонстрировать ошибку СКД покажите пример хорошего кода, который СКД обработает неправильно и не будет никаких вопросов к Вам. Ждем от Вас пример хорошего кода, который СКД отработает неправильно.

    Reply
  14. SeiOkami

    (14) независимо от оптимизированности запроса, СКД совершает ошибку. Читатель о ней теперь ознакомлен, и лишний раз подумает, прежде чем использовать конструкцию. У меня нет цели «заваливать» СКД.

    Reply
  15. Lucifer93

    (16) «независимо от оптимизированности запроса» Вот эта фраза очень интересная у Вас получается. То есть давайте писать кривые запросы, а потом жаловаться, что программа не так их понимает?!

    Reply
  16. SeiOkami

    (17) если писать неоптимальные запросы, и ожидать, что будет работать неоптимально

    Но здесь СКД совершает грубейшую ошибку. И это уж точно никто не ожидает.

    Reply
  17. SeiOkami

    (19)вы приводите странный пример. Запрос вполне ясный. Возможно, он не так оптимизирован (хотя это максимально спорное утверждение). Но он верен и очевиден. И в статье расписано, как должен накладываться отбор. Более того, СКД сама его так и накладывает, когда используются вычисляемые поля. Но с тем же самым полем косячит, когда он в запросе. Очевидно, что это ошибка. И очевидно, что это нужно знать при разработке. Иначе можно напороться. И уже не важно будет, кто здесь виноват

    Reply
  18. milanse

    Спасибо, хорошее замечание к работе СКД.

    Те кто говорят про или в условиях, вообще ничего не понимают?

    Reply
  19. Evil Beaver

    (11)

    Когда же 1Сники начнут ну хоть немного документацию читать

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

    Reply
  20. dhurricane

    (20)

    Но он верен

    Коллега, именно к этой фразе у Ваших оппонентов претензия. Он не неоптимизирован, он именно не верен с точки зрения документации к платформе. По приведенной ссылке явно указано, какие операции и над какими операндами можно выполнять в полях выборки. Сложение, вычитание и прочие арифметические операции, например, в этом списке есть, а вот логических — нет. Поэтому и следует делать вывод, что использование операции «ИЛИ» в поле выборки запроса без оператор «ВЫБОР» недопустимо.

    (11) Честно говоря, для меня также стало открытием, что использовать логические операторы в таком виде в секции «ВЫБРАТЬ» недопустимо. Я перечитал соответствующие разделы документации и для платформы 8.3.10, и для 8.3.14, и нигде не смог найти «разрешение» на использование оператора «ИЛИ». Почему открытие? Потому, что я хорошо помню, что где-то видел это самое «разрешение». И копнув глубже нашел его в списке изменений платформы 8.3.6:

    Реализована возможность использования логических выражений в описании поля выборки и в выражениях фильтрации результатов запроса (предложение ГДЕ).

    Данная возможность не предоставлялась.

    При необходимости использования логического выражения в описании поля выборки было необходимо использовать операцию выбора.

    Источник: https://dl03.1c.ru/content/Platform/8_3_14_1779/1cv8upd_8_3_14_1779.htm#b1d73456-26c0-11e4-98ab-e61f135f174b

    Далее идут ссылки на ИТС, где должно быть более подробно описано изменение, но ничего подобного в тексте узнать не удалось.

    Так что для меня теперь это открытый вопрос. Что это: ошибка в документации или неверная интерпретация нововведений в платформе?

    Reply
  21. dhurricane

    (24) Запрета нет. Но приведен список операций, называемых бинарными.

    Reply
  22. Lucifer93

    (21) Боюсь, что Вам нужно перечитать правила формирования запросов. Они отлично описаны в Настольная книга 1С:Эксперта по технологическим вопросам. 2 издание и там понятным языком объясняется почему использование ИЛИ в запросах является плохим.

    Reply
  23. d4rkmesa

    Вот хохма, набежали свидетели «святого СКД». Сам не использую подобные конструкции, но тут очевидно, что СКД работает не совсем ожидаемым образом, скажем так — не самым очевидным. Впрочем, в консоли СКД результирующий запрос смотрится и исправить можно довольно быстро.

    Reply
  24. toypaul

    Все каменты про — «пиши запросы правильно», «читай документацию» вроде как и верные, но к сути вопроса не имеют никакого отношения. суть вопроса в том, что в платформе косяк. нельзя писать ИЛИ — не давай писать. если даешь писать, обрабатывай правильно.

    книга про эксперта в ДАННОМ КОНКРЕТНОМ СЛУЧАЕ вообще не к месту упомянута. давайте будем везде запрещать писать ИЛИ — даже в справочниках где пара десятков записей. бред какой-то.

    Reply
  25. d4rkmesa

    (26) Хватит бредить уже.

    Reply
  26. srub

    У меня тоже есть пример, когда СКД отрабатывает не корректно есть запрос

    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | РасчетыСЗаказчикамиОбороты.Организация,
    | РасчетыСЗаказчикамиОбороты.Заказчик,
    | РасчетыСЗаказчикамиОбороты.Менеджер,
    | РасчетыСЗаказчикамиОбороты.Гаражка КАК Гаражка,
    | СУММА(ЕСТЬNULL(РасчетыСЗаказчикамиОбороты.СуммаПриход, 0)) КАК ПоступлениеОтЗаказчика,
    | СУММА(ЕСТЬNULL(РасчетыСЗаказчикамиОбороты.СуммаРасход, 0)) КАК РасходПоЗаказчику
    |ПОМЕСТИТЬ ВТ1
    |ИЗ
    | РегистрНакопления.РасчетыСЗаказчиками.Обороты(&ДатаНачала, &ДатаОкончания, , ) КАК РасчетыСЗаказчикамиОбороты
    |
    |СГРУППИРОВАТЬ ПО
    | РасчетыСЗаказчикамиОбороты.Организация,
    | РасчетыСЗаказчикамиОбороты.Заказчик,
    | РасчетыСЗаказчикамиОбороты.Менеджер,
    | РасчетыСЗаказчикамиОбороты.Гаражка
    |
    |ИНДЕКСИРОВАТЬ ПО
    | Гаражка
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | РасчетыСПеревозчикамиОбороты.Организация,
    | РасчетыСПеревозчикамиОбороты.Перевозчик,
    | РасчетыСПеревозчикамиОбороты.Гаражка КАК Гаражка,
    | РасчетыСПеревозчикамиОбороты.Менеджер,
    | СУММА(ЕСТЬNULL(РасчетыСПеревозчикамиОбороты.СуммаРасход, 0)) КАК ОплатаПеревозчику,
    | СУММА(ЕСТЬNULL(РасчетыСПеревозчикамиОбороты.СуммаПриход, 0)) КАК ПриходПоПеревозчику
    |ПОМЕСТИТЬ ВТ2
    |ИЗ
    | РегистрНакопления.РасчетыСПеревозчиками.Обороты КАК РасчетыСПеревозчикамиОбороты
    |
    |СГРУППИРОВАТЬ ПО
    | РасчетыСПеревозчикамиОбороты.Организация,
    | РасчетыСПеревозчикамиОбороты.Перевозчик,
    | РасчетыСПеревозчикамиОбороты.Гаражка,
    | РасчетыСПеревозчикамиОбороты.Менеджер
    |
    |ИНДЕКСИРОВАТЬ ПО
    | Гаражка
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | ВТ1.Организация КАК Организация,
    | ВТ1.Заказчик,
    | ВТ1.Гаражка.СтавкаСЗаказчиком КАК СтавкаСЗаказчиком,
    | ВТ1.Гаражка.СрокОплатыОтЗаказчиком КАК СрокОплатыЗаказчиком,
    | ВТ2.Перевозчик,
    | ВТ1.Гаражка.СтавкаСПеревозчиком КАК СтавкаСПеревозчиком,
    | ВТ1.Гаражка.СрокОплатыПеревозчику КАК СрокОплатыПеревозчику,
    | ВТ1.Менеджер,
    | ВТ1.Гаражка КАК Гаражка,
    | ВТ1.ПоступлениеОтЗаказчика,
    | ВТ2.ОплатаПеревозчику,
    | ВТ1.ПоступлениеОтЗаказчика — ВТ2.ОплатаПеревозчику КАК ОплаченоИзСвоих,
    | ВТ1.Гаражка.СтавкаСЗаказчиком — ВТ1.ПоступлениеОтЗаказчика КАК ДолгЗаказчика
    |ИЗ
    | ВТ1 КАК ВТ1
    |  ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ2
    |  ПО ВТ1.Гаражка = ВТ2.Гаражка
    |ГДЕ
    | ВТ1.ПоступлениеОтЗаказчика < ВТ2.ОплатаПеревозчику
    |
    |УПОРЯДОЧИТЬ ПО
    | Организация,
    | Гаражка»;
    

    Показать

    В консоли запросов за выбранный период 36 записей. А СКД выдает 6 записей.

    Reply
  27. milanse

    (26) Не надо бояться, надо делать. Второе издание не читал, первое лежало на краю стола, не успел прочитать, кто-то упер. Буду благодарен за скриншот выделенного жирным шрифтом обведенного в рамочку предупреждения «НИКОГДА, СЛЫШИТЕ НИКОГДА НЕ ИСПОЛЬЗУЙТЕ СЛОВО ИЛИ В ЗАПРОСАХ».

    Reply
  28. sergathome

    (27) тоже поржал. логика у ребят потрясающая — есть куча дерьма на лестнице в подъезде, на чердаке которого написано, что она там лежит и по лестнице не нужно ходить, хотя она есть… шиза, да и только. угага

    Reply
  29. sergathome

    (28) это типичный ФМГ от долгого чтения 1Сной «документации». Простите, но без кавычек оно не работает. Тут целая секта таких фимозников обитает…

    Reply
  30. unichkin

    (30) не понял, а зачем группировка и выражение isNULL в первых двух запросах? Это ж оборотные таблицы. В выходном запросе почему условие в секции где, а не в соединении?

    Почему-то никто не вспоминает про расширение языка запросов для системы компоновки данных, а ведь именно им управляются отборы.

    Запрос из статьи можно (нужно) описать так:

    ВЫБРАТЬ

    Валюты.Ссылка КАК Ссылка,

    Валюты.Наименование КАК Наименование,

    Валюты.Код КАК Код,

    Валюты.Наименование = «»

    ИЛИ Валюты.Код = «» КАК ОшибкаЗаполнения

    ИЗ

    Справочник.Валюты КАК Валюты

    {ГДЕ

    (Валюты.Наименование = «»

    ИЛИ Валюты.Код = «») КАК ОшибкаЗаполнения}

    Тогда в результате наложения отбора СКД вернет

    ВЫБРАТЬ

    Валюты.Наименование КАК Наименование,

    Валюты.Код КАК Код,

    Валюты.Наименование = «»

    ИЛИ Валюты.Код = «» КАК ОшибкаЗаполнения

    ИЗ

    Справочник.Валюты КАК Валюты

    ГДЕ

    (Валюты.Наименование = «»

    ИЛИ Валюты.Код = «») = &П

    ___

    Хочется здесь добавить — СКД классная штука, но как пользователю нужно понимать что программист лишь автоматизирует его труд, а не создает волшебные кнопки, так и программистам надо понимать что есть инструмент со своей спецификой, который как и многие другие инструменты не умеет вообще ВСЕ.

    Reply
  31. Lucifer93

    (29)Отличный комментарий и ,главное, по делу и аргументированный.

    Reply
  32. Lucifer93

    (31) «В секции ГДЕ логическое ИЛИ использовать тоже не рекомендуется. Следует разбить один запрос на несколько и объединить результаты (при возникновении проблем на данном участке кода). Пояснения — в этой же главе ниже.» Вот цитата, которая сохранена у нас для разработчиков, чтобы они не делали глупых ошибок.

    Reply
  33. SeiOkami

    (36) откройте любую типовую и тыкайте пальцем в каждое использование ИЛИ в секции ГДЕ.

    Можно быть «сферическим идеальным программистом в вакууме», а можно с умом использовать все возможности языка.

    Reply
  34. sergathome

    (35) Первое реальное возражение. Да, ***, да, язык СКД ОТЛИЧАЕТСЯ от языка запросов ! В «документации » это звучит абсолютно невнятно и неудивительно, что возникают секты на этой почве. бгы

    Reply
  35. Lucifer93

    (38) Так в данном случае Вы не используете их с умом. Вы просто пишите ерунду, которую Вам уже правили в постах выше. Я изначально попросил Вас написать качественно и найти ошибку. Никто не говорит, что СКД святая, я говорю Вам напишите запрос ПРАВИЛЬНО и тогда ошибка исчезнет. Вся статья, по сути, не будет иметь никакого смысла, если разработчик будь следовать элементарным правилам написания запроса(на данном этапе). Сделайте нормальный запрос, повторите ошибку и не будет к Вам вопросов.

    Возможности языка нужно использовать правильно, а не как Вам захотелось. Вы пытаетесь отверткой забить гвоздь

    Reply
  36. VmvLer

    (38) Дело не в ИЛИ или И.

    То что я написал в начале темы детализировано в (34)

    хватит бредить(с)

    Reply
  37. SlavaKron

    (23) Судя по всему, 1С автоматически переделывает логические выражения в секции ВЫБРАТЬ в CASE структуру, потому что, например, в T-SQL нельзя использовать булево в выборке – оно не является типом данных.

    Reply
  38. qwinter

    (23)

    Так что для меня теперь это открытый вопрос. Что это: ошибка в документации или неверная интерпретация нововведений в платформе?

    Нет никакого противоречия, логическое выражение это

    В языке запросов в операциях выбора и в условиях отборов используются логические выражения.

    <Логическое выражение>

    <Выражение> |

    (<Выражение> | <Логическое выражение>) <Операция сравнения> (<Выражение> | <Логическое выражение>) |

    <Выражение> [НЕ] В [ИЕРАРХИИ] (<Список значений>) |

    <Выражение> [НЕ] В [ИЕРАРХИИ](<Описание запроса>) |

    <Выражение> [НЕ] МЕЖДУ <Выражение> И <Выражение> |

    <Выражение> ЕСТЬ [НЕ] NULL |

    <Выражение> ССЫЛКА <Имя таблицы> |

    <Выражение> [НЕ] ПОДОБНО <Литерал типа СТРОКА>

    [СПЕЦСИМВОЛ <Литерал типа СТРОКА>]

    <Операция сравнения>

    > | < | = | >= | <= | <>

    <Список значений>

    <Выражение>[, <Выражение> [, …]]

    Логическим выражением может быть:

    ● обычное выражение языка запросов, если его результат имеет логический тип;

    ● операция сравнения двух выражений языка запросов; выполняется в соответствии с правилами сравнения значений, описанными в разделе «Правила сравнения значений»;

    ● оператор проверки совпадения/несовпадения значения выражения с одним из перечисленных или со значениями, содержащимися в результате другого запроса;

    ● оператор проверки вхождения значения выражения в диапазон;

    ● оператор проверки значения выражения на NULL;

    ● оператор проверки ссылочного значения выражения на ссылку на определенную таблицу;

    ● оператор проверки строкового значения наподобие шаблону.

    При сравнении значений используются правила сравнения значений, описанные ниже.

    Показать

    https://its.1c.ru/db/v8310doc#bookmark:dev:TI000000500

    Разрешения на использования логических операторов языка запросов в выражениях там нет.

    Reply
  39. milanse

    Уже предлагали зарегистрировать баг ?

    Reply
  40. pm74
    Валюты.Наименование = «» ИЛИ Валюты.Код = «»

    = НЕ (НЕ Список.Наименование = «» И НЕ Список.Код = «»)

    Reply
  41. Evil Beaver

    (43) вот что вас так тянет язвить-то, а? Ведь специально для Вас написал, что знаю про то, что в грамматике И и ИЛИ названы отдельно. Нет, все равно вы мне тыркаете, что я ссылку не читал.. Я вообще-то промышленный парсер под язык запросов писал, и почти каждую продукцию грамматики помню безо всяких ссылок на ИТС. Будьте вежливее, пожалуйста.

    Reply
  42. bulpi

    Критики этой статьи до боли напоминают мне работников техподдержки 1с (не только 1с, но мы сейчас здесь). Ты , значит, поработал для них бесплатным бета-тестером, нашел очевиднейший баг, не пожалел времени, задокументировал, пример написал, разжевал как для идиотов, написал туда … ИИИИ…. тебе отвечают, что ты сам дурак и читай документацию. Я вот так и бросил писАть в техподдержку.

    Люди, вы, блин, издеваетесь ? Если НЕЛЬЗЯ такое писАть в СКД, то нужно об этом выдавать диагностику на этапе перехода от текста запроса к полям. «Недопустимое логическое выражение в условии …» , как то так.

    Reply
  43. surikateg

    (35)

    В СП написано:

    При автоматическом заполнении доступных полей запроса выполняются следующие действия:

    все поля списка выборки и их дочерние поля становятся доступными для выбора, упорядочивания, группировки, отбора и др.;

    Как программист должен догадаться о создании дополнительной конструкции ГДЕ в расширении языка запросов СКД?

    Reply
  44. milanse

    Какой ужас, что же мы видим в центре внимания на главной странице инофостарта https://infostart.ru/public/1074066/ в перовом примере кода используется условие «или», а во втором выражение, которое может поломаться в СКД. Куда же смотрят тру программисты 1с, которые изучили настольные книги экспертов по технологическим вопросам ? Не время спать, 1с в опасности

    Reply
  45. unichkin

    (50) Нажать «F1» и прочитать про язык расширений компоновки? Навскидку — еще можно поизучать типовые, посмотреть курсы, почитать книги… Суть-то не в СКД. Развиваться надо. Писать много кода, стараться делать это правильно (ИТС имею в виду, хоть обкидайтесь помидорами). Гугл + ИТС + здравый смысл в помощь.

    Reply
  46. GreenDragon

    (38) А, так у вас эталоном являются типовые? Офигеть! Мы тут им баги репортим, а оно вон как! Вам написал уже не один человек про крайнюю нежелательность использования логического оператора «ИЛИ» в секции условий.

    Reply
  47. GreenDragon

    (48) Тут просто автор заявляет, что

    …Важно понимать, что целью статьи не является классифицировать те или иные конструкции как «документированными» или же нет.

    И не решать, что использовать «хорошо», а что «плохо».

    А лишь показать пример, как реагирует СКД на данный вид конструкций.

    И при этом использует «ИЛИ» в секции условий. На не рекомендуемый вид конструкций СКД реагирует плохо. Вот прям в первом комментарии об этом написано, а потом ещё с десяток подобных комментариев, но автор упоролся упёрся и настаивает, вот все и нервничают, повышая градус неадекватности.

    Reply
  48. surikateg

    (52)

    Я как раз и процитировал что по F1 написано. В каких курсах или книгах есть полное описание расширения языка запросов СКД? Гугл не 1с. Оптимальность кода это другой вопрос, синтаксис запроса корректен для платформы, он должен выполнятся правильно.

    Reply
  49. unichkin

    (55)

    Я как раз и процитировал что по F1 написано. В каких курсах или книгах есть полное описание расширения языка запросов СКД? Гугл не 1с. Оптимальность кода это другой вопрос, синтаксис запроса корректен для платформы, он должен выполнятся правильно.

    В (50) вы утверждаете что это из СП. ctrl + shift + F1, если что. Полного — подозреваю, что ни в каких. Просто с опытом приходит понимание того, что такое СКД, и как с ним жить. И можно хоть 1000 статей написать на тему «вот так не работает!!», я как-то более практично привык смотреть на эту проблему. Хотя тоже много глючков переловил. Мир не идеален) Максимум что можно сделать — попробовать зарегистрировать багу через поддержку.

    По поводу синтаксиса — я бы вот не разделял понятия «синтаксис» и «оптимальность». Я бы объединил: все надо делать максимально просто, быстро и понятно. Попробуйте переписать ваш запрос, и посмотрите поймет ли его СКД после этого. Я понятия не имею чего там у платформы в мозгах, но подозреваю что писатели парсеров ориентировались на корректный входящий запрос, а не на то что их будут ловить подводными камнями.

    Reply
  50. alex5550
    Если НЕЛЬЗЯ такое писАть в СКД, то нужно об этом выдавать диагностику

    Золотые слова…

    Reply
  51. surikateg

    (56) В 1с и так язык запросов типа «sql» обрезан по самое не балуйся и давно уже не расширяется, в чем сложность написать нормальный парсер для СКД?

    Reply
  52. VmvLer

    (49) (51)… вброшу еще на вентилятор

    Да забудьте вы про красную тряпку «ИЛИ» — оно тут не виновно и речь о нем шла в контексте. Еще раз суть:

    «Недопустимое логическое выражение в условии …»

    не надо нас, маленьких дурить, меняя контекст неполадки!

    в условии как раз допустимо выражение без КАК

    Валюты.Наименование = «» ИЛИ Валюты.Код = «» КАК ОшибкаЗаполнения
    

    а вот в выражении поля вместо логического выражения необходимо использовать

    Выбор …Когда.

    Это как таблица умножения и если вы забыли ИЛИ НЕ знали, что 2*2 = 4, то

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

    Reply
  53. unichkin

    (58) Это я думаю к техподдержке вопрос) Однако мне как программисту остается жить с тем, что есть.

    Reply
  54. triviumfan

    Давно натыкался на сие поведение, ошибке уже 100500 лет.

    Reply
  55. Evil Beaver

    (54) Как у вас всех так получается читать объяснения автора и в упор их не понимать…? Почему вы противопоставлете друг-другу тезисы «показать пример, как СКД реагирует» и «нельзя использовать ИЛИ»?? Это же несвязанные между собой вещи. Использование ИЛИ — иногда(!) ведет к плохому плану выполнения запроса. НО — операция ИЛИ это синтаксически корректная конструкция, ее в принципе можно применять.

    Далее, автор пишет, что можно написать вместо ИЛИ просто «И» и будет все равно ошибка. Никто это в упор не видит и начинает втирать, что ИЛИ неоптимально. Да, неоптимально. Но речь-то не об этом! Речь о том, что СКД, накладывая условие на поле, накладывает его не совсем ожидаемым образом.

    И да, это даже не ошибка СКД, в ее действиях есть логика, а для таких вещей надо применять вычисляемые поля или иные способы обхода (там же в статье).

    Но почему-то все считают, что корень всех бед статьи и ее автора — применение ИЛИ…

    Reply
  56. Sashares

    (11)

    такой документированной возможности не было и нет. Логические операции нельзя использовать в выражениях

    Можно с 8.3.6.

    (11)

    Когда же 1Сники начнут ну хоть немного документацию читать.

    Действительно. Когда же начнут?

    (1) А вот то что СКД не корректно воспринимает условие, в дополнение к статье стоило бы написать на v8@1c.ru

    Reply
  57. Sashares

    (62)

    И да, это даже не ошибка СКД, в ее действиях есть логика

    Нет в ней логики.

    Отбор накладывается по полю, а не по части поля.

    Почему СКД не знает о возможности использования логических выражениях в качестве полей, вопросы к Лейбовичу =)

    Reply
  58. GreenDragon

    (62) Андрей, при всём моём уважении. Комментарий (14)

    Reply
  59. dhurricane

    (63)

    Можно с 8.3.6.

    Чуть ниже я писал про это. Мне дали ответ, что в документации в отношении логических операций также отсутствует разрешение на использование бинарных операций «И/ИЛИ». Почитал документацию, оспорить не смог, стало быть ответ справедливый.

    Reply
  60. GreenDragon

    (62) И ещё. Автор в конце как правильный рецепт предлагает вставлять инструкцию ВЫБОР. В секции ГДЕ. Угу. Дальше он предложит 2 раза в цикле запросы выполнять? Ненуачо, работает жи?

    Вопрос — если скормить условие вида: «НЕ (условие1 ИЛИ условие2)»?

    Reply
  61. Sashares

    (66)

    Мне дали ответ, что в документации в отношении логических операций также отсутствует разрешение на использование бинарных операций «И/ИЛИ».

    Ох уж эти знатоки. Все то они знают.

    https://its.1c.ru/db/v836doc#bookmark:dev:TI000000464

    Reply
  62. dhurricane

    (67) Не-не, там в пункте 8.2.17.1 дается определение «логической операции».

    Reply
  63. spacecraft

    (69) а если так?

    Reply
  64. dhurricane

    (70) Я описался комментарием выше. Речь была о «логических выражениях». На Вашем снимке, во-первых, речь про условия отбора, а не поля выборки. А во-вторых, в выделенном Вами тексте явно разделены понятия логического выражения и операторов «И/ИЛИ».

    Reply
  65. spacecraft

    (71) читаем: «В простейшем случае условие является выражением, результат которого имеет значение логического типа. Логические выражения описаны в следующем разделе.

    Условия могут определяться и как более сложные логические выражения, где фигурируют простые логические выражения, соединенные между собой с помощью логических операторов И, Или, Не.»

    Про поля выборки, то там тоже упоминаются логические выражения. Так что актуально и для них.

    Reply
  66. dhurricane

    (72) Извините, но не согласен. Условия — могут определяться и как более сложные логические выражения. Про поля выборки такое не сказано, следовательно определяться как более сложные, чем описано «в следующем разделе», они быть не могут.

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

    Reply
  67. spacecraft

    (73) хорошо. Далее:

    «Логическим выражением может быть:

    ● обычное выражение языка запросов, если его результат имеет логический тип»

    «Выражения языка запросов описываются следующим набором правил:

    <Разыменование поля> |

    <Агрегатная функция> |

    <Встроенная функция> |

    <Операция выбора> |

    <Приведение типа>[.<Разыменование поля>] |

    <Значение> |

    <Выражение> <Бинарная операция> <Выражение> |

    <Унарная операция> <Выражение> |

    ( <Выражение> )

    «

    Reply
  68. dhurricane

    (74) А чуть ниже список бинарных операций, среди которых нет «И/ИЛИ»:

    + | – | * | /
    Reply
  69. spacecraft

    (75) да, что-то не указано.

    Но все равно конструкция вида (<Логическое выражение> И <Логическое выражение>) это тоже логическое выражение.

    Reply
  70. dhurricane

    (76) Конечно согласен. Но к сожалению, лишь на интуитивном уровне. Попробую, наверное, на днях «пошерстить» партнерский форум в поисках ответа, либо задать вопрос самому. Вдруг я не «утону в минусах», да еще и получу разъяснения сотрудников 1С. 🙂

    Reply
  71. spacecraft

    (75) вот пример бинарной операции ИЛИ

    ВЫБРАТЬ
    ПриобретениеТоваровУслуг.Ссылка КАК Ссылка,
    ПриобретениеТоваровУслуг.Проведен
    И НЕ ПриобретениеТоваровУслуг.ПометкаУдаления КАК Актуально
    ИЗ
    Документ.ПриобретениеТоваровУслуг КАК ПриобретениеТоваровУслуг

    Вполне себе рабочая конструкция.

    Reply
  72. Evil Beaver

    (65) При всем моем уважении, комментарий 14 нелогичен. Плохой запрос или хороший в данном случае роли не играет. Речь о необычном поведении СКД при использовании необычных полей, и только. Система должна иметь понятный набор поведений независимо от качества запроса. В данном случае СКД ведет себя не так, как вела бы с полем «ВЫБОР».

    Навскидку, попробуйте провести эксперимент не с ИЛИ, а просто с арифметическим выражением, например

    ВЫБРАТЬ ПолеРегистра + 2 КАК НаДваБольше

    и условие на это поле наложить.

    СКД отработает нормально или нет?

    Reply
  73. dhurricane

    (78) Да, как я уже выше писал, сам использовал подобные конструкции, и осечек до сих пор не наблюдал.

    И простите за занудство, но Ваше выражение избыточно: документ не может быть одновременно проведен и помечен на удаление. Если, конечно, кто-то накануне не работал с БД напрямую.

    Reply
  74. Evil Beaver

    (68) ВЫБОР в секции ГДЕ — ни разу не криминал. В типовых — полно такого. Зависит не от оператора ВЫБОР, а от того, что у него внутри. Если поле составного типа — то да, будет трэш.

    Reply
  75. spacecraft

    (80) это всего лишь синтетический код для проверки работы бинарной операции ИЛИ. Ничего более.

    Reply
  76. dhurricane

    (82) Еще раз простите, что не сдержался. 🙂

    Reply
  77. spacecraft

    (80)

    документ не может быть одновременно проведен и помечен на удаление

    может 🙂

    «Если документ помечен на удаление, то не допускается выполнение проведения этого документа. Однако допускается наличие движений у документа, помеченного на удаление, так как в 1С:Предприятии 8 понятие проведенности документа не связано жестко с наличием движений.»

    Хотя это наверно не про флаг «Проведен».

    Reply
  78. dhurricane

    (79) Эксперимент показал, что СКД отработает ровно также, как и в примере автора поста, т.е. добавит выражение поля в отбор как есть, без скобок. Но здесь нам на руку играет больший приоритет операции сложения.

    Reply
  79. Evil Beaver

    (85) Спасибо! Что и требовалось доказать — оптимальность или неоптимальность запроса — это не то, что рассказывается в статье.

    Reply
  80. GreenDragon

    (81) А индексы используются при такой конструкции?

    Я про вот это:

    https://its.1c.ru/db/v8std#content:658:hdoc

    «Основное условие должно содержать только такие операции, которые позволяют выполнять поиск по индексу»

    Reply
  81. Evil Beaver

    (87) Могут и использоваться. Зависит от того, что конкретно написано в ВЫБОР и от состава индекса.

    Reply
  82. GreenDragon

    (88) У автора в секции ГДЕ используется вполне конкретное выражение. Автор использует оператор ВЫБОР в основном , а не в дополнительном условии Ниже скриншот, так я подозреваю, что вы не смотрели ссылку на стандарт.

    Reply
  83. dhurricane

    (89) Я позволю себе встрять в Ваш диалог, извините. Уж очень интересно, какое альтернативное решение предложили бы Вы?

    Reply
  84. Sashares

    (0)Для информации.

    В 8.3.16 исправили.

    Reply
  85. Deslime

    Поржала с комментов — прям Священная Война Свидетелей Нуралиева ))

    Спасибо автору за статью — интересное замечание к работе СКД и пример хороший так как максимально очевидно показывает данный нюанс

    Reply
  86. SlavaKron

    К черту скд. Товарщи, пишите кастомные отчеты.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *