- Выборка из результата запроса всех вошедших в него значений группировок
- Основные приемы работы
- Обход по группировкам и получение общего итога
- ОбходРезультатаЗапроса ПоГруппировкам и вывод в табличный документ
- ОбходРезультатаЗапроса ПоГруппировкам и вывод в табличный документ
- Конструктор запроса
- Пример кода
Выборка из результата запроса всех вошедших в него значений группировок
При обходе результата запроса нередко возникает необходимость получения всех значений группировок внутри какой-либо другой группировки. Такая возможность может понадобиться, например, при выводе кросс отчета. Для обеспечения такой возможности в объекте ВыборкаИзРезультатаЗапроса предусмотрен третий параметр функции Выбрать().
Рассмотрим пример. Пусть нам необходимо получить кросс-отчет по остаткам номенклатуры на различных складах. Номенклатуру необходимо вывести в строках, склады — в колонках. Запрос для получения остатков будет выглядеть так:
ВЫБРАТЬ
УчетНоменклатурыОстатки.Номенклатура КАК Номенклатура,
УчетНоменклатурыОстатки.Номенклатура.Представление,
УчетНоменклатурыОстатки.Склад КАК Склад,
УчетНоменклатурыОстатки.Склад.Представление,
УчетНоменклатурыОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
РегистрНакопления.УчетНоменклатуры.Остатки КАК УчетНоменклатурыОстатки
ИТОГИ СУММА(КоличествоОстаток) ПО
ОБЩИЕ,
Номенклатура,
Склад
Для обхода номенклатуры воспользуемся выборкой из результата запроса:
ВыборкаНоменклатура = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Номенклатура»);
Пока ВыборкаНоменклатура.Следующий() Цикл
ОбластьНоменклатура.Параметры.Заполнить(ВыборкаНоменклатура);
ТабДок.Вывести(ОбластьНоменклатура);
Для обхода внутри номенклатуры всех складов, присутствующих в результате запроса, получим вложенную выборку от выборки номенклатуры, с указанием третьего параметра «ВСЕ»:
ВыборкаСклад = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Склад», «ВСЕ»);
Пока ВыборкаСклад.Следующий() Цикл
ОбластьСклад.Параметры.Заполнить(ВыборкаСклад);
ТабДок.Присоединить(ОбластьСклад);
КонецЦикла;
В случае если необходимо построить несколько отдельных кросс-таблиц для каждого значения некой группировки, необходимо в качестве третьего параметра выборки указать имя группировки, внутри которой необходимо получить все значения, вошедшие в запрос. Пример:
ВыборкаСклад = ВыборкаНоменклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, «Склад», «Организация»);
В данном примере будут получены все значения складов, присутствующие в ранее выбранной организации.
Пример вывода кросс-отчета с использованием выборок из результата запроса показан в демонстрационной конфигурации «Примеры ИТС», в отчете «ОстаткиНаСкладах».
Источник
Основные приемы работы
Основные приемы работы с запросами во встроенном языке 1С:Предприятия удобнее всего рассматривать на примерах. Приведем типичный пример использования запроса:
Запрос = Новый Запрос ( «ВЫБРАТЬ Товар.Наименование Наименование, |Товар.Родитель.Наименование НаименованиеРодителя |ИЗ Справочник.Товары Товар» ); // Выполним запрос и запишем результат в переменную РезультатЗапроса. // Получим выборку из результата запроса. // Пока в выборке есть записи . |
Как видно из этого примера, работа с запросом ведется при помощи трех основных объектов:
- Запрос – объект, выполняющий сам запрос. Представлен в примере переменной с именем Запрос.
- РезультатЗапроса – объект, содержащий полученные при выполнении запроса данные. Представлен в примере переменной с именем РезультатЗапроса.
- ВыборкаИзРезультатаЗапроса – объект, позволяющий обходить (т.е. перебрать) записи из результата. Представлен в примере переменной с именем Выборка.
Рассмотрим подробнее объект ВыборкаИзРезультатаЗапроса. Для этого нам понадобится следующий текст запроса:
ВЫБРАТЬ
Товар, Количество
ИЗ
Документ.РасхНакл.Состав
УПОРЯДОЧИТЬ ПО Товар
ИТОГИ Сумма(Количество) ПО Товар Иерархия
Его результат представлен в таблице:
N
Товар
Количество
1
Сантехника
104
11
Мебель
134
В эту таблицу добавлена колонка «N», которой нет в результате запроса, но которая будет использоваться нами в дальнейшем для идентификации записи в результате. Итоговые записи в таблице выделены курсивом, итоговые записи для иерархических уровней справочника выделены жирным шрифтом.
Способы обхода результата запроса
Линейный обход результата
Первый, и самый простой способ обхода – линейный. При линейном обходе выборка будет выдавать записи в той последовательности, в которой они располагаются в результате запроса. В нашем примере это будут записи с номерами 1, 2, 3, 4, 5 и так далее до записи с номером 20.
Для получения линейной выборки из результата необходимо вызвать метод Выбрать объекта РезультатЗапроса без параметров, либо с параметром ОбходРезультатаЗапроса.Прямой.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . Прямой ; Выборка1 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; // что равнозначно записи Выборка1 = РезультатЗапроса . Выбрать ( ) ; |
Иерархический обход результата
Следующий способ обхода результата – иерархический. При данном обходе обходятся только записи, находящиеся на одном уровне. Для получения иерархической выборки из результата необходимо вызвать метод Выбрать() объекта РезультатЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппировкамСИерархией.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . ПоГруппировкамСИерархией ; Выборка2 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; |
Выборка из результата с иерархическим обходом в нашем примере обойдет только записи с номерами 1 и 11, так как только эти две записи находятся на самом верхнем уровне. Проиллюстрируем это, представив наш результат в виде дерева, где узлами будут итоговые записи, а листьями дерева будут детальные записи. Вот что у нас получится:
Из этого рисунка видно, что именно записи с номерами 1 и 11, и только они находятся на первом уровне дерева, в результате чего только они и попадают в первый проход иерархической выборки.
Возникает вопрос, как получать остальные записи результата запроса. Для этого у объекта ВыборкаИзРезультатаЗапроса можно получить еще одну выборку, которая будет обходить подчиненные записи текущей записи выборки. В нашем примере в момент, когда объект Выборка2 будет позиционирован на запись с номером 1, мы запросим у него иерархическую выборку. Таким образом, мы получим выборку, которая нам вернет записи с номерами 2, 7. А когда Выборка2 будет спозиционирована на записи с номером 11, то полученная у нее иерархическая выборка вернет записи с номерами 12, 16. Так реализуется иерархический обход результатов запроса. Заметим, что у выборки можно получать вложенные выборки любого типа. Так, если бы мы запросили у Выборки2, спозиционированной на записи 1, линейную выборку, то с ее помощью мы бы получили записи с номерами записей со 2-го по 10-й. Проиллюстрируем описанную методику на примере.
Пример:
Процедура ВыполнитьЗапрос ( ) // Создадим запрос. Запрос = Новый Запрос ; // Установим текст запроса // Выполним запрос и запишем результат в переменную // Получим выборку из результата запроса. Процедура ВыдатьРекурсивно ( Выборка ) // Продолжим выборку подчиненных записей КонецЦикла ; |
Обход результата по группам
Третий, и последний способ обхода результата – по группам. Он сходен с иерархическим обходом, но с одним различием: записи с иерархическими итогами при обходе в нем рассматриваются как детальные записи, а не как узловые. Для получения выборки по группам из результата запроса необходимо вызвать метод Выбрать объекта РезультатЗапроса с параметром ОбходРезультатаЗапроса.ПоГруппировкам.
Пример:
СпособВыборки = ОбходРезультатаЗапроса . ПоГруппировкам ; Выборка2 = РезультатЗапроса . Выбрать ( СпособВыборки ) ; |
Перебрав в ней всё, мы получим записи с номерами 1, 2, 7, 11, 12, 16.
Пример:
Процедура ВыполнитьЗапрос ( ) // Создадим запрос. Запрос = Новый Запрос ; // Установим текст запроса // Выполним запрос и запишем результат в переменную // Получим выборку из результата запроса // Пока в выборке есть записи . ВыдатьДочерниеЗаписи ( Выборка . Выбрать ( ) ) ; Процедура ВыдатьДочерниеЗаписи ( Выборка ) |
Работа с выборкой
Объект ВыборкаИзРезультатаЗапроса предназначен для обхода записей результата запроса. Можно представить себе выборку как некоторый объект, который содержит указатель на текущую запись в результате и предоставляет программе доступ ко всем полям текущей записи. Для навигации по записям запроса используются три метода:
- Следующий() – перейти к следующей записи результата в соответствии с порядком обхода выборки. При первом вызове позиционирует выборку на первую запись. Когда будут выбраны все записи, данный метод просигнализирует об этом, вернув значение Ложь.
- СледующийПоЗначениюПоля() – получить следующую запись со значением в заданном поле, отличающимся от значения в этом поле текущей записи.
- НайтиСледующий () – найти запись, с заданными значениями некоторых полей.
Использование метода СледующийПоЗначениюПоля
Метод позволяет сгруппировать записи результата по значениям полей.
Пример запроса:
ВЫБРАТЬ
Док.Товар, Док.Получатель, Док.Количество
ИЗ
Документ.РасхНакл.Состав Док
УПОРЯДОЧИТЬ ПО Док.Товар.Наименование, Док.Получатель.Наименование
Источник
Обход по группировкам и получение общего итога
Например есть такой запрос:
ВЫБРАТЬ
Продажи.Контрагент КАК Покупатель,
Продажи.Маршрут КАК Маршрут,
СУММА(Продажи.Количество * Продажи.Номенклатура.ЕдиницаХраненияОстатков.Вес) КАК Вес,
СУММА(Продажи.Стоимость) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Регистратор КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Контрагент,
Продажи.Маршрут
ИТОГИ
СУММА(Вес),
СУММА(Сумма)
ПО
ОБЩИЕ,
Маршрут
как правильно организовать обход результата данного запроса, чтобы при выводе в табличный документ вначале выводилась группировка по Маршруту с итогам, затем детальные записи (Покупатель, количество, Вес), а в конце выводится общий итог?
Тип: ОбходРезультатаЗапроса.
Задает тип обхода записей в получаемой выборке.
Тип: Строка.
Список группировок по которым будет вестись обход, разделенных запятыми.
Для детальных записей указывается пустая строка. В случае, если группировки не указаны — будет использоваться следующая группировка, указанная в предложении запроса «ИТОГИ».
Тип: Строка.
Список группировок, из которых будут выбираться значения группировок для обхода, разделенных запятыми. Если указано «Все», то будут выбираться все значения группировок. Если указана пустая строка, то значения для группировок будут выбираться из предыдущей группировки.
Возвращаемое значение:
(4) ТО что выбрать понятно. Сформулирую по другому. Я делаю перебор результата запроса
> Я один тут не понимаю, что за таблица РегистрНакопления.Продажи.Регистратор?
в контексте итогов это вообще не важно и может просто для примера что-то написано.
(10) Хотел упростить текст запроса, вот и ошибся. Вот оригинал запроса:
Источник
ОбходРезультатаЗапроса ПоГруппировкам и вывод в табличный документ
ОбходРезультатаЗапроса ПоГруппировкам и вывод в табличный документ
Обход результата запроса по группировкам доступен при использовании конструкции Итоги по языка запросов.
При этом итоговые поля (суммы, количество), могут отсутствовать — производится просто группировка по нужным полям, либо по общим итогам — служебное поле «ОБЩИЕ»( флажок «Общие итоги»)
Конструктор запроса
Группировка добавляется на вкладке «Итоги», обратите внимание на флажок «Общие итоги», здесь же можно задать функцию итогов.
Не стоит путать функции группировки на вкладке «Группировки» с вкладкой «Итоги» (в общем случае для получения итогов группировка может не производится, либо производится по другому полю и с использованием другой функции) — это расчет итоговых показателей над готовой выборкой, а не группировка входных данных.
Не стоит использовать итоги, если в этом нет необходимости:
- это замедляет выполнение запроса
- при выборке доступны все поля запроса, но значение незадействованных на вкладке полей равно «Неопределено», что может быть не верно истолковано в процессе отладки и работы
Для использования механизма сводной таблицы платформы
- наоборот обязательно необходимы итоги запроса (определяет доступные поля группировки и ресурсы) иначе конструктор сводной таблицы будет пустым
В тексте запроса конструкция находится в нижней части:
Группировки могут быт вложенные, поэтому для выборки из запросов необходимо последовательно вызывать метод Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам).
Последняя группировка будет данными выборки, для которой вызов идет без параметра, либо с параметром ОбходРезультатаЗапроса.Прямой (по умолчанию).
Для примера, вывод результата произведем в табличный документ.
Чтобы вывести группировки в табличном документе, воспользуемся методом НачатьАвтогруппировкуСтрок(). После завершения вывода вызывается ЗакончитьАвтоГруппировкуСтрок() иначе группировка не сработает. Уровень группировки определяет второй параметр метода Вывести() табличного документа
Пример кода
Результат будет выглядеть вот так:
Для того, чтобы свернуть табличный документ можно вызывать метод ПоказатьУровеньГруппировокСтрок( )
Газетные объявления содержат больше правды о том, что происходит в стране, чем газетные передовицы.
Источник