Книга знаний

1С:Предприятие / Приемы программирования / Запросы

Хитрое написание текстов запросов с необязательными условиями

Предположим в форме есть список товаров, если он заполнен, то нужно сформировать отчет только по
указанным товарам, иначе по всем. Как написать текст запроса в таком случае?
Автор статьи: Гений 1С | Редакторы: acsent, Neco, TormozIT, vhl, Flashback1979SE, SuperSpade, Asmody
Последняя редакция №17 от 15.06.17 | История
URL: http://kb.mista.ru/article.php?id=269

Ключевые слова: запрос,условие


В типовых конфигурациях обычно пишут так:

Если ВыбТовары.Количество()=0 Тогда
    Условие="";
Иначе
    Условие=" ГДЕ Товар в (&Товары)";
КонецЕсли;
Запрос.Текст="ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура "+Условие;


Я предлагаю писать более изящно:
Запрос.Текст="ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ &Условие";
Если ВыбТовары.Количество()=0 Тогда
    Запрос.Текст=СтрЗаменить(Запрос.Текст, "&Условие", "ИСТИНА");
Иначе
    Запрос.Текст=СтрЗаменить(Запрос.Текст, "&Условие", "(Товар в (&Товары))");
КонецЕсли;


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

acsent

Обычно такие вещи делают с помощью построителя отчета или запроса
  ПЗ = Новый ПостроительЗапроса;
  ПЗ.Текст = "
  |ВЫБРАТЬ 
  |  Спр.Ссылка ИЗ Справочник.Номенклатура КАК Спр
  |{
  |ГДЕ 
  |  Спр.Ссылка.* КАК Ссылка
  |}";

  ПЗ.Отбор.Добавить("Ссылка");
  ПЗ.Отбор.Ссылка.Значение = СписокНоменклатуры;
  ПЗ.Отбор.Ссылка.ВидСравнения = ВидСравнения.ВСписке;
  ПЗ.Отбор.Ссылка.Использование = Истина; // или (СписокНоменклатуры.Количество() > 0)
  
  ПЗ.Выполнить();


TormozIT
Такое решение мне кажется наиболее отвечающим требованиям поставленной задачи.
ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры,
    ЦеныНоменклатурыСрезПоследних.ТипЦен,
    ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
ГДЕ
    (ЦеныНоменклатурыСрезПоследних.Номенклатура В (&СписокНоменклатуры)
     ИЛИ (НЕ 1 В
              (ВЫБРАТЬ РАЗЛИЧНЫЕ 1
               ИЗ Справочник.Номенклатура КАК Спр
               ГДЕ Спр.Ссылка В (&СписокНоменклатуры))))


acsent
Еще один вариант, для сложных условий
ВЫБРАТЬ
...
ИЗ
...
ГДЕ
   (НЕ &УсловиеЗадано ИЛИ (НашеСложноеУсловие))

От Гения 1С: но лучше в варианте аскента писать так (это и програмисту понятнее)
ВЫБРАТЬ
...
ИЗ
...
ГДЕ
   ВЫБОР КОГДА &УсловиеЗадано ТОГДА НашеСложноеУсловие ИНАЧЕ ИСТИНА КОНЕЦ

От vhl:
А можно и не плодить параметры:
ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура
ГДЕ
   ВЫБОР 
        КОГДА &Товары=НЕОПРЕДЕЛЕНО ТОГДА ИСТИНА 
        ИНАЧЕ Товар в (&Товары)
   КОНЕЦ


Этот принцип повсеместно используется в отчетах в конфе "Управление торговлей"

SuperSpade
Замечание по последнему варианту:
при сравнении с Неопределено в запросе предприятие ругается на сравнение несовместимых типов и типов
непостоянной длины, а вот с ЕСТЬ NULL работает:

Если СписокМагазов.Количество()>0 Тогда
   Запрос.УстановитьПараметр("СписокМагазов",    СписокМагазов);
Иначе
   Запрос.УстановитьПараметр("СписокМагазов",    NULL);
КонецЕсли;

Запрос.Текст = "ВЫБРАТЬ
   |    Склады.Ссылка
   |ИЗ
   |    Справочник.Склады КАК Склады
   |ГДЕ
   |    ВЫБОР
   |       КОГДА &СписокМагазов ЕСТЬ NULL ТОГДА ИСТИНА
   |       ИНАЧЕ Склады.Магазин В (&СписокМагазов)
   |    КОНЕЦ";

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2024 | Mista.ru

Яндекс.Метрика