Имя: Пароль:
1C
 
Таблица значений - Дерево значений с итогами
0 Mort
 
30.06.06
17:28
Стоит задача выполнить функцию типа
СформироватьДЗ(ТаблицаЗначений, <КолонкиГруппировок>,<КолонкиСуммируемые>) В результирующем дереве одна колонка с группировками остальные суммы. Мож кто сталкивался уже, есть простое решение?
1 Mort
 
30.06.06
18:18
Вот решение, может кому надо будет, а мож кто оптимальней придумает:

Функция СвернутьВДерево(ТЗ,СтрокаГруппировок,СтрокаСумм) Экспорт
   Дерево = Новый ДеревоЗначений;
   НовКолонка = Дерево.Колонки.Добавить("Группировка");
   НовКолонка.Заголовок = СтрокаГруппировок;
   СЗГрупп = Новый  СписокЗначений;
   Стр = СтрокаГруппировок;
   Пока Истина Цикл
       Симв = Найти(Стр,",");
       Если Симв=0 Тогда
           СЗГрупп.Добавить(Стр);
           Прервать;
       КонецЕсли;
       СЗГрупп.Добавить(Лев(Стр,Симв-1));
       Стр = Прав(Стр,СтрДлина(Стр)-Симв);
   КонецЦикла;
   Стр = СтрокаСумм;
   Пока Истина Цикл
       Симв = Найти(Стр,",");
       Если Симв=0 Тогда
           Дерево.Колонки.Добавить(Стр);
           Прервать;
       КонецЕсли;
       Дерево.Колонки.Добавить(Лев(Стр,Симв-1));
       Стр = Прав(Стр,СтрДлина(Стр)-Симв);
   КонецЦикла;
   СоздатьСтроки(Дерево.Строки, ТЗ, СЗГрупп,СтрокаСумм);
   Возврат Дерево;
КонецФункции

Процедура СоздатьСтроки(СтрокиДЗ,ТЗ,СписокГруппировок,СтрокаСумм,Уровень = 0)
   КопияТЗ = ТЗ.Скопировать();
   КопияТЗ.Свернуть(СписокГруппировок[Уровень].Значение,СтрокаСумм);
   Для Каждого СтрокаТаб ИЗ КопияТЗ Цикл
       НовСтрокаДЗ = СтрокиДЗ.Добавить();
       ЗаполнитьЗначенияСвойств(НовСтрокаДЗ,СтрокаТАБ);
       НовСтрокаДЗ.Группировка = СтрокаТАБ[СписокГруппировок[Уровень].Значение];
       Если Уровень < СписокГруппировок.Количество()-1 Тогда
           МассивСтрок = ТЗ.НайтиСтроки(Новый Структура(СписокГруппировок[Уровень].Значение,НовСтрокаДЗ.Группировка));    
           ПодТЗ = Новый ТаблицаЗначений;
           Для Каждого Колонка ИЗ ТЗ.Колонки Цикл
               ПодТЗ.Колонки.Добавить(Колонка.Имя);
           КонецЦикла;
           Для Каждого СтрМасс из МассивСтрок Цикл
               ЗаполнитьЗначенияСвойств(ПодТЗ.Добавить(),СтрМасс);
           КонецЦикла;
           СоздатьСтроки(НовСтрокаДЗ.Строки,ПодТЗ,СписокГруппировок,СтрокаСумм,Уровень+1);
       КонецЕсли;
   КонецЦикла;
КонецПроцедуры
2 clappa
 
30.06.06
20:26
Или так:


//Преобразует таблицу значений в дерево значений с иерархическкими итогами по группировочным полям
//
// Параметры
//  ТЗ  – Объект типа "ТаблицаЗначений"
//  КолонкиГрупп - Строка - перечень группировочных колонок через запятую
//  КолонкиГрупп - Строка - перечень суммируемых колонок через запятую
//
// Возвращаемое значение:
//  Объект типа ДеревоЗначений с колонками
//     ИмяГруппировки      - указывает имя группировки текущей строки
//     ЗначениеГруппировки - указывает значение группировки текущей строки
//     <колонки сумм>      - итоговые колонки в соответствии с параметром КолонкиСумм
//
Функция ТЗвДЗ(ТЗ, КолонкиГрупп, КолонкиСумм = "") Экспорт
   
   ДЗ = Новый ДеревоЗначений;
   ДЗ.Колонки.Добавить("ИмяГруппировки");
   ДЗ.Колонки.Добавить("ЗначениеГруппировки");
   
   МассивКолонокГрупп = ИзСтрокиСРазделителями(КолонкиГрупп);
   МассивКолонокСумм = ИзСтрокиСРазделителями(КолонкиСумм);
   Для каждого ИмяКолонки Из МассивКолонокСумм Цикл
       ДЗ.Колонки.Добавить(ИмяКолонки) //Здесь ещё можно дописать установку параметров колонки как в исходной ТЗ
   КонецЦикла;
   
   Если не ПустаяСтрока(КолонкиГрупп) Тогда
       ТЗ.Сортировать(КолонкиГрупп)
       
       КоличествоКолонокГрупп = МассивКолонокГрупп.Количество();
       СтекВеток = Новый Массив(КоличествоКолонокГрупп);
       СтекГрупп = Новый Массив(КоличествоКолонокГрупп);
       НачатьНовуюВетку = Истина;
       
       Для каждого Строка Из ТЗ Цикл
           Ветка = ДЗ;
           Для Уровень = 0 По КоличествоКолонокГрупп-1 Цикл
               Группировка = Строка[МассивКолонокГрупп[Уровень]];
               НачатьНовуюВетку = НачатьНовуюВетку или (СтекГрупп[Уровень] <> Группировка);
               Если НачатьНовуюВетку  Тогда
                   Ветка = Ветка.Строки.Добавить();
                   Ветка.ИмяГруппировки = МассивКолонокГрупп[Уровень];
                   Ветка.ЗначениеГруппировки = Группировка;
                   СтекВеток[Уровень] = Ветка;
                   СтекГрупп[Уровень] = Группировка;
               Иначе
                   Ветка = СтекВеток[Уровень]
               КонецЕсли;
           КонецЦикла;
           ЗаполнитьЗначенияСвойств(Ветка, Строка, КолонкиСумм);
           НачатьНовуюВетку = Ложь;
       КонецЦикла;
           
       ТЗвДЗ_ПосчитатьИтогиРекурсивно(ДЗ, МассивКолонокСумм);
   КонецЕсли;
   
   Возврат ДЗ
КонецФункции

Процедура ТЗвДЗ_ПосчитатьИтогиРекурсивно(Ветка, МассивКолонокСумм, Корень = Истина) //вспомогательная
   Если Ветка.Строки.Количество() = 0 Тогда Возврат КонецЕсли;
   Для каждого Подветка Из Ветка.Строки Цикл
       ТЗвДЗ_ПосчитатьИтогиРекурсивно(Подветка, МассивКолонокСумм, Ложь)
   КонецЦикла;
   Если не Корень Тогда
       Для каждого Инд Из МассивКолонокСумм Цикл
           Ветка[Инд] = Ветка.Строки.Итог(Инд)
       КонецЦикла;
   КонецЕсли;
КонецПроцедуры
3 clappa
 
30.06.06
20:38
(2) Сорри, перед ТЗ.Сортировать(КолонкиГрупп) должна быть строчка ТЗ.Свернуть(КолонкиГрупп, КолонкиСумм)
4 Mort
 
30.06.06
22:11
(3) Угу. Вот этой функции мне и не хватало в 17.28, уже в 3 раз пишу локально в отчетах а до общей обработки дело не дошло.
5 clappa
 
05.07.06
12:10
А вообще, с помощью построителя запросов можно сделать то же самое проще и гораздо быстрее:
Книга знаний: v8: Ускорение типовой свертки таблиц значений в 1С80
6 Mort
 
05.07.06
12:12
ТЗ в качестве источника данных не идет в релизах после 12-го кажется..
7 clappa
 
06.07.06
17:54
(6) Вроде идет.

ПЗ = Новый ПостроительЗапроса;
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаЗначений);
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;

//Устанавливаем все группировочные колонки
ПЗ.ИсточникДанных.Колонки.Группировка1.Измерение = Истина;
ПЗ.ИсточникДанных.Колонки.Группировка2.Измерение = Истина;
...

//Устанавливаем все итоговые колонки
ПЗ.ИсточникДанных.Колонки.КолонкаСуммы1.Итог = "Сумма(КолонкаСуммы1)";
ПЗ.ИсточникДанных.Колонки.КолонкаСуммы2.Итог = "Сумма(КолонкаСуммы2)";
...

ПЗ.ЗаполнитьНастройки();
ПЗ.Выполнить();

ДеревоЗначений = ПЗ.Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);
ДеревоЗначений.ВыбратьСтроку();
AdBlock убивает бесплатный контент. 1Сергей