рубрики: Запросы | Дата: 2 ноября, 2016
Достаточно часто после выполнения запроса к таблице, в момент обхода результата
запроса есть необходимость расположить эти данные иерархически.
Давайте сразу рассмотрим пример для наглядности. Пусть у нас есть некая таблица с ценами товаров
на дату в разрезе складов:
Период | Склад | Товар | Цена |
---|---|---|---|
01.01.2016 | Центральный | Ручка | 30 |
01.01.2016 | Офис | Карандаш | 15 |
05.01.2016 | Центральный | Ручка | 45 |
10.01.2016 | Офис | Карандаш | 25 |
15.01.2016 | Центральный | Степлер | 150 |
17.01.2016 | Офис | Дырокол | 200 |
А мы хотим при обходе результата запроса представить данные вот в таком виде:
Центральный | |||
---|---|---|---|
Ручка | |||
01.01.2016 | 30 | ||
05.01.2016 | 45 | ||
Степлер | |||
15.01.2016 | 150 | ||
Офис | |||
Карандаш | |||
01.01.2016 | 15 | ||
10.01.2016 | 25 | ||
Дырокол | |||
17.01.2016 | 200 |
Реализуется это с использованием итогов в запросе, а при обходе результата
запроса используются вложенные выборки с типом обхода ПоГруппировкам.
Чтобы была возможность воспроизвести описанную ситуацию в любой конфигурации,
и самостоятельно поэксперементировать, давайте с помощью запроса создадим
приведенную выше таблицу и поместим ее во временную:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 1) КАК Период,
| ""Центральный"" КАК Склад,
| ""Ручка"" КАК Товар,
| 30 КАК Цена
|ПОМЕСТИТЬ ВТ_Цена
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 1),
| ""Офис"",
| ""Карандаш"",
| 15
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 5),
| ""Центральный"",
| ""Ручка"",
| 45
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 10),
| ""Офис"",
| ""Карандаш"",
| 25
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 25),
| ""Центральный"",
| ""Степлер"",
| 150
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 17),
| ""Офис"",
| ""Дырокол"",
| 200
|";
Теперь выберем все поля из этой временной таблицы с использованием итогов по
полям «Склад» и «Товар»:
|ВЫБРАТЬ
| ВТ_Цена.Период,
| ВТ_Цена.Склад КАК Склад,
| ВТ_Цена.Товар КАК Товар,
| ВТ_Цена.Цена
|ИЗ
| ВТ_Цена КАК ВТ_Цена
|ИТОГИ ПО
| Склад,
| Товар";
И наконец выполним запрос и сделаем обход результата запроса в нескольких вложенных
выборках. Замечу, что в последней вложенной выборке обход делается уже без группировки.
Результат = Запрос.Выполнить();
ВыборкаСклад = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаСклад.Следующий() Цикл
Сообщить(ВыборкаСклад.Склад);
ВыборкаТовар = ВыборкаСклад.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаТовар.Следующий() Цикл
Сообщить(" " + ВыборкаТовар.Товар);
Выборка = ВыборкаТовар.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(" " + Выборка.Период + "; " + Выборка.Цена);
КонецЦикла;
КонецЦикла;
КонецЦикла;
Ну и теперь соберем все кусочки кода в одно целое. Можно вставить этот код в обработку
и посмотреть как он работает. Этот код работает в управляемых формах.
&НаСервере
Процедура ВыполнитьЗапрос()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 1) КАК Период,
| ""Центральный"" КАК Склад,
| ""Ручка"" КАК Товар,
| 30 КАК Цена
|ПОМЕСТИТЬ ВТ_Цена
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 1),
| ""Офис"",
| ""Карандаш"",
| 15
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 5),
| ""Центральный"",
| ""Ручка"",
| 45
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 10),
| ""Офис"",
| ""Карандаш"",
| 25
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 25),
| ""Центральный"",
| ""Степлер"",
| 150
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| ДАТАВРЕМЯ(2016, 1, 17),
| ""Офис"",
| ""Дырокол"",
| 200
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Цена.Период,
| ВТ_Цена.Склад КАК Склад,
| ВТ_Цена.Товар КАК Товар,
| ВТ_Цена.Цена
|ИЗ
| ВТ_Цена КАК ВТ_Цена
|ИТОГИ ПО
| Склад,
| Товар";
Результат = Запрос.Выполнить();
ВыборкаСклад = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаСклад.Следующий() Цикл
Сообщить(ВыборкаСклад.Склад);
ВыборкаТовар = ВыборкаСклад.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаТовар.Следующий() Цикл
Сообщить(" " + ВыборкаТовар.Товар);
Выборка = ВыборкаТовар.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(" " + Выборка.Период + "; " + Выборка.Цена);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ОК(Команда)
ВыполнитьЗапрос();
КонецПроцедуры
Добавить комментарий