mnogopotochnaja_obrabotka

1. Вызываем основную функцию где нужно получить результат многопоточной обаботки

&НаСервере
Процедура ПолучитьтаблицуПоПараметрам_Многопоточно(парам1)	
	ТЗСтатистикаПродажПоДням				=	АвтоматизацияПрогноза.ПолучитьТЗСтатистикаПродаж_Многопоточно(парам1,8);	
КонецПроцедуры

2. В общем модуле, например, получаем основноую таблицу, котороую потом нужно многопоточно обработать

&НаСервере
Функция ПолучитьТЗСтатистикаПродаж_Многопоточно(Параметры=Неопределено) Экспорт 
	
	ТЗОбщая	=	Новый ТаблицаЗначений;
	
	Если Не ЗначениеЗаполнено(Параметры) Тогда 
		Возврат ТЗОбщая;
	КонецЕсли;
	
	//Получаем общую таюлицу для последующей многопоточной обработки
	ТЗОбщая	=	ПолучитьПредварительнуюТаблицу(Параметры);
	
	// определяем максимальное количество потоков
	ЧислоСтрокВТаблице = ТЗОбщая.Количество();
	
	//Определяем число потоков
	ЧислоПотоков		=	РегистрыСведений.РегистрКонстант.ПолучитьЗначениеКонстанты("КоличествоПотоковДляРасчетаАвтоПрогноза");
	Если Не ЗначениеЗаполнено(ЧислоПотоков) Тогда 
		 ЧислоПотоков	=	8;
	КонецЕсли;
	 
	
	// объем порции данных для обработки каждым потокомс
	РазмерПроции = Цел(ЧислоСтрокВТаблице/ЧислоПотоков);
			
	// массив где будут храниться фоновые задания
    МассивЗаданий = Новый Массив;
	
	Для НомерПотока = 1 По ЧислоПотоков Цикл 		  
		
		// определяем индекс для начала обработки данных данным потоком
		// разные потоки обрабатывают разные части таблицы
		ИндексНачала = (НомерПотока - 1)*РазмерПроции;	
		
		Если (НомерПотока = ЧислоПотоков) Тогда
			// если это последний поток, то он обрабатывает все оставшиеся данные
			// т.к. число потоков может не быть кратно количеству строк в таблице
			РазмерПроции = ЧислоСтрокВТаблице-(ЧислоПотоков*РазмерПроции)+РазмерПроции;			
		КонецЕсли;                                        		
		
		// определяем массив параметров для процедуры
		НаборПараметров = Новый Массив;
		НаборПараметров.Добавить(ТЗОбщая);
		НаборПараметров.Добавить(Параметры.ЗапросСтатистики_Склад);
		НаборПараметров.Добавить(ИндексНачала);
		НаборПараметров.Добавить(РазмерПроции);				
		
		// запуск фонового задания
		Задание = ФоновыеЗадания.Выполнить("АвтоматизацияПрогноза.ДополнитьДопДанными_Многопоточный", НаборПараметров);
		
		// добавляем задание в массив, что бы потом отследить выполнение
		МассивЗаданий.Добавить(Задание);
        
    КонецЦикла;

	// проверим результат выполнения фоновых заданий
    Если МассивЗаданий.Количество() > 0 Тогда
        Попытка
            ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
		Исключение
			// действия в случае ошибки
			Сообщить(ОписаниеОшибки());
		КонецПопытки;        
    КонецЕсли;
	
	
	
	Возврат  ТЗОбщая;
	
КонецФункции

3. Вот эта часть будет обрабатывать свои части таблицы значений в паралельных многопоточных потоках

&НаСервере
Процедура ДополнитьДопДанными_Многопоточный(ТЗОбщая, Склад, ИндексНачала, РазмерПроции) Экспорт 
	
	
	//Дополнительные таблицы
	Для Сч = 1 По РазмерПроции Цикл
		
		
		Индекс 	= ?(Сч=1, ИндексНачала, Индекс+1);
		стр		= ТЗОбщая[Индекс];	
		
		
		//++Остатки
		Запрос = Новый ПостроительЗапроса();
		Запрос.Текст = 
		"ВЫБРАТЬ
		|	ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
		|	ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК КоличествоНаСкладе,
		|	&Период КАК ДеньМесяца
		|ИЗ
		|	РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Номенклатура = &Номенклатура {(Склад = &Склад) КАК Поле2}) КАК ТоварыНаСкладахОстатки";
		
		Запрос.Параметры.Вставить("Номенклатура", стр.Номенклатура);
		Запрос.Параметры.Вставить("Период", стр.Период);
		
		Если ЗначениеЗаполнено(Склад) тогда
			
			Запрос.Параметры.Вставить("Склад", Склад);
			Запрос.Отбор.Добавить("Поле2");
			Запрос.Отбор.Поле2.Значение = Истина;
			Запрос.Отбор.Поле2.ВидСравнения = ВидСравнения.Равно;
			Запрос.Отбор.Поле2.Использование = Истина;
			
		КонецЕсли;
		
		Запрос.Выполнить();
		
		ТЗОстатки = Запрос.Результат.Выгрузить();
				
		Для каждого ВыборкаДетальныеЗаписи из ТЗОстатки Цикл
			стр.Остаток = ВыборкаДетальныеЗаписи.КоличествоНаСкладе;
			прервать;
		КонецЦикла;	
		//--Остатки
		
		
		
		//++Себестоимость
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ
		|	СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура КАК НоменклатураСебестоимость,
		|	СРЕДНЕЕ(ВЫБОР
		|			КОГДА ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0) > 0
		|				ТОГДА ЕСТЬNULL(СебестоимостьТоваровОстатки.СтоимостьОстаток, 0) / ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0)
		|			ИНАЧЕ 0
		|		КОНЕЦ) КАК СебестоимостьТовара,
		|	&Период КАК ДеньМесяца
		|ИЗ
		|	РегистрНакопления.СебестоимостьТоваров.Остатки(&Период, АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура) КАК СебестоимостьТоваровОстатки
		|
		|СГРУППИРОВАТЬ ПО
		|	СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура";
		
		Запрос.УстановитьПараметр("Номенклатура", стр.Номенклатура);
		Запрос.УстановитьПараметр("Период", стр.Период);
		
		РезультатЗапроса = Запрос.Выполнить();
		
		ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
		
		Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
			стр.Себестоимость = ВыборкаДетальныеЗаписи.СебестоимостьТовара;
			прервать;
		КонецЦикла;
		//--Себестоимость
		
		
		
		//++ВЗаказах
		Запрос = Новый ПостроительЗапроса();
		Запрос.Текст = 
		"ВЫБРАТЬ
		|	ЗаказыПоставщикамОстатки.Номенклатура КАК Номенклатура,
		|	СУММА(ЕСТЬNULL(ЗаказыПоставщикамОстатки.ЗаказаноОстаток, 0)) КАК КоличествоВЗаказах,
		|	СРЕДНЕЕ(ЕСТЬNULL(ВложенныйЗапрос.Цена, 0)) КАК ЦенаИзЗаказа,
		|	&Период КАК ДеньМесяца
		|ИЗ
		|	РегистрНакопления.ЗаказыПоставщикам.Остатки(&Период, Номенклатура = &Номенклатура {(Склад = &Склад) КАК Поле2}) КАК ЗаказыПоставщикамОстатки
		|		ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
		|			ЗаказПоставщикуТовары.Номенклатура КАК Номенклатура,
		|			СРЕДНЕЕ(ЗаказПоставщикуТовары.Цена) КАК Цена,
		|			ЗаказПоставщикуТовары.Ссылка КАК Ссылка
		|		ИЗ
		|			Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
		|		
		|		СГРУППИРОВАТЬ ПО
		|			ЗаказПоставщикуТовары.Номенклатура,
		|			ЗаказПоставщикуТовары.Ссылка) КАК ВложенныйЗапрос
		|		ПО ЗаказыПоставщикамОстатки.Номенклатура = ВложенныйЗапрос.Номенклатура
		|			И ЗаказыПоставщикамОстатки.ЗаказПоставщику = ВложенныйЗапрос.Ссылка
		|
		|СГРУППИРОВАТЬ ПО
		|	ЗаказыПоставщикамОстатки.Номенклатура";
		
		Запрос.Параметры.Вставить("Номенклатура", стр.Номенклатура);
		Запрос.Параметры.Вставить("Период", стр.Период);
		
		 Если ЗначениеЗаполнено(Склад) тогда
			
			Запрос.Параметры.Вставить("Склад", Склад);
			Запрос.Отбор.Добавить("Поле2");
			Запрос.Отбор.Поле2.Значение = Истина;
			Запрос.Отбор.Поле2.ВидСравнения = ВидСравнения.Равно;
			Запрос.Отбор.Поле2.Использование = Истина;
			
		КонецЕсли;
		
		Запрос.Выполнить();
		
		ТЗВЗаказах = Запрос.Результат.Выгрузить();
		
		Для каждого ВыборкаДетальныеЗаписи из ТЗВЗаказах Цикл
			стр.ЦенаИзЗаказов = ВыборкаДетальныеЗаписи.ЦенаИзЗаказа;
			стр.ВЗаказах = ВыборкаДетальныеЗаписи.КоличествоВЗаказах;
			прервать;
		КонецЦикла;
		//--+ВЗаказах
		
		
		//++ВДороге
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ
		|	СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура КАК НоменклатураЕдет,
		|	СУММА(ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0)) КАК КоличествоЕдет,
		|	СРЕДНЕЕ(ВЫБОР
		|			КОГДА ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0) > 0
		|				ТОГДА ЕСТЬNULL(СебестоимостьТоваровОстатки.СтоимостьОстаток, 0) / ЕСТЬNULL(СебестоимостьТоваровОстатки.КоличествоОстаток, 0)
		|			ИНАЧЕ 0
		|		КОНЕЦ) КАК СебестоимостьЕдет,
		|	&Период КАК ДеньМесяца
		|ИЗ
		|	РегистрНакопления.СебестоимостьТоваров.Остатки(
		|			&Период,
		|			РазделУчета = ЗНАЧЕНИЕ(Перечисление.РазделыУчетаСебестоимостиТоваров.ТоварыВПути)
		|				И АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура) КАК СебестоимостьТоваровОстатки
		|
		|СГРУППИРОВАТЬ ПО
		|	СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура";
		
		Запрос.УстановитьПараметр("Номенклатура", стр.Номенклатура);
		Запрос.УстановитьПараметр("Период", стр.Период);
		
		РезультатЗапроса = Запрос.Выполнить();
		
		ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
		
		Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
			стр.ВДороге = ВыборкаДетальныеЗаписи.КоличествоЕдет;	
			прервать;
		КонецЦикла;	
		//--ВДороге
		
	КонецЦикла;
	
КонецПроцедуры
  • /sites/data/pages/mnogopotochnaja_obrabotka.txt
  • Последнее изменение: 2022/02/28 17:22
  • tro