Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Класс "Запрос_СГоризонтальнойГруппировкой" (число прочтений - 5902 )
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Класс "Запрос_СГоризонтальнойГруппировкой"
29. Января 2007 :: 23:49
Печать  
Запрос_СГоризонтальнойГруппировкой
Описание:
Код
Выбрать все
Класс для работы с запросом и преврашения запроса с вертикальными группировками
в объект с горизонтальной группировкой.


Терминолокия:
"Результат": закамуфлированная под это слово таблица значений, содержащая данные
	по группировкам горизонтальным и вертикальным.
	Она перебирается специальными функциями и обходится только
	в том порядке, в котором она была изготовлена.
	результат представлен таблицей значений "гТаблицаГруппировок".
	Имейте это ввиду.
"Показатели": именованные числовые показатели по которым нужны итоги.



Интерфейс(функции):
Сгруппировать(псЗапрос, псГруппировки, псГоризонтальная, псПоказатели) Функция
	Описание:
		- превращает запрос в таблицу значений группировок (гТаблицаГруппировок)
    Параметры:
		псЗапрос: - входящий запрос;
		псГруппировки - вертикальные группировки запроса (не менее одной)
		псГоризонтальная - горизонтальная группировка запроса (обязательно)
		псПоказатели - Числовые показатели, которые будут суммироваться в горизонтальной
		группировке.
		* все параметры здесь обязательны.

НачатьВыборкуРезультатов() Функция
	Описание:
		- Начинает перебор результатов группирования.
		Фактически выполняет начало выборки строк:
		гТаблицаГруппировок.ВыбратьСтроки()
	Возвращает:
		0 - если в гТаблицаГруппировок нет строк, и
		1 - если они есть

ПолучитьРезультат(псЗначГруппировки, псНомГруппировки, псИдГруппировки) Функция
	Описание:
		- получает следующую строку из таблицы для обработки результатов
		(гТаблицаГруппировок.ПолучитьСтроку())
	Возвращает:
		0 - если больше нет строк
		1 - если получена следующая строка
	Параметры:
		- псЗначГруппировки: отдает значение текущей группировки
		- псНомГруппировки: отдает номер текущей группировки
		- псИдГруппировки: отдает идентификатор текущей группировки

НачатьОбходПоказателей() Функция
	Описание:
		После получения ВЕРТИКАЛЬНОЙ группировки нам бы хотелось получить показатели
		горизонтальной группировки. Эта функция начинает их выборку, фактически
		начиная перебирать строки в таблице значений горизонтальной группировки.
	Возвращает:
		1 - если есть значения в горизонтальной группировке
		0 - в противном случае

ПолучитьПоказатели_2(псЗначениеВертикальной, псПоказатель1, псПоказатель2) Функция
	Описание:
		Получает первые 2 показателя, если у вас показателей<= 2 и
		Значение горизонтальной группировки.
		Тем самым у Вас есть возможность проанализировать значение горизонтальной
		группировки	и поработать с показателями.
	Возвращает:
		1 - если получено следующее значение в горизонтальной группировке.
		0 - в противном случае
	Параметры:
		псЗначениеВертикальной: - значение вертикальной группировки
		псПоказатель1..псПоказатель2: значения показателей, как они указаны в
		параметре "псПоказатели" функции "Сгруппировать"

ПолучитьПоказатели_5(псЗначениеВертикальной, псПоказатель1, псПоказатель2,,,псПоказатель5)
Функция
	Описание:
		Получает первые 5 показателя, если у вас показателей<= 5 и
		Значение горизонтальной группировки.
		Тем самым у Вас есть возможность проанализировать значение горизонтальной
		группировки	и поработать с показателями.
	Возвращает:
		1 - если получено следующее значение в горизонтальной группировке.
		0 - в противном случае
	Параметры:
		псЗначениеВертикальной: - значение вертикальной группировки
		псПоказатель1..псПоказатель5:  значения показателей, как они указаны в
		параметре "псПоказатели" функции "Сгруппировать"

ПолучитьПоказатели_Списком(псЗначениеВертикальной, псСписПоказателей) Функция
	Описание:
		Получает все показатели, которые вы обозначены и
		Значение горизонтальной группировки.
		Тем самым у Вас есть возможность проанализировать значение горизонтальной
		группировки	и поработать с показателями.
	Возвращает:
		1 - если получено следующее значение в горизонтальной группировке.
		0 - в противном случае
	Параметры:
		псЗначениеВертикальной: - значение вертикальной группировки
		псСписПоказателей:  список значений в который упакованы
		значения показателей, как они указаны в
		параметре "псПоказатели" функции "Сгруппировать"
		Внимание!!!!! "Представление" у элемента списка это просто порядковый номер
		показателя в параметре "псПоказатели" функции "Сгруппировать".

НачатьОбходЗначенийГоризонтальной() Функция
	Описание:
		начинает обход таблицы со значениями горизонтальной группировки
		Фактически выполняет: гГоризонтГр_Значения.ВыбратьСтроки()
	Возрващает:
		0 - если нет строк и нечего перебирать
		1 - если перебор начат.

ПолучитьЗначениеГоризонтальной( псЗначениеВертикальной ) Функция
	Описание: получает значение горизонтальной группировки.
 

  

QVG.rar ( 17 KB | Загрузки )
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #1 - 29. Января 2007 :: 23:51
Печать  
+1
Код
Выбрать все
Пояснения.
1. По скольку данный класс работает с таблицами значений и перебирает
	данные последовательно, следовательно необходимо строго соблюдать
	порядок вызова методов в такой последовательности:

	// последовательность 1
	вЭкзКласса = СоздатьОбъект("ИмяДанногоКласса");
	вЭкзКласса.Сгруппировать()...
	вЭкзКласса.НачатьВыборкуРезультатов();
	Пока вЭкзКласса.ПолучитьРезультат() = 1 Цикл
		// Вывод начальной секции группировок
		вЭкзКласса.НачатьОбходПоказателей();
		Пока вЭкзКласса.{ПолучитьПоказатели_2|ПолучитьПоказатели_5|
		|ПолучитьПоказатели_Списком}() = 1 Цикл
		    // Присоединение справа секций "Показателей" группировок
		КонецЦикла;
	КонецЦикла;

	// последовательность 2
	вЭкзКласса.НачатьОбходЗначенийГоризонтальной();
	Пока вЭкзКласса.ПолучитьЗначениеГоризонтальной(псЗначениеГоризонтальной) = 1 Цикл
		....
	КонецЦикла;
 

  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #2 - 29. Января 2007 :: 23:56
Печать  
пример ипользования:
Код
Выбрать все
Процедура Сформировать()
	Перем Запрос, ТекстЗапроса, Таб;
	Запрос = СоздатьОбъект("Запрос");
	ТекстЗапроса =
	"//{{ЗАПРОС(Сформировать)
	|Период с ВыбНачПериода по ВыбКонПериода;
	|Фирма			= Регистр.ПартииТоваров.Фирма;
	|Товар			= Регистр.ПартииТоваров.Товар;
	|Статус			= Регистр.ПартииТоваров.Статус;
	|ОстатокТовара	= Регистр.ПартииТоваров.ОстатокТовара;
	|Оборот			= Регистр.ПартииТоваров.Оборот;
	|Агент			= Регистр.ПартииТоваров.Склад;
	|Клиент			= Регистр.ПартииТоваров.ТекущийДокумент.РасходнаяНакладная.Клиент;
	|Докум			= Регистр.ПартииТоваров.ТекущийДокумент;
	|Функция ОстатокТовараРасход= Расход(ОстатокТовара);
	|Функция ОборотСумма		= Сумма(Оборот);
	|Условие(Агент в ВыбАгент);
	|Условие(Клиент в ВыбКлиент);
	|Условие(Товар в ВыбТовар);
	//|Условие(Докум в вСписДокументов);
	|"//}}ЗАПРОС
	;

	Если гПалитра.ПостроитьГруппировкиЗапроса(ТекстЗапроса) = 0 Тогда
		Возврат;
	КонецЕсли;

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

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

	// Подготовка к заполнению выходных форм данными запроса
	Таб = СоздатьОбъект("Таблица");
	Таб.ИсходнаяТаблица("Таблица");

	// Заполнение полей "Заголовок"
	Состояние("Заполнение выходной таблицы...");

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

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

				СамоЗначениеГруппировки = ПечЗначениеГруппировки;
				вУровень = 1;
				Если ТипЗначенияСтр( СамоЗначениеГруппировки ) = "Справочник" Тогда
				    вУровень = СамоЗначениеГруппировки.Уровень();
				КонецЕсли;
				ПечЗначениеГруппировки = ?(вНомГруппировки>1, Формат("","С"+(вНомГруппировки*2+вУровень*2)) , Формат("","С"+((вУровень-1)*2))) +""+ПечЗначениеГруппировки;

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

			Если гЗапросСГорГр.НачатьОбходЗначенийГоризонтальной() = 1 Тогда
				Таб.ВывестиСекцию("Итого|Начало");
				ПечЗначениеГорГр = ""; вСписПоказателей = СоздатьОбъект("СписокЗначений");
				Пока гЗапросСГорГр.ПолучитьЗначениеГоризонтальной( ПечЗначениеГорГр, вСписПоказателей ) = 1 Цикл
					ПечОборот	= вСписПоказателей.ПолучитьЗначение(1);
					ПечРасход	= вСписПоказателей.ПолучитьЗначение(2);
				    Таб.ПрисоединитьСекцию("Итого|Показатели");
				КонецЦикла;  
			КонецЕсли;
		КонецЕсли;
	Иначе	  
		ПечЗначениеГруппировки = "Показатели";
		Таб.ВывестиСекцию("Шапка|Все");
		Таб.Опции(0,0,Таб.ВысотаТаблицы(),1);

		глДобавитьКСтроке(вСтрГруппировок,вСтрГоризонтальнаяГр,",");
		гЗапросСГорГр.УстановитьСписокГруппировок(вСтрГруппировок);
		вНомерГруппировки = 0; // обязательно "0" вначале
		вИдГруппировки = "";
		Пока гЗапросСГорГр.СканироватьЗапрос(Запрос,вНомерГруппировки, вИдГруппировки) = 1 Цикл
			вСекция = "Гр" + вНомерГруппировки;
			ПечЗначениеГруппировки = Запрос.ПолучитьАтрибут(вИдГруппировки);

			ПечРасход = Запрос.ОстатокТовараРасход;
			ПечОборот = Запрос.ОборотСумма;
			Таб.ВывестиСекцию(вСекция + "|Все");

		КонецЦикла;  
	КонецЕсли;
	Таб.ТолькоПросмотр(1);
	Таб.Показать("Сформировать", "");
КонецПроцедуры
 

  
Наверх
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #3 - 31. Января 2007 :: 22:42
Печать  
Кто нить сравнивал с классом из темы: "Горизонтальные группировки"
http://www.1cpp.ru/forum/YaBB.pl?num=1162579818
Может зря колотился?
  
Наверх
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #4 - 02. Февраля 2007 :: 12:15
Печать  
давно не использовал гор. группировки (сделал один универсальный отчет и забыл  Улыбка)
по поводу сравнения следующее мысли. для функционала:
1. вложенность гор.группировок больше 1-й.
2. возможность сортировки итоговой таблицы по ресурсу.
  

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



Сообщений: 2343
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #5 - 02. Февраля 2007 :: 12:25
Печать  
Bond писал(а) 02. Февраля 2007 :: 12:15:
давно не использовал гор. группировки (сделал один универсальный отчет и забыл  Улыбка)

Вот бы пощупать.
Цитата:
по поводу сравнения следующее мысли. для функционала:
1. вложенность гор.группировок больше 1-й.

А как их родимых выводить?
Цитата:
2. возможность сортировки итоговой таблицы по ресурсу.

Все сортировки в запросе указываются.
  
Наверх
IP записан
 
Bond
Full Member
***
Отсутствует



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #6 - 25. Февраля 2007 :: 10:00
Печать  
Цитата:
Вот бы пощупать.

отчет в приложении. работает по регистру обороты (воткнул в конфу сам).
но можно переписать подлюбой другой регистр.

принцып такой:
- есть список с вертикальными группировками.
- галочками отмечаются те, которые нужны.
- кнопками "вверх" и "вниз" устанавливается порядок раскрытия группировок
- кнопка "вправо" устанавливает текущее значение списка как гор.группировку (она видна под списком жирным текстом).
- там где ресурсы, отмечаем галочками те, которые нам нужны, они будут выводится в виде строки через "/"
- в поле настроек выбираешь "доп. инфо" - тогда будет расшифровываться часть значений группировок (за это отвечает функция "ДопИнфо")

- сначала формируется ТЗ с необходимыми данными (Функция  ПодготовитьТЗ) - это занимает большую часть времени. её то и хотел бы переписать под прямой запрос.
- потом идет сворачивание и все такое (по тексту видно)

в общем это был очень большой отчет по всем регистрам у меня в конфе, почистил как смог (что б легче было разобраться), но торопился - потому много не нужного. если что спрашивай.

используется ActiveText, прямые запросы через OLEDB (вобщето хотел переписать под прямые запросы весь текст, но не хватает знаний, и времени Злой )

если не будет хватать чегото для запуска - пиши, прикреплю.
  

___.rar ( 20 KB | Загрузки )

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



Сообщений: 106
Зарегистрирован: 01. Ноября 2006
Пол: Мужской
Re: Класс "Запрос_СГоризонтальнойГруппировкой"
Ответ #7 - 25. Февраля 2007 :: 10:17
Печать  
Цитата:
А как их родимых выводить?


например как во вложеном файле (набросал в экселе). имеет смысл для 2-х, может для 3-х группировок

может использоваться в отчетах с например такими задачами. Продажи по месяцам/неделям/дням в разрезе филиал/супервайзер/торговый агент, или остатки в разрезе поставщик/товарная группа/товар по склад/неделя/день. Вобщем мне несколько раз ставили такие задачи. сводил все в экселе руками (убивал по 2 дня на каждый отчет).
  

__.rar ( 140 KB | Загрузки )

работай с умом, а не до ночи!
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать