Тип обхода по группировкам 1с
ВЫБРАТЬ
Продажи.Контрагент КАК Покупатель,
Продажи.Маршрут КАК Маршрут,
СУММА(Продажи.Количество * Продажи.Номенклатура.ЕдиницаХраненияОстатков.Вес) КАК Вес,
СУММА(Продажи.Стоимость) КАК Сумма
ИЗ
РегистрНакопления.Продажи.Регистратор КАК Продажи
СГРУППИРОВАТЬ ПО
Продажи.Контрагент,
Продажи.Маршрут
ИТОГИ
СУММА(Вес),
СУММА(Сумма)
ПО
ОБЩИЕ,
Маршрут
как правильно организовать обход результата данного запроса, чтобы при выводе в табличный документ вначале выводилась группировка по Маршруту с итогам, затем детальные записи (Покупатель, количество, Вес), а в конце выводится общий итог?
Тип: ОбходРезультатаЗапроса.
Задает тип обхода записей в получаемой выборке.
Тип: Строка.
Список группировок по которым будет вестись обход, разделенных запятыми.
Для детальных записей указывается пустая строка. В случае, если группировки не указаны - будет использоваться следующая группировка, указанная в предложении запроса "ИТОГИ".
Тип: Строка.
Список группировок, из которых будут выбираться значения группировок для обхода, разделенных запятыми. Если указано "Все", то будут выбираться все значения группировок. Если указана пустая строка, то значения для группировок будут выбираться из предыдущей группировки.
Возвращаемое значение:
"как правильно организовать обход результата данного запроса" // Правильно будет организовать обход результата данного запроса силами СКД
(4) ТО что выбрать понятно. Сформулирую по другому. Я делаю перебор результата запроса
> Я один тут не понимаю, что за таблица РегистрНакопления.Продажи.Регистратор?
в контексте итогов это вообще не важно и может просто для примера что-то написано.
(10) Хотел упростить текст запроса, вот и ошибся. Вот оригинал запроса:
Ну как бы вопрос мой вообще может касаться любого запроса, где есть группировка, итоги и общий итог. Поэтомуменя интересует схема вызова методов Выбрать() и параметры, чтобы получит вывести шапку группировки, детали, итог по группировки и в самом конце общий итог?
Команда ИТОГИ ПО предназначена для получения итогов по выбранным полям, затем позволяет производить иерархическую выборку результата запроса, а также выгрузку его сразу в ДеревоЗначений.
Обычный же результат выгружается как таблица значений (помимо линейной выборки).
Синтаксис блока ИТОГИ
Пример:
ИТОГИ
МАКСИМУМ(СуммаОборот)
ПО
ОБЩИЕ,
Ссылка ИЕРАРХИЯ
Конструктор запроса
Управление итогами производится на одноименной вкладке «Итоги»
- Доступно выбор группировочного поля
- Типа итогов (Элементы, Элементы и иерархия, Только иерархия)
- Указания наличия/отсутствия общего итога по всей выборке
- Выбор итоговых полей и выражений аналогичных по синтаксису группировке
Иерархия выборки
Выборка запроса по группировкам была рассмотрена в этой статье.
Приведем фрагмент кода:
Тонкости итогов
Если вызвать команду выгрузить с обходом по группировкам, она вернет ДеревоЗначений:
Есть интересный механизм получения аккуратного и компактного дерева через использования ВЫБОР в разделе ИТОГИ
Имя поля в итоге должно совпадать с одним из полей выборки иначе будет ошибка «Невозможно определить поле для записи результата»
Поля в итогах также должны быть в выборке, в противном случае выйдет ошибка: «Поле, по которому рассчитываются итоги, должно присутствовать в списке выборки»
ВЫБРАТЬ
4 КАК Четыре,
3 КАК Три,
2 КАК Два,
1 КАК Один
ИТОГИ
ВЫБОР
КОГДА Два ЕСТЬ NULL
ТОГДА Один
КОГДА Три ЕСТЬ NULL
ТОГДА Два
ИНАЧЕ Три
КОНЕЦ КАК Четыре
ПО
Один,
Два,
Три
На Выходе будет вот такая дерево:
- Осталось удалить лишние колонки и можно сразу выводить на форму
Как описываются машины в рекламных проспектах? “Волнующие”, “эффектные”, “изящные”, “грациозные”, “обтекаемой формы”. Прямо не знаешь, куда их вести — в гараж или в номер мотеля.
— Роберт Орбен
Вроде и тема небольшая, не для статьи, но поиски в интернете показали, что найти ответ довольно сложно. Из-за простоты вопроса специалисты обычно отмахиваются, считая, что вопрошающий не разбирается с азами программирования, не понимает рекурсии. В итоге на форумах тема обычно остается без ответа, либо приводится только часть ответа кратко. На самом деле есть «подводные камни», которые нужно знать.
«Подводные камни», мешающие реализовать обход иерархии:
1) В запросе в итогах нужно использовать ключевое слово ИЕРАРХИЯ, например, «ИТОГИ ПО Номенклатура Иерархия»
2) При использовании Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией) ,если есть несколько уровней группировки, нужно указывать второй параметр, строку с именем поля группировки. Например, для иерархической группироки по номенклатуре правильно будет Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией, «Номенклатура»)
3) При обходе выборки мы можем находиться в текущий момент на элементе или папке, для папки необходимо запускать рекурсивно выборку элементов в этой папке. А для элемента нижестоящую выборку, если есть группировки в запросе ниже нашей иерархической группировки, либо ничего не делать, если наша группировка нижняя. Чтобы определить тип элемента, используется функция ТипЗаписи()
Сам алгоритм обхода.
2) Иерархия на первом уровне группировки, второй уровень без иерархии
3) Первый уровень без иерархии, второй с иерархией
4) Первый уровень без иерархии, второй с иерархией (без рекурсии)
Специальные предложения
Рекурсия требует доп.расходов ресурсов и не удобна из-за того, что выходим из области видимости остальных переменных - приходится или параметрами их передавать или объявлять в теле модуля. Любую выборку можно обойти в одной процедуре и без рекурсий.
(1) Согласен. Но в данной статье не рассматривается преобразование рекурсии в циклический алгоритм, т.к. это отдельная тема. Хотя, в принципе, можно добавить нерекурсивный алгоритм в качестве примера.
(8) Я правильно понял, что в примере без рекурсии "ВыбратьДанные" имеется ввиду обработать подчиненные группировки?
Гуд. Но почему нету примера, когда в методе "Выбрать" указывается 3 параметра?
Автор, допиши статью, указав пример с использованием 3-ех параметров (подсказка - хороший пример при работе с датами). Сделай из своей статьи конфетку ;-)
При использовании Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией) обязательно указание второго параметра, строки с именем поля группировки.
Второй параметр вроде как не обязательный. И если у нас нет других полей группировки то можно и не указывать второй параметр.
Спасибо! Решил проблему:)
У меня сейчас есть подобная задача, построить отчет в виде пирамиды сверху вниз, и я вот никак не могу его побороть(((
Уже кажется что в 1С эта задача не реализуема(((
Неоднозначная формулировка, ведь при группировке по иерархии подразумевается, что поле группировки иерархическое. В таком случае действительно будут и папки и элементы. Однако если справочник подчинен элементам? Тогда будут группировки по элементам.
Я бы здесь все-таки разделил. Папки - это те же элементы справочника, как и элементы, которым подчинены другие папки или элементы. А вот когда в запросе выбираются итоги по, то в результат запроса помимо самой выборки платформа добавляет еще группировки (строки итогов).
Сам в очередной раз сталкиваясь с задачей иерархического обхода выборки начинаю по началу вспоминать теорию. Вот следующие выводы, которые мне помогают:
Если в итогах нет модификаторов, то это будут группировки по значению поля. Для иерархического справочника в такой группировке мало смысла, т.к. все элементы уникальны.
Если в итогах указать модификатор ИЕРАРХИЯ, то платформа помимо итоговых группировок для элементов еще добавит элементы иерархии и по ним также итоговые группировки. Получатся итоги по элементам и по группам элементов - избыточное количество итогов. При этом сами элементы иерархии будут входить в свою же группировку.
Если указать модификатор ТОЛЬКО ИЕРАРХИЯ, то платформа добавит итоговые группировки только по элементам иерархии. При этом сами элементы иерархии будут входить в свою же группировку.
И наконец самый практичный вариант: ТОЛЬКО ИЕРАРХИЯ и условие на элемент НЕ ЭтоГруппа. В таком варианте будут выведены элементы сгруппированные по папкам. Однако такой вариант не сработает, если есть иерархия элементов.
Когда происходит обход по иерархической группировке, то этот обход всегда происходит на одном уровне иерархии. Если нам встречается итоговая запись, не важно какой итог (по иерархии или по группе), то нужно выбрать следующий уровень иерархии группировки: для итога по иерархии - ОбходРузультатаЗапроса.ПоГруппировкамСИерархией, а для итога по группировке (всегда присутствует на последнем уровне группировки по выбранному полю) - ПоГруппировкам. При этом нужно обязательно указать имя поля группировки то же самое или просто передать в выборку значение функции Выборка.Группировка(). Это нужно сделать для того, чтобы платформа не выбрала сама следующую группировку итогов или детальные записи, т.к. в платформе такое поведение заложено по-умолчанию.
Рекурсия при обходе результата запроса
Добрый вечер! Необходимо сохранить уровень обхода результата запроса при рекурсии. В задаче.
Выбрать следующее значение
Здравствуйте ! Есть таблица: |id | login| |1 | admin| |2 | user | |3 | admin | Мне нужно.
Как посмотреть следующее значение, не увеличив при этом текущий индекс в sequence
Как посмотреть следующее значение, не увеличив при этом текущий индекс в sequence? Или, если єто.
При копировании массива данных, чтоб в каждый новый подставлялось следующее значение из соседней таблицы
Добрый день, Клан Office. Мне дали задание напечатать 3 класса по 35 учеников обложек с их.
Выгрузи результат запроса в дерево значений. И сможешь записи и блоки использовать многократно, а не только ForwardMove.
Выборка - это дерево в данном случае, но оснащённое методами "хождения". Те же самые методы можно реализовать, получив дерево-объект, но уже думать надо .
всё есть в синт.поме. Дерево - рекурсивный типовой объект.
Дерево.Строки
КоллекцияСтрокДереваЗначений (ValueTreeRowCollection)
Элементы коллекции:
СтрокаДереваЗначений
Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются элементы коллекции.
Возможно обращение к элементу коллекции посредством оператора [. ]. В качестве аргумента передается индекс строки (нумерация с 0).
Вставить (Insert)
ВыгрузитьКолонку (UnloadColumn)
Добавить (Add)
ЗагрузитьКолонку (LoadColumn)
Индекс (IndexOf)
Итог (Total)
Количество (Count)
Найти (Find)
НайтиСтроки (FindRows)
Очистить (Clear)
Получить (Get)
Сдвинуть (Move)
Сортировать (Sort)
Удалить (Delete)
Представляет собой коллекцию строк, подчиненных какой-либо строке дерева значений.
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Добавлено через 1 минуту
Каждая строка - дерево.
в теории строка=Дерево.Строки[0].Строки[0].Строки[0].Строки[0].Строки[0].
Рассматривается применимость и недостатки следующих способов получения дерева
1) Запрос с использованием итогов по иерархии
2) Формирование дерева обходом выборки с упорядочиванием по иерархии
3) Формирование иерархии по списку элементов транзитивным замыканием
1) Идея проста — выбираем запросом элементы, не являющиеся папками, а всю иерархию нам построит запрос. Тут сразу начинаются неожиданности. Какую конструкцию использовать: ИЕРАРХИЯ или ТОЛЬКО ИЕРАРХИЯ? Вроде логично было бы ТОЛЬКО ИЕРАРХИЯ, т.к. итоги на уровне элементов нам не нужны (будут дубли). Заглядываем в справку: «ИЕРАРХИЯ. В результате будут рассчитаны итоги по контрольным точкам и итоги по иерархии для контрольных точек … При необходимости можно рассчитать итоги только значений по иерархии, без расчета итогов в контрольных точках. Для этого перед ключевым словом ИЕРАРХИЯ нужно указать ключевое слово ТОЛЬКО.»
Для однозначного понимания моих объяснений введу несколько «терминов», которыми буду пользоваться. Все листья дерева буду называть элементами. Узлы дерева, которые содержат только элементы — нижние папки, Остальные узлы, которые содержат хотя бы одну нижнюю папку — верхние папки.
Для ИЕРАРХИЯ — все логично: разбираем дерево итогов по иерархии для папок. У всех папок тип — ТипЗаписиЗапроса.ИтогПоИерархии. У элементов тип — ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри группировки одна запись того же элемента но уже с типом ТипЗаписиЗапроса.ДетальнаяЗапись. Все как заявлено. Но если выгрузить в дерево, дубль пропадает!
Либо сформировать вручную
Для ТОЛЬКО ИЕРАРХИЯ все немного не так, как ожидалось. Верхние папки — ТипЗаписиЗапроса.ИтогПоИерархии, нижние — ТипЗаписиЗапроса.ИтогПоГруппировке. Внутри элементы с типом — ТипЗаписиЗапроса.ДетальнаяЗапись. НО, если верхняя папка содержит элементы, все они будут помещены в еще в одну вложенную группу с типом ТипЗаписиЗапроса.ИтогПоГруппировке. Поэтому выгрузить() приводит к дублированию! Цель такого дублирования думаю в том, чтобы все элементы обязательно содержались в папке с ТипЗаписиЗапроса.ИтогПоГруппировке, чтобы мы могли обходить выборку ОбходРезультатаЗапроса.ПоГруппировкам. Поэтому, если использовать ТОЛЬКО ИЕРАРХИЯ, лучше обойти выборку и сформировать ручками дерево, устраняя дублирование. При обходе нужно обязательно указывать второй параметр «Группировки». Привожу обход для ТОЛЬКО ИЕРАРХИЯ
Недостатки такого метода очевидны. Все папки вычисляет запрос, и мы не можем как-то их использовать. Например, при соединении с другой таблицей по номенклатуре, склеются только элементы, а на уровне папок нам доступны только вычисления в итогах. Проблема производительности здесь не рассматривается.
2) Для решения этой проблемы необходимо выбрать папки в запросе. Такой запрос не получиться выгрузить в дерево, но, если мы будем использовать в запросе УПОРЯДОЧИТЬ ПО … ИЕРАРХИЯ, а также выберем в запросе родителя, то обход дерева станет простым, мы будем обходить выборку в цикле и прицеплять следующий элемент к текущему или одному из его родителей. К кому цеплять покажет выбранное поле родитель.
Рассмотрим задачу получения только иерархии по набору элементов. Для решения задачи выберем для элементов все папки, в которых они содержатся, затем замыканием вычислим всех родителей этих папок, ну и далее выборка с обходом по 2 методу.
Читайте также: