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 | КОНЕЦ) КАК СебестоимостьЕдет, | &Период КАК ДеньМесяца |ИЗ | РегистрНакопления.СебестоимостьТоваров.Остатки( | &Период, | РазделУчета = ЗНАЧЕНИЕ(Перечисление.РазделыУчетаСебестоимостиТоваров.ТоварыВПути) | И АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура) КАК СебестоимостьТоваровОстатки | |СГРУППИРОВАТЬ ПО | СебестоимостьТоваровОстатки.АналитикаУчетаНоменклатуры.Номенклатура"; Запрос.УстановитьПараметр("Номенклатура", стр.Номенклатура); Запрос.УстановитьПараметр("Период", стр.Период); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл стр.ВДороге = ВыборкаДетальныеЗаписи.КоличествоЕдет; прервать; КонецЦикла; //--ВДороге КонецЦикла; КонецПроцедуры