Хитрости запросов: сравнения и проверки в запросах 1С. Отбор не заполненного значения. Отбор в запросе документов конкретного типа при составном типе и т.п. ( 1С: 8.1: Язык программирования: Запросы)

Вопрос Как в языке запросов 1С отобрать не заполненное значение? Какое условие указать в запросе после ключевого слова «ГДЕ», когда нужно сделать отбор по не заполненным полям?
Ответ См. примеры запросов и комментарии к ним:

    Запрос.Текст =
    "ВЫБРАТЬ 
    |    усЕдиницыХранения.Ссылка
    |ИЗ
    |    Справочник.усЕдиницыХранения КАК усЕдиницыХранения

    // Пример 1. сравнение с не заполненным булевым значением:
    |ГДЕ
    |     усЕдиницыХранения.РазрешитьОтборИзРезервнойЗоны = Ложь

    // Пример 2. но если это булево определено, то лучше так: // условие на отрицательное булево:
    |ГДЕ
    |     НЕ усЕдиницыХранения.РазрешитьОтборИзРезервнойЗоны

    // Пример 3. выборка по условию не заполненного поля, имеющего тип "справочник конкретного типа"
    |ГДЕ
    |    усЕдиницыХранения.АктивнаяОбластьОтбора = ЗНАЧЕНИЕ(Справочник.усОбластиОтбора.ПустаяСсылка)

    // Пример 3а. выборка по условию не заполненного поля, имеющего тип "документ конкретного типа"
    |ГДЕ
    |    НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент.ПустаяСсылка)

    // Пример 3б. выборка по условию не заполненного поля, имеющего тип "документы разных типов" (составное поле)
    |ГДЕ
    |    (НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент1.ПустаяСсылка)
    |    ИЛИ НашРегистрСведений.Документ = ЗНАЧЕНИЕ(Документ.НашДокумент2.ПустаяСсылка) 
    |    ИЛИ ...(и т.д. - последовательно перечисляем условия для всех возможных типов этого составного поля))
    
    // Пример 4. или наоборот, если нужно выбрать заполненное значение типа "строка", то поможет условие:
    |ГДЕ
    |    усЕдиницыХранения.Наименование > """"

    // Пример 5. если нужно выбрать документы конкретного типа, при составном типе данных, например в регистре "ВыполняемыеЗадания" ресурс "Задание" имеет составной тип, среди значений которого возможен документ "Отбор"
    |ГДЕ
    |    ВЫРАЗИТЬ(РегистрСведенийВыполняемыеЗадания.Задание КАК Документ.Отбор) ССЫЛКА Документ.Отбор

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


    // Пример 6. выбор по условию не определенного значения:
    |ГДЕ
    |    СохраненныеНастройки.Пользователь = НЕОПРЕДЕЛЕНО

    // Пример 7. выбор по виду движения "Приход" регистра накопления, "Расход" - аналогично):
    |ГДЕ
    |    РегТоварыВРознице.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)


    // Пример 8. Как в запросе указать, что выполнять запрос не нужно (например, 
нужно программно в зависимости от какого-то условия вернуть пустой результат запроса - Запрос.Текст = СтрЗаменить(Запрос.Текст, "ГДЕ Док.Ссылка = &ДокументСсылка", "ГДЕ ЛОЖЬ");). 
Для этого достаточно добавить условие "Где Ложь". 
Кстати, независимо от объема запрашиваемых в выборке данных, такой запрос будет выполнен мгновенно.
    |ГДЕ ЛОЖЬ

    // Пример 9. Проверка на то, что результат выполнения запроса содержит данные:
    Если НЕ Запрос.Выполнить().Пустой() Тогда

    // Пример 10. выбор по условию не заполненной даты:
    |ГДЕ
    |    тбСтроки.ДатаОтмены = ДАТАВРЕМЯ(1, 1, 1)

16 thoughts on “Хитрости запросов: сравнения и проверки в запросах 1С. Отбор не заполненного значения. Отбор в запросе документов конкретного типа при составном типе и т.п. ( 1С: 8.1: Язык программирования: Запросы)

  1. Если проверка на не заполненную строку (недавно у меня была задача отсечь) поэтому условие сработало
    |ГДЕ усЕдиницыХранения.АктивнаяОбластьОтбора > «»»»

    как-то так

  2. Если тип значения не известен, например Реквизит составного типа, или имеет тип Любая Ссылка?

  3. Составной тип можно проверить через конкатенацию: ИЛИ, ИЛИ, ИЛИ… перечисляя по очереди внутри конструкции ЗНАЧЕНИЕ(…) все допустимые типы. Про любую ссылку — надо подумать. Есть идеи?

  4. Т.е. указываем
    |ГДЕ
    | усЕдиницыХранения.АктивнаяОбластьОтбора = ЗНАЧЕНИЕ(Справочник.усОбластиОтбора.ПустаяСсылка)
    | ИЛИ усЕдиницыХранения.АктивнаяОбластьОтбора = ЗНАЧЕНИЕ(Справочник.усДругойСправочник.ПустаяСсылка)»;

    А как указать, если тип в этом реквизите совсем не задан (не выбирался, и равен Неопределено)? ЕСТЬ NULL не прокатывает..

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

    или такого:
    |ГДЕ
    | И СохраненныеНастройки.Пользователь = НЕОПРЕДЕЛЕНО

    Т.е. условие зависит от того, что именно все-таки нужно.

  6. Добавлен Пример 5. если нужно выбрать документы конкретного типа, при составном типе данных, например в регистре «ВыполняемыеЗадания» ресурс «Задание» имеет составной тип, среди значений которого возможен документ «Отбор»

  7. Я использовал такое выражение, для выборки строк, где не заполнен реквизит Документ. Этот реквизит составного типа.

    ГДЕ
    (НЕ РегистрСведений.ИмяРегистра.Документ ЕСТЬ NULL)

    • Baduin, для проверки на незаполнненное поле типа «документ» подходят примеры 3а и 3б, т.е. Вы ошибаетесь, условие «ЕСТЬ NULL» не подходит для проверки на то, что значение просто не заполнено.
      «ЕСТЬ NULL» подойдет только в двух случаях:
      1. Этим условием проверяется наличие битой ссылки (см. http://www.1c-h.ru/?p=935)
      2. Значением NULL заполняются поля присоединяемых в запросе таблиц, когда по условию соединения запроса отсутствуют подходящие значения.

      Вероятно, у вас выполняется соединение в запросе? Что-то вроде этого:


      РегистрСведений.Документ,

      ИЗ …
      ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ИмяРегистра КАК РегистрСведений

      Суть «ЕСТЬ NULL» в том, что берутся строки, в которых по условию соединения нет подходящего Документа
      Т.е. предположим, есть две таблицы:

      Таблица1:

      Параметр1
      Х
      У
      Z

      И есть Таблица2:

      Параметр2 Документ
      Х Док1
      Z Док2

      При левом присоединении Таблицы2 к Таблице1 по условию
      Параметр1 = Параметр2

      Получим строки

      Параметр Документ
      Х Док1
      У NULL
      Z Док2

      Т.е., как видите, для значения «У» Таблицы 1 не нашлось подходящего Документа. Теперь если выбрать из этой результирующей таблицы строки по условию, что Документ ЕСТЬ NULL, то получим таблицу:

      Параметр Документ
      У NULL

      А если выбрать по условию НЕ Документ ЕСТЬ NULL, то получим таблицу:

      Параметр Документ
      Х Док1
      Z Док2

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

  8. А зачем используется такая конструкция:

    ВЫРАЗИТЬ(РегистрСведенийВыполняемыеЗадания.Задание КАК Документ.Отбор) ССЫЛКА Документ.Отбор

    Я всегда пользовался:

    РегистрСведенийВыполняемыеЗадания.Задание ССЫЛКА Документ.Отбор

    И это великолепно работает. ВЫРАЗИТЬ тут в лучшем случае — не будет обрабатываться. В Худшем — создаст дополнительную ненужную нагрузку.
    Или от меня ускользнула некая непостижимая моему разумению житейская мудрость?

    • «ВЫРАЗИТЬ» используется во всех случаях, когда исходное значение может оказаться не того типа, который нужен, например, в указанном примере «Задание» — измерение составного типа и может содержать не только документы «Отбор», но и другие виды документов.

      См. так же http://www.1c-h.ru/?p=1553 или http://www.1c-h.ru/?p=89 — другие примеры применения(и обоснвания применения) метода «ВЫРАЗИТЬ».

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

  9. Решал вопрос с незаполненными полями в регистрах вот таким образом :

    Запрос.УстановитьПараметр(«ПустаяСсылка»,);

    ……………..
    ИмяРегистра.Ссылка = &ПустаяСсылка»
    ……………..

    Работает отлично, побочных эфектов пока не наблюдаю 🙂

    • Спасибо за комментарий!
      Один минус все же есть — в необходимости самой передачи параметра 🙂

Добавить комментарий

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