Книга знаний

1С:Предприятие / v8 / Администрирование / Производительность

v8: Ускорение типовой свертки таблиц значений в 1С80

Ускоряет на порядки выполнение свертки таблиц значенийАвтор статьи: Гений 1С | Редакторы:
Последняя редакция №4 от 18.05.06 | История
URL: http://kb.mista.ru/article.php?id=228

Ключевые слова: производительность,таблица значений,свертка


Волочаев Дмитрий написал код и разрешил его публикацию здесь, я его лишь косметически доработал. Код предназначен для замены типовой функции по свертке таблицы значений ее сверткой через построитель запроса.

Суммирует пока только по числовым полям, типовая умеет суммировать и по полям неопределенного вида.

КОД ПОКА НЕ НА 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");


Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика