Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Горизонтальные группировки (число прочтений - 14855 )
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Горизонтальные группировки
03. Ноября 2006 :: 18:50
Печать  
столкнулся с задачей отчет с вертикальными и горизонтальными группировками.
если кто уже делал - подскажите плз!!!!
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #1 - 03. Ноября 2006 :: 19:53
Печать  
Это легко и непринужденно реализуется при помощи класса ИндексированнаяТаблица
Вот код класса КроссТаблица - наследника ИТЗ.
Код
Выбрать все
Перем ИТЗ; //:ИндексированнаяТаблица
Перем Колонки Экспорт; //:ИндексированнаяТаблица
Перем ИзмерениеКолонки;

Функция Сам(Конт) Возврат Конт; КонецФункции

//#if DEBUG
Процедура ПриОткрытии()
	Форма.Параметр._ПриОткрытии();
	Форма.Закрыть();
КонецПроцедуры
//#endif

Процедура Конструктор()
	ИТЗ=Сам(Контекст).ПолучитьБазовыйКласс("ИндексированнаяТаблица");
КонецПроцедуры	// Конструктор

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

Функция ВыбратьКолонки() Экспорт
	Возврат Колонки.ВыбратьСтроки();
КонецФункции	// ВыбратьКолонки

Функция ПолучитьКолонку() Экспорт
	в=Колонки.ПолучитьСтроку();
	Возврат в;
КонецФункции	// ПолучитьКолонку
 


А это пример использования - кусок кода из отчета с произвольным количеством вертикальных группировок не более 4-х и одной горизонтальной группировкой
Код
Выбрать все
Процедура Колонки(Табл,ИмяСекции)
	ТАб.ВывестиСекцию(ИмяСекции+"|Начало");
	КТ.ВыбратьКолонки();
	Пока КТ.ПолучитьКолонку()=1 Цикл
		К=Табл.ПолучитьЗначение(,"_"+КТ.Колонки.НомерСтроки);
		ТАб.ПрисоединитьСекцию(ИмяСекции+"|Колонка");
	КонецЦикла;
КонецПроцедуры	// Колонки

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

Процедура Сформировать()
//...................
	КТ=СоздатьОбъект("КроссТаблица");
	КТ.Построить(Запрос,СтрГруппировки,"Товар","Количество");
	КТ.ВыбратьСтроки();
	КТ.ПолучитьСтроку();
	Колонки(КТ,"Шапка");
	КТ.ВыбратьСтроки();
	ВывестиГруппировку(КТ,5-КоличествоГруппировок);
//..................
КонецПроцедуры
 

  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #2 - 03. Ноября 2006 :: 20:02
Печать  
Класс легко можно модифицировать для расчета итогов более чем по одному числовому ресурсу.
Можно также в параметре метода "Построить" указать более одного измерения для группировок по горизонтали, только итоги по горизонтальным группировкам посчитаны не будут. Зато в выборку колонок попадут все комбинации измерений, выбранных для группировки по вертикали, присутствующие в исходной таблице.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #3 - 03. Ноября 2006 :: 20:14
Печать  
Еще вариант - купить за 2,5 тыр Новейший Отчет у ИнфоСтарта.
И еще вариант - посмотреть как сделан отчет Список / КроссТаблица от Maniac'а.
Не самый быстрый вариант, имеет ограничение - один ресурс и одна горизонтальная группировка, но зато без всяких ВК Улыбка
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #4 - 04. Ноября 2006 :: 15:24
Печать  
to steban огромное спасибо!

только я 2 недели как начал изучать 1с++ и не все понимаю как использовать.
1. как подключить класс? (сохранить верхний кусок кода как КроссТаблица.ert и прописать все процедуры и функции в defcls.prn)? если можно подробнее или дай ссылку на информацию.
2. можно ли на базе этого кода делать таблицу например 10х3 (больше 3-х горизонтальных я так прикидывал нет смысла делать - никто не разберется в выходной таблице)
3. очень интересно как выглядит печатная форма! (можешь какртинку или mxl прицепить)


понимаю что напрягаю, но если это возможно, ответь пожалуйста.
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #5 - 04. Ноября 2006 :: 20:48
Печать  
to steban
кажись почти разобрался.
пару вопросов:
1. где вытащить значения группировок? (где ресурсы полял)
2. как увеличить вложеность горизонтальных группировок и количество ресурсов?
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #6 - 04. Ноября 2006 :: 20:49
Печать  
или может кто нибудь ещё знает?
подскажите плз!!!
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #7 - 05. Ноября 2006 :: 19:35
Печать  
Bond писал(а) 04. Ноября 2006 :: 20:48:
2. как увеличить вложеность горизонтальных группировок и количество ресурсов?

С ресурсами тривиально Улыбка
« Последняя редакция: 28. Ноября 2006 :: 12:57 - steban »  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #8 - 06. Ноября 2006 :: 08:16
Печать  
[quote author=steban link=1162579818/0#7 date=1162755340][quote author=Bond link=1162579818/0#5 date=1162673287]1. где вытащить значения группировок?[/quote]
[code]КТ.Колонки.Значение[/code]

горизонтальные выводит, а вертикальные как?
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #9 - 06. Ноября 2006 :: 08:23
Печать  
2. как увеличить вложеность горизонтальных группировок и количество ресурсов?[/quote]
С ресурсами тривиально :)

что для тебя тривиально то для меня "китайская грамота"
допускаю что примерно так

КТ.Построить(ТЗ,группировкаТЗ,ГорГруппировка,"Кол,Сумма,Прибыль")

а как их вытащить при выводе в таблицу?

Процедура Колонки(Табл,ИмяСекции)
     ТАб.ВывестиСекцию(ИмяСекции+"|Начало");
     КТ.ВыбратьКолонки();
      
     Пока КТ.ПолучитьКолонку()=1 Цикл
      //     назвВерт= ?????  (КТ.колонки.Значение - выводит пустую строку)
               назвГор=КТ.колонки.Значение;  // колонка Значение это горизонтальная группировка
           К=Табл.ПолучитьЗначение(,"_"+КТ.Колонки.НомерСтроки);
           ТАб.ПрисоединитьСекцию(ИмяСекции+"|Колонка");
     КонецЦикла;
КонецПроцедуры      // Колонки
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #10 - 28. Ноября 2006 :: 12:57
Печать  
steban писал(а) 05. Ноября 2006 :: 19:35:
Bond писал(а) 04. Ноября 2006 :: 20:48:
2. как увеличить вложеность горизонтальных группировок и количество ресурсов?

С ресурсами тривиально Улыбка

Вот и мне понадобилось больше одного ресурса.
Код класса КроссТаблица с возможностью получать итоги по нескольким ресурсам:
Код
Выбрать все
Перем ИТЗ; //:ИндексированнаяТаблица
Перем Колонки Экспорт; //:ИндексированнаяТаблица
Перем ИзмерениеКолонки;

Функция Сам(Конт) Возврат Конт; КонецФункции

//#if DEBUG
Процедура ПриОткрытии()
	Форма.Параметр._ПриОткрытии();
	Форма.Закрыть();
КонецПроцедуры
//#endif

Процедура Конструктор()
	ИТЗ=Сам(Контекст).ПолучитьБазовыйКласс("ИндексированнаяТаблица");
КонецПроцедуры	// Конструктор

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

Функция ВыбратьКолонки() Экспорт
	Возврат Колонки.ВыбратьСтроки();
КонецФункции	// ВыбратьКолонки

Функция ПолучитьКолонку() Экспорт
	в=Колонки.ПолучитьСтроку();
	Возврат в;
КонецФункции	// ПолучитьКолонку
 


  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #11 - 28. Ноября 2006 :: 16:01
Печать  
спасибо.
буду ждать пока понадобится несколько горизонтальных группировок Улыбка
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #12 - 03. Декабря 2006 :: 15:46
Печать  
to Steban
может не самый умный вопрос, а как сортировать колонки (горизонтальные группировки) и строки (вертикальные группировки)?
  

работай с умом, а не до ночи!
Наверх
 
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #13 - 30. Января 2007 :: 00:12
Печать  
steban писал(а) 03. Ноября 2006 :: 20:14:
Еще вариант - купить за 2,5 тыр Новейший Отчет у ИнфоСтарта.
И еще вариант - посмотреть как сделан отчет Список / КроссТаблица от Maniac'а.
Не самый быстрый вариант, имеет ограничение - один ресурс и одна горизонтальная группировка, но зато без всяких ВК Улыбка

+ еще один вариант: http://www.1cpp.ru/forum/YaBB.pl?num=1170114584/0
  
Наверх
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Горизонтальные группировки
Ответ #14 - 17. Апреля 2007 :: 17:17
Печать  
Очередной велосипед получился Улыбка
Вот, кстати, наткнулся на способ строить кросс-таблицы на T-SQL:
Dynamic CrossTabs using T-SQL.
Основная идея такая-же как и в классе КроссТаблица:
Для каждого значения горизонтальной группировки добавить в исходную таблицу столбец.
Процедура динамически формирует текст запроса исходя из количества выбранных запросом значений для столбцов.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать