Имя: Пароль:
1C
 
1С 7.7. Группировка ТаблицыЗначений
,
0 es3000
 
06.07.15
22:57
Нужно сгруппировать таблицу значений. Типа как ИндексированнаяТаблица в 1С++.

Вот здесь (http://www.1cpp.ru/forum/YaBB.pl?num=1436179378) посоветовали воспользоваться классом "ТаблицаГруппировок", который это делает.
Вот ссылка откуда брал класс:
http://itland.ru/forum//index.php?showtopic=15709&st=0&p=83328&#entry83328

Только я не понял как им пользоваться - нету описания.

лТГ.ВНачалоВыборки();
Пока лТГ.Группировка("Склад") = 1 Цикл
    Пока лТГ.Группировка("Номенклатура") = 1 Цикл
               хххх
    КонецЦикла;
КонецЦикла;


Кто-нибудь может помочь?
Что надо в цикле писать?
1 Злопчинский
 
07.07.15
00:42
ТЗсклад = СоздатьОбъект("таблицаЗначений");
ТЗ.Выгрузить(ТЗсклад,,,"Склад");
ТЗСклад.Свернуть("Склад",);

ТЗсклад.ВыбратьСтроки();
Пока ТЗСклад.ПолучитьСтроку()=1 Цикл
  ТекущийСклад = ТЗСклад.Склад;
  ТЗраб = глОтобратьПоКОлонке(ТЗ,"Склад",ТекущийСклад);
  ТЗраб.ВыбратьСтроки();
  Пока ТЗраб.ПолучитьСтроку()=1 Цикл
     ТекНОменклатура = ТЗраб.Номенклатура;
  ....


Можно сделать рекурсивный алгоритм.
На вход можно подать строку с идентификаторами группировок, и в рекурсии отфильтровывать штатными средствами.
Я так делал - работает, кушать не просит...
2 es3000
 
07.07.15
09:15
(1) "глОтобратьПоКолонке" - это твоя функция?

то есть получается что итоги по группировкам нигде не хранятся, а рассчитываются "на лету"?
3 ДенисЧ
 
07.07.15
09:17
А почему бы не взять саму индексированную таблицу?
4 es3000
 
07.07.15
09:19
(3) для ИТ нужно подключать 1С++,
клиент не хочет использовать внешние компоненты,
вот один вредный такой попался
5 dk
 
07.07.15
09:31
непонятненько новый класс можно взять а индексированную таблицу нельзя?
6 Масянька
 
07.07.15
09:31
(4) А ты не говори про ВК... Просто - сделай.
7 dk
 
07.07.15
09:33
если количество группировок заранее известно, то тупо делаешь несколько ТЗ и группируешь до нужного уровня, муторно некрасиво но работает
8 vcv
 
07.07.15
09:35
У меня в конфе валяется такая функция, давно-давно взятая непонятно откуда. Вроде еще работает, не всё заменено на ИндексированнуюТаблицу

Функция СоздатьГруппировкиВТаблице(табОтчета,Группировки,КолонкиДляСуммирования,ПоследняяГруппировка=0) экспорт
    Перем Тип,Длина,Точность;      
    Перем зн1[20],ИдКолонки[20];
    // подразумеваем, что макс. число группировок 20. должно хватить

    Состояние("Расчет итогов по группировкам...");
    
    //счетнач=_GetPerformanceCounter();
    Если табОтчета.КоличествоСтрок()=0 тогда // чтобы не глюкнуло для пустой            
        таб=ПолучитьПустоеЗначение();
        табОтчета.Выгрузить(таб);
        возврат таб;
    КонецЕсли;    
    
    сзГруппировки=СоздатьОбъект("СписокЗначений");
    сзГруппировки.ИзСтрокиСРазделителями(""""+СтрЗаменить(Группировки,",",""",""")+"""");
    сзКолонкиДляСуммирования=СоздатьОбъект("СписокЗначений");
    сзКолонкиДляСуммирования.ИзСтрокиСРазделителями(""""+СтрЗаменить(КолонкиДляСуммирования,",",""",""")+"""");
    //сзТаблицы=СоздатьОбъект("СписокЗначений");
    сзГруппировки1=СоздатьОбъект("СписокЗначений");
    
    ПройденныеКолонки="";
    Для с=1 по сзГруппировки.РазмерСписка() цикл  
        ТекКолонка=сзГруппировки.ПолучитьЗначение(с);
        ПройденныеКолонки=ПройденныеКолонки+?(ПустоеЗначение(ПройденныеКолонки)=1,"",",")+ТекКолонка;
        сзГруппировки1.ВставитьЗначение(1,ПройденныеКолонки);
    КонецЦикла;    

    ПредТаб=ПолучитьПустоеЗначение();
    табОтчета.Выгрузить(ПредТаб);
    Для с=1 по сзГруппировки1.РазмерСписка() цикл  
        ТекКолонки=сзГруппировки1.ПолучитьЗначение(с);
        
        сзТекКолонки=СоздатьОбъект("СписокЗначений");
        сзТекКолонки.ИзСтрокиСРазделителями(""""+СтрЗаменить(ТекКолонки,",",""",""")+"""");
        КолТекКолонок=сзТекКолонки.РазмерСписка();
        
        
        ПредТаб.Сортировать(ТекКолонки); // эта сортировка ускоряет сдвиг строк "чужих" в блоке  
        // (весьма интересный эффект). в противном случае достаточно было ПредТаб сортировать один раз (при создании)
        
        таб=ПолучитьПустоеЗначение();
        ПредТаб.Выгрузить(таб);
        таб.Свернуть(ТекКолонки,КолонкиДляСуммирования);
        //таб.Сортировать(ТекКолонки);  // предполагаем, что сворачивание не нарушает сортировки
        
        Если (ПоследняяГруппировка=0) и (с=1) тогда
            ПредТаб=таб; продолжить;    // не создаем вложенную таблицу в последней таб
        КонецЕсли;

        таб.НоваяКолонка("ВложеннаяТаблица","ТаблицаЗначений");
        шабл_ВТ=ПолучитьПустоеЗначение();
        ПредТаб.Выгрузить(шабл_ВТ,1,1);
        шабл_ВТ.УдалитьСтроки();
            
        НачСтр=1;
        таб.ВыбратьСтроки();
        Пока таб.ПолучитьСтроку()=1 цикл
            текВТ=ПолучитьПустоеЗначение();
            шабл_ВТ.Выгрузить(текВТ);
            таб.ВложеннаяТаблица=текВТ;

            Для к=1 по КолТекКолонок цикл
                ТекИдКолонки=сзТекКолонки.ПолучитьЗначение(к);
                зн1[к]=таб.ПолучитьЗначение(таб.НомерСтроки,ТекИдКолонки);
                ИдКолонки[к]=ТекИдКолонки;
            КонецЦикла;    

            ПереместитьБлок=0;  
            СтрСтрокиСОтличиямиВнутриБлока="";
            // бывает так, что представление у разных объектов одинаково
            // и при этом в таблице они могут перемешиваться друг с другом в порядке следования
            // т.е. метод сортировать() так работает
            // мы запомним такие строки, а замем переместим их все за пределы блока
            
            БылоБезОтличий=0; ПрерватьПеребор=0;
            Для i=НачСтр по ПредТаб.КоличествоСтрок() цикл
                //Если i>ПредТаб.КоличествоСтрок() тогда прервать КонецЕсли;

                НайденоОтличие=0;
                Для кк=1 по КолТекКолонок цикл
                    // колонки быстрее просматривать в обратном порядке  
                    к=КолТекКолонок-кк+1;
                    //ТекИдКолонки=ИдКолонки[к];
                    //ИдКолонки=сзТекКолонки.ПолучитьЗначение(к);
                    зн2=ПредТаб.ПолучитьЗначение(i,ИдКолонки[к]);
                    Если зн1[к]=зн2 тогда продолжить КонецЕсли;
                    Если ПустоеЗначение(зн1[к])+ПустоеЗначение(зн2)=2 тогда продолжить КонецЕсли;
                              
                    Если ""+зн1[к]<>""+зн2 тогда
                        // если представления отличаются, то значит здесь своих уже не будет
                        // если уже были (поскольку сортируется ПредТаб по представлению)
                        ПрерватьПеребор=1;      
                    Иначе                
                        СтрСтрокиСОтличиямиВнутриБлока=""+i+?(СтрСтрокиСОтличиямиВнутриБлока="","",","+СтрСтрокиСОтличиямиВнутриБлока);
                    КонецЕсли;    
                    НайденоОтличие=1; прервать;
                КонецЦикла;    
                
                
                Если НайденоОтличие=1 тогда
                
                    Если БылоБезОтличий*ПрерватьПеребор=1 тогда
                        ПереместитьБлок=1;  
                    Иначе    
                        продолжить            
                    КонецЕсли;
                    
                ИначеЕсли i=ПредТаб.КоличествоСтрок() тогда
                    ПереместитьБлок=1;  
                КонецЕсли;
                
                Если ПереместитьБлок=1 тогда
                    
                    КолЧужихВБлоке=0;
                    // перемещаем строки, в которых были отличия, после текущего блока
                    Если СтрСтрокиСОтличиямиВнутриБлока<>"" тогда
                        
                        //Сообщить ("есть чужие в блоке!"+", "+зн1[1]);      
                        //ПредТаб.ВыбратьСтроку();
                        сз_строки_с_отличиями_внутри_блока =СоздатьОбъект("СписокЗначений");
                        сз_строки_с_отличиями_внутри_блока.ИзСтрокиСРазделителями(""""+СтрЗаменить(СтрСтрокиСОтличиямиВнутриБлока,",",""",""")+"""");
                        
                        КолЧужихВБлоке=сз_строки_с_отличиями_внутри_блока.РазмерСписка();
                        Для ii=1 по КолЧужихВБлоке цикл
                            ТекЧужаяСтрока=0+сз_строки_с_отличиями_внутри_блока.ПолучитьЗначение(ii);
                            ПредТаб.СдвинутьСтроку(i-ТекЧужаяСтрока-ii,ТекЧужаяСтрока);
                            
                        КонецЦикла;            
                    КонецЕсли;    
                    
                    НачСтрокаВыгрузки=НачСтр;
                    НачСтр=i-КолЧужихВБлоке;
                    КонСтрокаВыгрузки=НачСтр-НайденоОтличие;

                    ПредТаб.Выгрузить(текВТ,НачСтрокаВыгрузки,КонСтрокаВыгрузки);    
                    
                    
                    прервать;
                КонецЕсли;
                
                БылоБезОтличий=1;
            КонецЦикла;    
        КонецЦикла;    
        
        ПредТаб=таб;
        
    КонецЦикла;

    //счеткон=_GetPerformanceCounter();
    //сообщить ("время запроса: "+(счеткон-счетнач));

    Состояние("");
    
    возврат таб;    

КонецФункции
9 es3000
 
07.07.15
09:37
(5) я собирался взять новый класс и переделать его на обычные процедуры
10 es3000
 
07.07.15
09:37
(8) спасибо, буду разбираться
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой