gifts2017

Оптимизация отборов в табличных полях

Опубликовал Danil Snissarenko (d.snissarenko) в раздел Программирование - Практика программирования

В предыдущей статье - 1сv8 дела интерфейсные , я рассматривал возможность вывода вычисляемой колонки в табличном поле и отбора по ней, в данной статье как в дополнение хочу продемонстрировать, как можно ускорить отбор.
В предыдущей статье - 1сv8 дела интерфесные , я рассматривал возможность вывода вычисляемой колнки в табличном полеи и отбора по ней, в данной статье как в дополнение, хочу продемонстрировать как можно ускорить отбор.
Рассматривая процедуру ОтборПоОстаткам видно, что запросом выбираются все данные из регистров, а не только те, что видно в табличном поле, поэтому если скажем номенклатуры будет не 2-3 тысячи а 20-40, то на такой отбор потребуется достаточно много ресурсов, а возможнен и вылет 1с с сообщением о нехватке памяти, поэтому на мой взгляд отбор лучше проводить по ограниченому списку.
Итак добавим в модуль переменные
// добавим переменные отражающие текущее состояние отбора // для ускорения отбора будем использовать отбор только по той группе товара которую выбрали Перем
ОтборПоОстаткам
,
ОтборПоРезервам
,
ОтборПоПоставке ;

а так-же добавим предопределенную процедуру ПриОткрытии(), где присвоим переменным значение Ложь
Процедура
ПриОткрытии
()
ОтборПоОстаткам 
=
Ложь;
ОтборПоРезервам 
=
Ложь;
ОтборПоПоставке 
=
Ложь;
КонецПроцедуры
Далее добавляем предопределенную процедуру ПриСменеТекущегоРодителя

Процедура
СписокПриСменеТекущегоРодителя
(
Элемент
) Если
ОтборПоОстаткам 
=
Истина  
Тогда
Список
.
Отбор
.
Ссылка
.
Использование 
=
Ложь;
	ОтборПоОстаткам
(
ЭлементыФормы
.
Остаткам
,2,
Элемент
.
ТекущийРодитель
)
;
    
КонецЕсли
;
	
Если
ОтборПорезервам 
=
Истина  
Тогда
Список
.
Отбор
.
Ссылка
.
Использование 
=
Ложь;
	ОтборПоОстаткам
(
ЭлементыФормы
.
Остаткам
,3,
Элемент
.
ТекущийРодитель
)
;
	
КонецЕсли
;
    
Если
ОтборПоПоставке 
=
Истина  
Тогда
Список
.
Отбор
.
Ссылка
.
Использование 
=
Ложь;
	ОтборПоОстаткам
(
ЭлементыФормы
.
Остаткам
,4,
Элемент
.
ТекущийРодитель
)
;
	
КонецЕсли
;

КонецПроцедуры
Как видно из процедуру в зависимости от текущего выбранного значения и текущего значения переменных отбора происходит вызов процедуры ОтборПоОстаткам.
Добавим в процедуру ОтборПоОстаткам дополнительные переменные
ЗначениеОтбора=0 и Номенклатура = Неопределено
Процедура
ОтборПоОстаткам
(
Элемент
,
ЗначениеОтбора
=0,
Номенклатура 
=
Неопределено 
) Если НЕ
ЭлементыФормы
.
Список
.
ТекущаяСтрока 
=
Неопределено 
Тогда Если
Номенклатура 
=
Неопределено 
Тогда
Номенклатура 
=
ЭлементыФормы
.
Список
.
ТекущаяСтрока
.
Ссылка
.
Родитель;
		
КонецЕсли
;
Иначе Если
Номенклатура 
=
Неопределено 
Тогда
Номенклатура 
=
ЭлементыФормы
.
Список
.
ТекущаяСтрока
.
Ссылка
.
Родитель;
КонецЕсли
;
		
КонецЕсли
;

		Номенклатура 
=
ЭлементыФормы
.
Список
.
ТекущийРодитель;

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

Результат данных изменеий можно взять тут http://infostart.ru/file.php?0,file=348



См. также

Подписаться Добавить вознаграждение
В этой теме еще нет сообщений.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа