v8: Ускорение типовой свертки таблиц значений в 1С80 Ключевые слова: производительность,таблица значений,свертка
Волочаев Дмитрий написал код и разрешил его публикацию здесь, я его лишь косметически доработал. Код предназначен для замены типовой функции по свертке таблицы значений ее сверткой через построитель запроса.
Суммирует пока только по числовым полям, типовая умеет суммировать и по полям неопределенного вида.
КОД ПОКА НЕ НА 100% соместим с ТЗ.Свернуть
Дело в том что таблица значений - неиндексированная коллекция и типовая свертка по ней работает медленно.
Рекомендуется для ускорения все вызовы ТЗ.Свернуть(А,Б) на ТурбоСвернуть(ТЗ,А,Б) и удивитесь приросту скорости.
Код функции СвернутьТаблицуЗначений
Функция СвернутьТаблицуЗначений(Таб, строкаГруппировок, СтрокаСуммирования, ГраничноеКоличество = 1000) Экспорт
Если Таб.Количество()<ГраничноеКоличество Тогда
Т1=Таб.Скопировать(); //fixin
Т1.Свернуть(строкаГруппировок, СтрокаСуммирования);//fixin
Возврат Т1; //fixin
КонецЕсли;
пз = Новый ПостроительЗапроса();
пз.ИсточникДанных = Новый ОписаниеИсточникаДанных(Таб);
пз.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
СтрукГруппировок = Новый Структура(строкаГруппировок);
КоличествоГруппировок = СтрукГруппировок.Количество();
Для каждого Эл Из СтрукГруппировок Цикл
пз.ИсточникДанных.Колонки[Эл.Ключ].Измерение = Истина;
КонецЦикла;
СтрукСуммирования = Новый Структура(СтрокаСуммирования);
Для каждого Эл Из СтрукСуммирования Цикл
ИмяКолонки=Эл.Ключ;
//Если ТипЗнч(пз.ИсточникДанных.Колонки[ИмяКолонки].ТипЗначения)<>Тип("Число") Тогда
// ИмяВременнойКолонки="TMP_only_for_groupping" & "Эл.Ключ";
// пз.Колонки.Добавить(ИмяВременнойКолонки);
// Для Каждого Стр Из Пз.ИсточникДанных Цикл
// Стр[ИмяВременнойКолонки]=Стр[ИмяКолонки];
// КонецЦикла;
// пз.ИсточникДанных.Колонки[ИмяКолонки].Удалить();
// пз.ИсточникДанных.Колонки[ИмяКолонки].Удалить();
// пз.ДоступныеПоля.С1.ТипЗначения=Новый ОписаниеТипов("Число") //fixin
//КонецЕсли;
пз.ИсточникДанных.Колонки[Эл.Ключ].Итог = "Сумма("+Эл.Ключ+")";
КонецЦикла;
Таб1 = Новый ТаблицаЗначений;
Для каждого Колонка Из Таб.Колонки Цикл
Если (СтрукГруппировок.Свойство(Колонка.Имя) = Ложь) И
(СтрукСуммирования.Свойство(Колонка.Имя) = Ложь) Тогда
Продолжить;
КонецЕсли;
Таб1.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
пз.ЗаполнитьНастройки();
пз.Выполнить();
ЗаполнитьТаблицуПоВыборке(пз.Результат, Таб1, КоличествоГруппировок);
Возврат Таб1;
КонецФункции
Процедура ЗаполнитьТаблицуПоВыборке(Рез,Таб, Знач КоличествоГруппировок)
выб = Рез.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока выб.Следующий() Цикл
Если КоличествоГруппировок=0 Тогда
НовСтрока = Таб.Добавить();
ЗаполнитьЗначенияСвойств(НовСтрока, выб);
Иначе
ЗаполнитьТаблицуПоВыборке(выб,Таб, КоличествоГруппировок-1);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Для проверки запускать тест:
// Вставить содержимое обработчика.
ТЗ=Новый ТаблицаЗначений();
//ТЗ.Колонки.Добавить("А"); //В таком режиме пока не работает
//ТЗ.Колонки.Добавить("Б"); //В таком режиме пока не работает
ТЗ.Колонки.Добавить("С1", Новый ОписаниеТипов("Число"));
ТЗ.Колонки.Добавить("С2", Новый ОписаниеТипов("Число"));
ТЗ.Колонки.Добавить("С1");
ТЗ.Колонки.Добавить("С2");
Для Инд=1 По 10 Цикл
Стр=ТЗ.Добавить();
Стр.А="А"+Инд%2;
Стр.Б="Б"+Инд%3;
Стр.С1=Инд*1;
Стр.С2=Инд*10;
КонецЦикла;
ТЗ1=ТЗ.Скопировать();
ТЗ2=ТЗ.Скопировать();
ТЗ3=ТЗ.Скопировать();
ТЗ4=ТЗ.Скопировать();
ТЗ1=СвернутьТаблицуЗначений(ТЗ1,"А","С1,С2",0);
ТЗ1.ВыбратьСтроку("А:С1,С2");
ТЗ2=СвернутьТаблицуЗначений(ТЗ2,"А,Б","С1",0);
ТЗ2.ВыбратьСтроку("А,Б:С1");
ТЗ3=СвернутьТаблицуЗначений(ТЗ3,"","С1,С2",0);
ТЗ3.ВыбратьСтроку(":С1,С2");
ТЗ4=СвернутьТаблицуЗначений(ТЗ4,"А,Б","С1,С2",0);
ТЗ4.ВыбратьСтроку("А,Б:С1,С2");
|