Как получить запрос с итогами?

Дерево значенийСегодня разберём функцию, с помощью которой из обычной таблицы значений 1С можно получить результат запроса с итогами и построить дерево значений.

Это может быть полезно в некоторых практических задачах, таких как:

  • Построение отчёта
  • Иерархический просмотр данных, в том числе консолидированных значений
  • Обход элементов таблицы в заданном порядке.

Чтобы наглядно показать работу функции ПолучитьЗапросСИтогами была создана внешняя обработка 1С «Запрос с итогами». Скачать её можно по ссылке ниже.

Запрос с итогами 1С

При открытии обработки формируется таблица из следующих колонок:

  • НоменклатурнаяГруппа (группировочное поле)
  • Номенклатура
  • Количество (функция расчёта — количество)
  • Цена (функция расчёта — максимум)
  • Сумма (функция расчёта — сумма).

Колонки «Количество», «Цена», «Сумма» — используются для исчисления итогов. Группировать значения будем по номенклатурным группам. В обработке можно добавлять свои строки в таблицу «Товары», чтобы проверить как строится дерево значений. Построение дерева на вкладке «Дерево товаров» происходит при нажатии кнопки «Выполнить».

В функции ПолучитьЗапросСИтогами доступны следующие операции для расчёта итоговых значений:

  • СУММА – сложение значений
  • МИНИМУМ – минимум из представленных значений в группе
  • МАКСИМУМ – максимум из представленных значений в группе
  • КОЛИЧЕСТВО – количество позиций в группе
  • СРЕДНЕЕ – среднее из представленных значений.

Теперь рассмотрим код обработки 1С. Текст обработки приведён под управляемые формы. Для формирования запроса с итогами воспользуемся следующим кодом 1С:

1
2
3
ТЗТовары = Объект.Товары.Выгрузить();
ОбъектФормы = РеквизитФормыВЗначение("Объект");
РезультатЗапроса = ОбъектФормы.ПолучитьЗапросСИтогами(ТЗТовары, "НоменклатурнаяГруппа", "Количество, Цена, Сумма", "КОЛИЧЕСТВО, МАКСИМУМ, СУММА");

Выведем получившееся дерево значений:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ТоварыДерево = РеквизитФормыВЗначение("РеквизитДерево");
ТоварыДерево.Строки.Очистить();
 
ВыборкаНГ = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "НоменклатурнаяГруппа");
Пока ВыборкаНГ.Следующий() Цикл
	ВыборкаДЗ = ВыборкаНГ.Выбрать();
	ЗаписьДереваНГ = ТоварыДерево.Строки.Добавить();
	ЗаполнитьЗначенияСвойств(ЗаписьДереваНГ, ВыборкаНГ);
 
	Пока ВыборкаДЗ.Следующий() Цикл
		ЗаписьДереваДЗ = ЗаписьДереваНГ.Строки.Добавить();
		ЗаполнитьЗначенияСвойств(ЗаписьДереваДЗ, ВыборкаДЗ);
	КонецЦикла;
КонецЦикла;
 
ЗначениеВРеквизитФормы(ТоварыДерево, "РеквизитДерево");

Основная функция ПолучитьЗапросСИтогами:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Получает результат запроса с итогами по данной таблице.
//
// Параметры:
//	Таблица - <ТаблицаЗначений> - Таблица значений;
//	СтрокаГруппировки - <Строка> - Строка с именами полей, разделённых запятыми, группировок итогов;
//  СтрокаИтогов - <Строка> - Строка с именами, разделённых запятыми, вычисляемых полей итогов;
//	СпособВычисления - <Строка> - Способы вычисления полей итогов: СУММА, МИНИМУМ, МАКСИМУМ, КОЛИЧЕСТВО, СРЕДНЕЕ. 
//		Если этот параметр не указан, то по умолчанию будет использоваться функция СУММА;
//
// Возвращаемое значение:
//	<РезультатЗапроса> - Результат запроса с обходом элементов по заданным группировкам итогов.
//
Функция ПолучитьЗапросСИтогами(Таблица, СтрокаГруппировки, СтрокаИтогов, СпособВычисления = Неопределено) Экспорт
 
	МассивГруппировки = РазобратьСтрокуВМассивПоРазделителю(СтрокаГруппировки, , Истина);
	МассивИтогов = РазобратьСтрокуВМассивПоРазделителю(СтрокаИтогов, , Истина);
	МассивСпособовВычисления = ?(СпособВычисления = Неопределено, Неопределено, РазобратьСтрокуВМассивПоРазделителю(СпособВычисления, , Истина));
 
	ТекстВыборка = "";
	Для Каждого ЭлементКолонка Из Таблица.Колонки Цикл
		ТекстВыборка = ТекстВыборка + ",
	               |	Таблица." + ЭлементКолонка.Имя + " КАК " + ЭлементКолонка.Имя;
	КонецЦикла;
	ТекстВыборка = Сред(ТекстВыборка, 4);
 
	ТекстГруппировка = "";
	ТекстПорядок = "";
	Для Каждого ЭлементГруппировки Из МассивГруппировки Цикл
		ТекстГруппировка = ТекстГруппировка + ",
			|	" + ЭлементГруппировки;
		ТекстПорядок = ТекстПорядок + ",
			|	" + ЭлементГруппировки;
	КонецЦикла;
	ТекстГруппировка = Сред(ТекстГруппировка, 4);
	ТекстГруппировка = ?(ПустаяСтрока(ТекстГруппировка), "", "ПО
	               |	" + ТекстГруппировка);
	ТекстПорядок = Сред(ТекстПорядок, 4);
	ТекстПорядок = ?(ПустаяСтрока(ТекстПорядок), "", "УПОРЯДОЧИТЬ ПО
	               |	" + ТекстПорядок);
 
	ТекстИтоги = "";
	Индекс = 0;
	Для Каждого ЭлементИтоги Из МассивИтогов Цикл
		Способ = ?(МассивСпособовВычисления = Неопределено, "СУММА", МассивСпособовВычисления[Индекс]);
		ТекстИтоги = ТекстИтоги + ",
			|	" + Способ + "(" + ЭлементИтоги + ")";	
		Индекс = Индекс + 1;
	КонецЦикла;
	ТекстИтоги = Сред(ТекстИтоги, 4);
	ТекстИтоги = ?(ПустаяСтрока(ТекстИтоги), "ИТОГИ
				   |", "ИТОГИ
	               |	" + ТекстИтоги);
 
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	               |	" + ТекстВыборка + "
	               |ПОМЕСТИТЬ Таблица
	               |ИЗ
	               |	&Таблица КАК Таблица
	               |;
	               |
	               |////////////////////////////////////////////////////////////////////////////////
	               |ВЫБРАТЬ
	               |	" + ТекстВыборка + "
	               |ИЗ
	               |	Таблица КАК Таблица
				   |
				   |" + ТекстПорядок + "
	               |" + ТекстИтоги + "
	               |" + ТекстГруппировка;
	Запрос.УстановитьПараметр("Таблица", Таблица);			   
	РезультатЗапроса = Запрос.Выполнить();
 
	Возврат РезультатЗапроса;
КонецФункции;

Смело используйте этот код 1С для реализации своих проектов! Если в коде имеются баги (ошибки), просьба сообщить об этом, написав в комментариях ниже.

Скачать