Каталог решений - Итоги по объединенной совокупности группировок в запросе

Итоги по объединенной совокупности группировок в запросе

Итоги по объединенной совокупности группировок в запросе

В наличии

Способ формирования итогов в запросе по совокупности группировок, объединенных в единый набор, при помощи функции АВТОНОМЕРЗАПИСИ.

Категория:

Описание

Задача перевода "плоской" информации в "иерархическую" встает перед разработчиком 1С достаточно часто. В качестве примера такой задачи можно привести случай, когда мы имеем таблицу с данными о контрагентах и проданных им товарах, из данных которой нам нужно сформировать документы реализации. Каждая реализация должна объединять в себе строки по одному контрагенту, и все эти строки должны формировать табличную часть товаров документа.

Такая задача решается легко, путем использования ключевого слова ИТОГИ в запросе:

ВЫБРАТЬ
	ТаблицаТоваров.Контрагент КАК Контрагент,
	ТаблицаТоваров.Номенклатура КАК Номенклатура,
	ТаблицаТоваров.Количество КАК Количество,
	ТаблицаТоваров.Сумма КАК Сумма
ИЗ
	&ТаблицаТоваров КАК ТаблицаТоваров
ИТОГИ
	СУММА(Сумма)
ПО
	Контрагент

Затем результат запроса обходим по группировкам и создаем документы:

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

Пока ВыборкаПоКонтрагентам.Следующий() Цикл
	
	// Заполнение шапки
	
	ДетальныеЗаписи = ВыборкаПоКонтрагентам.Выбрать();
	
	Пока ДетальныеЗаписи.Следующий() Цикл
		// Заполнение ТЧ товаров
	КонецЦикла;
	
КонецЦикла;

Усложним задачу, добавив в исходную таблицу колонку "Договор".

Теперь каждая отдельная реализация должна объединять строки с одинаковым набором значений Контрагент-Договор. Для того чтобы это учесть, можно добавить в запрос итоги по полю договор. При обходе результата запроса у нас появится еще один вложенный цикл.

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

Пока ВыборкаПоКонтрагентам.Следующий() Цикл

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

	Пока ВыборкаПоДоговорам.Следующий() Цикл
		
		// Заполнение шапки
		
		ДетальныеЗаписи = ВыборкаПоДоговорам.Выбрать();
		
		Пока ДетальныеЗаписи.Следующий() Цикл
			// Заполнение ТЧ товаров
		КонецЦикла;
		
	КонецЦикла;
	
КонецЦикла;

Добавим в таблицу еще пару полей. Например, "Организация" и "Грузоотправитель". Реализация теперь создается на каждый набор Организация-Контрагент-Грузоотправитель-Договор. Если действовать тем же методом, добавляя итоговые поля в запрос, при обработке результата мы получим цикл пятого уровня вложенности:

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

Пока ВыборкаПоОрганизациям.Следующий() Цикл

	ВыборкаПоКонтрагентам = ВыборкаПоОрганизациям.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

	Пока ВыборкаПоКонтрагентам.Следующий() Цикл

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

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

			Пока ВыборкаПоДоговорам.Следующий() Цикл
				
				// Заполнение шапки
				
				ДетальныеЗаписи = ВыборкаПоДоговорам.Выбрать();
				
				Пока ДетальныеЗаписи.Следующий() Цикл
					// Заполнение ТЧ товаров
				КонецЦикла;
				
			КонецЦикла;
			
		КонецЦикла;
		
	КонецЦикла;
	
КонецЦикла;

Вид этой конструкции вызывает, мягко говоря, негативные эмоции.
А ведь группировочных полей может быть еще больше…
Для того чтобы избежать матрешки из циклов, нужно присвоить каждой связке Организация-Контрагент-Грузоотправитель-Договор какой-то идентификатор и производить группировку по всему набору, а не по каждому полю в отдельности. В рамках языка запросов это можно сделать при помощи функции АВТОНОМЕРЗАПИСИ. Для нашего примера запрос должен выглядеть так:

ВЫБРАТЬ
	ТаблицаТоваров.Организация КАК Организация,
	ТаблицаТоваров.Контрагент КАК Контрагент,
	ТаблицаТоваров.Грузополучатель КАК Грузополучатель,
	ТаблицаТоваров.Договор КАК Договор,
	ТаблицаТоваров.Номенклатура КАК Номенклатура,
	ТаблицаТоваров.Количество КАК Количество,
	ТаблицаТоваров.Сумма КАК Сумма
ПОМЕСТИТЬ ВТ_ИсходнаяТаблица
ИЗ
	&ТаблицаТоваров КАК ТаблицаТоваров

ИНДЕКСИРОВАТЬ ПО
	Организация,
	Контрагент,
	Грузополучатель,
	Договор
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ВТ_ИсходнаяТаблица.Организация КАК Организация,
	ВТ_ИсходнаяТаблица.Контрагент КАК Контрагент,
	ВТ_ИсходнаяТаблица.Грузополучатель КАК Грузополучатель,
	ВТ_ИсходнаяТаблица.Договор КАК Договор,
	АВТОНОМЕРЗАПИСИ() КАК ИдентификаторНабора
ПОМЕСТИТЬ ВТ_РеквизитыШапки
ИЗ
	ВТ_ИсходнаяТаблица КАК ВТ_ИсходнаяТаблица

ИНДЕКСИРОВАТЬ ПО
	Организация,
	Грузополучатель,
	Контрагент,
	Договор
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ_РеквизитыШапки.ИдентификаторНабора КАК ИдентификаторНабора,
	ВТ_РеквизитыШапки.Организация КАК Организация,
	ВТ_РеквизитыШапки.Контрагент КАК Контрагент,
	ВТ_РеквизитыШапки.Грузополучатель КАК Грузополучатель,
	ВТ_РеквизитыШапки.Договор КАК Договор,
	ВТ_ИсходнаяТаблица.Номенклатура КАК Номенклатура,
	ВТ_ИсходнаяТаблица.Количество КАК Количество,
	ВТ_ИсходнаяТаблица.Сумма КАК Сумма
ИЗ
	ВТ_РеквизитыШапки КАК ВТ_РеквизитыШапки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ИсходнаяТаблица КАК ВТ_ИсходнаяТаблица
		ПО ВТ_РеквизитыШапки.Организация = ВТ_ИсходнаяТаблица.Организация
			И ВТ_РеквизитыШапки.Контрагент = ВТ_ИсходнаяТаблица.Контрагент
			И ВТ_РеквизитыШапки.Грузополучатель = ВТ_ИсходнаяТаблица.Грузополучатель
			И ВТ_РеквизитыШапки.Договор = ВТ_ИсходнаяТаблица.Договор
ИТОГИ
	МАКСИМУМ(Организация),
	МАКСИМУМ(Контрагент),
	МАКСИМУМ(Грузополучатель),
	МАКСИМУМ(Договор),
	СУММА(Сумма)
ПО
	ИдентификаторНабора

Воспользовавшись функцией АВТОНОМЕРЗАПИСИ, мы идентифицировали все наборы Организация-Контрагент-Грузоотправитель-Договор и выполнили группировку в рамках целого набора, а не по каждому полю отдельно.
Код обработки такого запроса выглядит так же просто, как и в первоначальном случае с единственным группировочным полем:

ВыборкаПоНаборам = Запрос.Выполнить.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаПоНаборам.Следующий() Цикл
	
	// Заполнение шапки
	
	ДетальныеЗаписи = ВыборкаПоНаборам.Выбрать();
	
	Пока ДетальныеЗаписи.Следующий() Цикл
		// Заполнение ТЧ товаров
	КонецЦикла;
	
КонецЦикла;

 

has been added to your cart:
Оформление заказа