Ускорение пересчета заказа покупателя УНФ

У клиента в счете на оплату и заказе клиента при смене процента скидки пересчитывался документ. При этом счет пересчитывался быстро, а заказ — медленно. Обычно там документы состоят из нескольких сотен строк.

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

&НаКлиенте
Процедура ОбработатьТаблицу(ИмяТЧ)
...    
	Для каждого Строка Из ИзменяемыеСтроки Цикл
		РассчитатьСуммуВСтрокеТабличнойЧасти(, Строка);
	КонецЦикла;
...
КонецПроцедуры

&НаКлиенте
&После("РассчитатьСуммуВСтрокеТабличнойЧасти")
Процедура ТР_РассчитатьСуммуВСтрокеТабличнойЧасти(ИмяТабличнойЧасти, СтрокаТабличнойЧасти, ПараметрыРасчета)
	ПересчитатьВесИОбъем(СтрокаТабличнойЧасти);
КонецПроцедуры
                            
                            
&НаКлиенте
Процедура ПересчитатьВесИОбъем(СтрокаТабличнойЧасти)
	
	Если Не СтрокаТабличнойЧасти.Характеристика.Пустая() Тогда
		
		СтрокаТабличнойЧасти.Вес 	= СтрокаТабличнойЧасти.Количество * ПолучитьВесТекСтроки(СтрокаТабличнойЧасти.Характеристика);
		СтрокаТабличнойЧасти.Объем 	= СтрокаТабличнойЧасти.Количество * ПолучитьОбъемТекСтроки(СтрокаТабличнойЧасти.Характеристика);
		СтрокаТабличнойЧасти.Площадь= СтрокаТабличнойЧасти.Количество * ПолучитьПлощадьТекСтроки(СтрокаТабличнойЧасти.Характеристика);
	    Возврат;
	КонецЕсли;	
	
   СтрокаТабличнойЧасти.Вес = СтрокаТабличнойЧасти.Количество*ВернутьВес(СтрокаТабличнойЧасти.Номенклатура);
   СтрокаТабличнойЧасти.Объем = СтрокаТабличнойЧасти.Количество*ВернутьОбъем(СтрокаТабличнойЧасти.Номенклатура);
	
КонецПроцедуры

При пересчете веса и объема вызывались серверные функции ВернутьВес и ВернутьОбъем. Т.е. постоянно дергался клиент-сервер.

Я поменял вызов следующим образом:

&НаКлиенте
Перем дор_СтрокиПересчета; 
&НаКлиенте
&После("РассчитатьСуммуВСтрокеТабличнойЧасти")
Процедура ТР_РассчитатьСуммуВСтрокеТабличнойЧасти(ИмяТабличнойЧасти, СтрокаТабличнойЧасти, ПараметрыРасчета)
	//Откладываем пересчет
	дор_СтрокиПересчета.Добавить(СтрокаТабличнойЧасти.ПолучитьИдентификатор());
	ПодключитьОбработчикОжидания("ТР_ОтложенныйПересчет", 0.1, истина);
	//ПересчитатьВесИОбъем(СтрокаТабличнойЧасти);
КонецПроцедуры

&НаКлиенте
Процедура ТР_ПриОткрытииПеред(Отказ)
	дор_СтрокиПересчета = Новый Массив(); 
КонецПроцедуры

&НаКлиенте
Процедура ТР_ОтложенныйПересчет() Экспорт
	Если дор_СтрокиПересчета.Количество() > 0 Тогда
		ТР_ОтложенныйПересчетНаСервере(дор_СтрокиПересчета); 
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ТР_ОтложенныйПересчетНаСервере(дор_СтрокиПересчета) Экспорт
	Для Каждого ИдентификаторСтроки ИЗ дор_СтрокиПересчета Цикл 
		СтрокаТабличнойЧасти = Объект.Запасы.НайтиПоИдентификатору(ИдентификаторСтроки);
		Если СтрокаТабличнойЧасти <> Неопределено Тогда
			ПересчитатьВесИОбъемНаСервере(СтрокаТабличнойЧасти);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры


&НаСервере
Процедура ПересчитатьВесИОбъемНаСервере(СтрокаТабличнойЧасти)
	//Скопирована из клиентской процедуры
	
	Если Не СтрокаТабличнойЧасти.Характеристика.Пустая() Тогда
		
		СтрокаТабличнойЧасти.Вес 	= СтрокаТабличнойЧасти.Количество * ПолучитьВесТекСтроки(СтрокаТабличнойЧасти.Характеристика);
		СтрокаТабличнойЧасти.Объем 	= СтрокаТабличнойЧасти.Количество * ПолучитьОбъемТекСтроки(СтрокаТабличнойЧасти.Характеристика);
		СтрокаТабличнойЧасти.Площадь= СтрокаТабличнойЧасти.Количество * ПолучитьПлощадьТекСтроки(СтрокаТабличнойЧасти.Характеристика);
	    Возврат;
	КонецЕсли;	
	
   СтрокаТабличнойЧасти.Вес = СтрокаТабличнойЧасти.Количество*ВернутьВес(СтрокаТабличнойЧасти.Номенклатура);
   СтрокаТабличнойЧасти.Объем = СтрокаТабличнойЧасти.Количество*ВернутьОбъем(СтрокаТабличнойЧасти.Номенклатура);
	
КонецПроцедуры

Пришлось клонировать функцию ПересчитатьВесИОбъем. Узнал, что если несколько раз подключить один и тот же обработчик ожидания, он вызовется все равно один раз, что и требовалось.

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

Среда: УНФ 1.6.26.172. Объем: 1 час.

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Читайте также:

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

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