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

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

21

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

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

Требуется отобрать по условию, что у справочника усЕдиницыХранения реквизит РазрешитьОтборИзРезервнойЗоны пустой
Реквизит РазрешитьОтборИзРезервнойЗоны имеет тип булево
Вариант 1. сравнение с не заполненным булевым значением:

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

Вариант 2. Если это булево определено, то лучше так:

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

Требуется отобрать по условию, что у справочника усЕдиницыХранения реквизит АктивнаяОбластьОтбора пустой
Реквизит АктивнаяОбластьОтбора имеет тип Справочник.усОбластиОтбора

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

Требуется отобрать по условию, что у регистра сведений НашРегистрСведений реквизит Документ пустой
Реквизит Документ имеет тип Документ.НашДокумент1

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

Требуется отобрать по условию, что у регистра сведений НашРегистрСведений реквизит Документ пустой
Реквизит Документ имеет составной тип значения: Документ.НашДокумент1, Документ.НашДокумент2 и т.д.

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

Требуется отобрать по условию, что реквизит не пустой (заполнен хоть чем-то)
Тип значения реквизита — Строка.

    
    // Пример 4. или наоборот, если нужно выбрать заполненное значение типа "строка", то поможет условие:
    |ГДЕ
    |    усЕдиницыХранения.Наименование > """"

Допустим требуется отобрать данные, при условии, что реквизит Задание регистра сведений ВыполняемыеЗадания содержит какой-либо Документ.Отбор
Реквизит Задание имеет составной тип значения: Документ.Отбор, Документ.Поступление и т.д.

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

Еще аналогичный пример, когда нужно выбрать документы конкретного типа

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

Отобрать по условию не определенного значения:

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

Отобрать по условию, что вид движения — Приход

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

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

    // Пример 8. Не исполнять запрос:
    |ГДЕ ЛОЖЬ

Проверка на то, что результат выполнения запроса содержит данные:

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

Отобрать записи с не заполненной датой (реквизит ДатаОтмены имеет тип Дата)

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

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

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

    как-то так

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

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

    1. А еще можно использовать конструкцию вида

      НашРегистрСведений.Документ В(ЗНАЧЕНИЕ(Документ.НашДокумент1.ПустаяСсылка), ЗНАЧЕНИЕ(Документ.НашДокумент2.ПустаяСсылка), …)

      Привет из будущего 🙂

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

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

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

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

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

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

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

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

    1. 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. А зачем используется такая конструкция:

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

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

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

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

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

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

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

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

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

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

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

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

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

    За такой быдлокод сразу кол в дневник и линейкой по пальцам….
    Каждое ИЛИ создает неявное соединение таблиц. Дядя гугл детальней расскажет вам о данном косяке запросов в 1С.
    Альтернатива например:
    |ГДЕ
    | НашРегистрСведений.Документ В (ЗНАЧЕНИЕ(Документ.НашДокумент1.ПустаяСсылка), ЗНАЧЕНИЕ(Документ.НашДокумент2.ПустаяСсылка) , и т.д.)

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

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

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

Next Post

Установка 1С: Предприятие. Установка 1С:Предприятия 8 в варианте "клиент-сервер" (на SQLServer) (1С)

Вт Май 18 , 2010
Вопрос Как установить 1С: Предприятие в клиент-серверном варианте. Раздел содержит практические рекомендации по решению проблем, возникающих при установке и настройке клиент-серверного варианта 1С:Предприятия 8. При подготовке раздела учтен опыт партнеров и пользователей, которым в процессе установки 1С:Предприятия потребовалась дополнительная настройка различных служб Microsoft Windows. Более подробно с материалом можно ознакомиться […]