Необязательные параметы запроса

Ппоказан пример запроса с необязательным отбором по товару и складу. Этот пример предназначен не для СКД, а для запросов в программном коде 1С:Предприятие 8.3.

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

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

  • модификацией самого текста запроса (например, через СтрЗаменить). Методическая правильность этого способа может вызывать нарекания, но я допускаю, что в некоторых особо продвинутых случаях работы с запросами в 1С без этого способа не обойтись.
  • проверкой параметров на пустоту (заполненность) сравнением с пустым значением в самом запросе: (&Товар = ЗНАЧЕНИЕ(Справочник.Товары.ПустаяСсылка) ИЛИ … )
  • передачей дополнительных параметров вида &НеПроверятьРеквизитТакойТо. Условие обратное (не проверять), т.к. такие параметры удобно объединять с основным условием по ИЛИ.
  • использованием конструкции {ГДЕ … }, которая имеется в СКД и объекте ПостроительЗапроса.

Тестовый пример

В качестве тестового примера в пустой конфигурации создадим документ ПриходнаяНакладная с табличной частью Тч и ее реквизитами Товар и Количество, реквизитом Склад в шапке. Тестовый отчет содержит реквизиты Товар, Склад и МинимальноеКоличество. Пример конфигурации с тестовыми данными (вбиты несколько документов с товарами и складами) можно скачать здесь: https://yadi.sk/d/92c3oEKWZG4ZY - для 1С:Предприятие 8.3 (8.3.4.482).

Использование дополнительных параметров

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

Использование объекта ПостроительЗапроса

&НаКлиенте
Процедура КомандаПостроитель(Команда)
  ОчиститьСообщения();
	КомандаПостроительНаСервере();
КонецПроцедуры
 
 
&НаСервере
Процедура КомандаПостроительНаСервере()
//Это пример использования построителя запросов. 
//Реквизиты на форме - Товар, Склад, МинимальноеКоличество
 
	пз = Новый ПостроительЗапроса;
 
	пз.Текст =  
	"ВЫБРАТЬ
	|	ПриходнаяНакладнаяТч.Ссылка,
	|	ПриходнаяНакладнаяТч.НомерСтроки,
	|	ПриходнаяНакладнаяТч.Товар,
	|	ПриходнаяНакладнаяТч.Количество,
	|	ПриходнаяНакладнаяТч.Ссылка.Склад
	|ИЗ
	|	Документ.ПриходнаяНакладная.Тч КАК ПриходнаяНакладнаяТч
	|ГДЕ
	|	ПриходнаяНакладнаяТч.Ссылка.ПометкаУдаления = ЛОЖЬ
	|	И ПриходнаяНакладнаяТч.Ссылка.Проведен = ИСТИНА
	|	И ПриходнаяНакладнаяТч.Количество >= &МинимальноеКоличество
	|{ГДЕ      
	|	ПриходнаяНакладнаяТч.Товар,
	|	ПриходнаяНакладнаяТч.Ссылка.Склад}";
 
	//Необязательный отбор по товару
	Если ЗначениеЗаполнено(Товар) Тогда		
	  ПЗ.Отбор.Добавить("Товар");
	  ПЗ.Отбор.Товар.Значение = Товар;
	  ПЗ.Отбор.Товар.ВидСравнения = ВидСравнения.Равно;
	  ПЗ.Отбор.Товар.Использование = Истина; 		
	КонецЕсли;
 
	//Необязательный отбор по складу
	Если ЗначениеЗаполнено(Склад) Тогда		
	  ПЗ.Отбор.Добавить("Склад");
	  ПЗ.Отбор.Склад.Значение = Склад;
	  ПЗ.Отбор.Склад.ВидСравнения = ВидСравнения.Равно;
	  ПЗ.Отбор.Склад.Использование = Истина; 		
  	КонецЕсли;
 
	//Обязательный отбор по минимальному количеству	
	пз.Параметры.Вставить("МинимальноеКоличество", МинимальноеКоличество);
 
	пз.Выполнить();
	РезультатЗапроса = пз.Результат; 
 
	вв = РезультатЗапроса.Выбрать();
 
	Пока вв.Следующий() Цикл
		Сообщить(""+вв.Склад+" "+вв.Товар+" "+вв.Количество);
	КонецЦикла;
 
КонецПроцедуры

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

{ГДЕ
  ПриходнаяНакладнаяТч.Товар,
	ПриходнаяНакладнаяТч.Ссылка.Склад}

вместо обычной записи условий в запросе вида

  ПриходнаяНакладнаяТч.Товар = &Товар
  И ПриходнаяНакладнаяТч.Ссылка.Склад = &Склад

Добавляется фигурная скобка и ключевое слово ГДЕ, убирается часть вида = &Склад, добавляется закрывающая фигурная скобка, вместо И пишется запятая (см. образец).

В конструкторе запросов необязательные параметры из выражения с фигурными скобками {ГДЕ…} можно найти на вкладке Построитель - Условия.