Не строгий поиск по нескольким словам в запросе 1с

Программирование 1с

Предисловие

Разрабатывая приложения на 1с, довольно частой задачей является извлечение данных из 1с. Зачастую эти данные нужно еще удобный образом отобразить пользователю.

Разрабатывая свою версия подбора для РМК в конфигурации Розница 2, столкнулся с некоторыми сложностями. Форма подбора которая идет в конфигурации сразу же была отброшена, так как реализованный в ней подбор характеристик является крайне неудобным. Пришлось делать с нуля свою форму подбора

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

Чтоб проще было понять о чем идет речь, мне нужно было найти в базе данных значение Кавинтон 0,5% 10 мл. №5 амп используя в поле поиска запись вида Кавинтон 10 5.

Решение как оказалось было довольна простым. Нужно было правильно использовать операцию ПОДОБНО в запросе 1с. Код оставлю ниже может кому пригодится

<code>&amp;НаКлиенте
Процедура ОбновитьТаблицуОстатковНаКлиенте()
	ОбновитьТаблицуОстатков();
КонецПроцедуры

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


Функция СфориироватьСтрокуПоиска()
	МассивСлов = СтрРазделить(ПолеПоиска, " ", Ложь);
	СтрокаПоиска = "";
	сч = 0;
	КоличествоСлов = МассивСлов.Количество();

	Для Каждого стр Из МассивСлов Цикл
		сч = сч + 1;
		СтрокаПоиска = СтрокаПоиска + "Номен.Наименование ПОДОБНО " + """%" + стр+ "%""";
		Если НЕ (КоличествоСлов - сч) = 0 Тогда
			СтрокаПоиска = СтрокаПоиска + " И ";	
		КонецЕсли;	
	КонецЦикла;	
	
	Возврат СтрокаПоиска;
КонецФункции	</code>

UPD от 12.02.2019

По итогу выяснилось, что предыдущий запрос выполнялся крайне не эффективно так как в выборку попадали все остатки и все цены, время выполнения запроса равнялась около 3.5 секунд. Потому была проведена оптимизация запроса, после которой удалось снизить время запроса до 0.125 секунд, что является для меня приемлемым значением.
Ошибка же была в том, что я не накладывал на виртуальные таблицы Остатков и Цен дополнительный параметры отбора, в виду чего отбирались все данные, даже которые мне не были необходимы. А если учесть что в конфигурации Розница 2 я включил учет характеристик, которые автоматически создаются при каждом приходе товара, то и соответственно сам регистр ЦеныНоменклатуры у меня очень большой и тянуть из него данные каждый раз будет накладно.

Код оптимизированного запроса прилагаю ниже.

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

Вам также может понравиться

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

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

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