Обход запроса по нескольким группировкам

16.05.12

Разработка - Запросы

Хочу поделиться с вами небольшой "зарисовкой", которая помогает мне обходить выборку запроса, как бы пропуская некоторые группировки.

Хочу поделиться с вами небольшой "зарисовкой", которая помогает мне обходить выборку запроса, как бы пропуская некоторые группировки.
Что я имею в виду. Предположим, у нас есть запрос, который выбирает из регистра движения по номенклатуре в разрезе склада, номенклатуры, характеристики номенклатуры и документа движения. Вот как выглядит "плоская" выгрузка результата этого запроса:

Если в запросе указать итоги по складу, номенклатуре и характеристике номенклатуры и написать следующий код:

то обход будет производиться следующим образом:

Т.е. по первой группировке "Склад" внешний цикл (голубой) совершит одну итерацию, по второй группировке "Номенклатура" ("розовый" цикл) четыре итерации, в каждой из итераций "розового" цикла будет разное количество итераций "зеленого" цикла по группировке "ХарактеристикаНоменклатуры", и в конечном итоге будут выбраны все детальные записи ("серый" цикл), которые на рисунке я отмечать не стал, ибо лениво.

Но иногда хочется выбрать записи вот таким образом:

Т.е. так, чтобы внешний (голубой) цикл выбирал, как и положено, по группировке "Склад", а внутренний (зеленый) выбирал по некой "агрегатной" группировке "Номенклатура+ХарактеристикаНоменклатуры". Ну и дальше по необходимости детальные записи. Это было бы удобно, если бы вы, например, создавали документы по группировке "Склад", а второй "метагруппировкой" заполняли табличную часть каким-либо образом. Конечно, код, который приведен выше, справляется с этой задачей, но лично моя печаль в том, что там есть один вложенный цикл (розовый), который делается совершенно ненужным с точки зрения "изящества кода" как минимум. К тому же, когда таких группировок становится больше, например девять, мы видим совершенно "потрясающую" картину из девяти вложенных циклов.
Еще можно просто пропустить группировку "Номенклатура" и обходить результат запроса по группировкам "Склад - ХарактеристикаНоменклатуры - ДетальныеЗаписи". Но вот беда, в этом случае на уровне характеристики нет самой номенклатуры. Смотрите сами:

 

Получается, что на уровне выборки по складу номенклатуры еще нет, а на уровне выборки по характеристике ее... все еще нет. Бида.

Я точно знаю, что я не один такой, но у меня и у других коллег по несчастью как-то сам собой напрашивается вот такой код:


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

Но мы не ждем милости от природы и от 1С. А берем и сами делаем. Вот такой код работает нормально вполне:

Пара слов о функциях.
Функция "зфВыбратьПоГруппировкам" применяется вместо "ВыборкаЛалала.Выбрать()". Ей передается выборка, из которой нужно выбирать, и перечень группировок через запятую. При этом она возвращает некую "метавыборку". Ничего военного, просто соответствие с необходимыми данными.
Функция "зфСледующийПоГруппировкам" применяется вместо "ВыборкаОлоло.Следующий()". Ей передается та самая, открытая на предыдущем шаге "метавыборка" и возвращает она истину или ложь, как и штатный метод "Следующий".
Да. Внутри цикла вы можете смело получать родную 1С-овскую выборку нижнего уровня группировок, обратившись к элементу соответствия "Выборка". Вот так:

РоднаяВыборка1С = МетаВыборка["Выборка"];

Естественно, дальше родную выборку 1С можно хоть снова перебирать этими функциями, хоть выбирать штатными средствами.

Также не могу не сказать, что, в принципе, в функциях нет ничего нового и я тут не претендую на оригинальность или что-нибудь в таком духе. Думаю, что многие писали такие же функции, просто хотелось поделиться с уважаемым сообществом.
Они также не убирают вложенные циклы, просто немного иначе их организуют и скрывают. Т.е. в действительности все "лишние" циклы есть, но из кода это не очевидно.
Еще вполне понятно, что их использование будет менее производительным в смысле быстродействия, нежели использование вороха вложенных циклов. Я, конечно, старался написать пооптимальнее, но сами понимаете, накладные расходы будут.
Да, одна функция рекурсивная. По идее глубина рекурсии будет небольшой и равна количеству пропускаемых группировок плюс один, однако рекурсия есть рекурсия.
Ну и конечно, не исключен вариант, что я где-то накосячил. Если обнаружите - пишите, поправим.

Наконец сами функции:


Функция зфВыбратьПоГруппировкам(Выборка, Группировки, СИерархией = Ложь)

      
МетаВыборка = Новый Соответствие;

      
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкам;
       Если
СИерархией Тогда
              
врОбходРезультата = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
       КонецЕсли;
      
МетаВыборка.Вставить("ОбходРезультата", врОбходРезультата);

      
МассивГруппировок = Новый Массив;
      
врСтрГруппировки = Группировки;
       Пока Истина Цикл
              
Поз = Найти( врСтрГруппировки, "," );
               Если
Поз = 0 Тогда
                      
МассивГруппировок.Добавить(СокрЛП(врСтрГруппировки));
                       Прервать;
               КонецЕсли;
              
МассивГруппировок.Добавить( СокрЛП( Лев(врСтрГруппировки,Поз-1) ) );
              
врСтрГруппировки = Сред( врСтрГруппировки, Поз+1 );
       КонецЦикла;

      
МетаВыборка.Вставить("Группировки", МассивГруппировок);

      
врВыборка = Выборка;
       Для
пц=0 По МассивГруппировок.Количество()-2 Цикл
              
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
              
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);
               Если не
врВыборкаУровня.Следующий() Тогда
                       Прервать;
               КонецЕсли;
              
врВыборка = врВыборкаУровня;
       КонецЦикла;
      
врВыборкаУровня = врВыборка.Выбрать(врОбходРезультата, МассивГруппировок[пц]);
      
МетаВыборка.Вставить("Выборка", врВыборкаУровня);
      
МетаВыборка.Вставить("_Выборка"+Строка(пц), врВыборкаУровня);

       Возврат
МетаВыборка;

КонецФункции
// зфВыбратьПоГруппировкам

Функция зфСледующийПоГруппировкам(МетаВыборка, Уровень = Неопределено)

       Если
Уровень = Неопределено Тогда
              
Уровень = МетаВыборка["Группировки"].Количество()-1;
       КонецЕсли;

       Если
Уровень < 0 Тогда
               Возврат Ложь;
       КонецЕсли;

      
врВыборка = МетаВыборка["_Выборка"+Строка(Уровень)];

       Если
врВыборка.Следующий() Тогда
               Возврат Истина;
       КонецЕсли;

       Если
зфСледующийПоГруппировкам(МетаВыборка, Уровень-1) Тогда
              
МассивГруппировок = МетаВыборка["Группировки"];
              
врВыборкаРодитель = МетаВыборка["_Выборка"+Строка(Уровень-1)];
              
врВыборка = врВыборкаРодитель.Выбрать(МетаВыборка["ОбходРезультата"],МассивГруппировок[Уровень]);
              
МетаВыборка["_Выборка"+Строка(Уровень)] = врВыборка;
               Если
Уровень = МассивГруппировок.Количество()-1 Тогда
                      
МетаВыборка["Выборка"] = врВыборка;
               КонецЕсли;
               Возврат
зфСледующийПоГруппировкам(МетаВыборка, Уровень);
       Иначе
               Возврат Ложь;
       КонецЕсли;

КонецФункции
// зфСледующийПоГруппировкам

Спасибо за внимание, а я желаю вам хорошего дня и хорошего кода.

Оригинал статьи в блоге автора

См. также

SALE! 20%

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 10400 руб.

02.09.2020    122136    670    389    

714

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5746    KawaNoNeko    23    

23

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2000    2    Yashazz    0    

29

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6284    31    mkalimulin    25    

50

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1742    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5388    user1923546    26    

43

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16183    skovpin_sa    14    

98
Вознаграждение за ответ
Показать полностью
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. zfilin 2337 24.04.12 21:50 Сейчас в теме
В основном блоге коллега советует для данного примера применить к полю "Номенклатура" агрегатную функцию МАКСИМУМ.

Не пробовал, но почему ему не работать?
16. i132 122 28.04.12 16:08 Сейчас в теме
(1) Максимум при группировке по Характеристики не поможет, если есть пустые характеристики.
2. Новиков 292 24.04.12 23:44 Сейчас в теме
Непонятно мне, а почему нельзя подготовить текст запроса таким образом чтобы получить простую выборку для простого обхода вот без этих всех квадратных треуголок? )
soci0pat; pavlo; +2 Ответить
3. zfilin 2337 25.04.12 00:01 Сейчас в теме
(2) Новиков, Да, почему ж нельзя? Можно, конечно! Более того, это было бы даже лучше и быстрее.
Но иногда приходится и с треуголками. =)

А предложите свой вариант для такого обхода?
4. Новиков 292 25.04.12 00:06 Сейчас в теме
(3) я признаться, уже забыл, когда руками обходил результат запроса с группировками. Я обычно делаю базовую схему компоновки, и при помощи настроек компоновки (двигаю группировки вверх и вниз) получаю нужный резалт. И уже его как-то обрабатываю. Т.е. даже текст запроса никакого не нужно собирать. А Ваш вариант - он наверное крут, я не спорю. И наверное даже где-то находит применение. Вот и хотелось бы узнать - где! :%)
5. zfilin 2337 25.04.12 00:22 Сейчас в теме
(4) Новиков, А! СКД. Да, я тоже люблю скормить данные СКД, а потом получить их в нужно виде и по ним ходить. Но, вот недавно решил выбрать просто запросом и просто ходить по группировкам без СКД. Как-раз документы создавал. Так и применял.
Глупо было бы утверждать, что это единственный и уникальный способ и я сейчас выдам прям такую исключительную ситуацию, где запрос применить можно, а СКД нельзя.
С другой стороны какое-то внутреннее стремление к простоте протестует против того, чтобы "городить ЦЕЛУЮ СКД", когда надо просто обойти группировки простого запроса. Если бы это было возможно реализовать штатными средствами (как в не работающем примере), это был бы win. А поскольку сами функции получились достаточно "мозгачными", то это, конечно не win, а так - посокрушаться.
15. i132 122 28.04.12 15:34 Сейчас в теме
Если нет пустых характеристик, можно сделать запрос без группирповки итогов и воспользоваться методом Выборка.СледующийПоЗначениюПоля()

Описание метода на ИТС

либо как предложил Новиков в (2) прямой запрос, без группировок остортировать по списку полей шапки:
СтруктураУникальнойШапки = Новый Структура("Поле1,Поле2,Поле3");

Док = Неопределено; //Лучше объявить переменную до цикла, заодно проверим первый вход
Пока выборка.Следующий() Цикл
   ФлНоваяШапка =Ложь;
   Для каждого ПолеШапки из СтруктураУникальнойШапки Цикл
      Если НЕ ПолеШапки.Значение= выборка[ПолеШапки.Ключ] Тогда
		Если Док = Неопределено тогда 
		 	Док.Записать();
		КонецЕсли;	
         ЗаполнитьЗначенияСвойств(СтруктураУникальнойШапки,Выборка);
         Док = СоздатьДокПоШапке(СтруктураУникальнойШапки);
         Прервать;
      КонецЕсли;   
   КонецЦикла;   
   НоваяСтрока = Док.(ТабЧасть).Добавить();
   Док = ЗаполнитьЗначенияСвойств(НоваяСтрока,Выборка);
КонецЦикла;   

Если НЕ Док = Неопределено тогда 
	Док.Записать();
КонецЕсли;
Показать
18. zfilin 2337 28.04.12 18:20 Сейчас в теме
(15) i132, За "СледующийПоЗначениюПоля()" спасибо, нужно будет посмотреть.

А по поводу кода. Мне кажется или у вас там первая строка проглатывается? Когда вы в выборке дважды в подряд "Следующий()" вызываете?
Ну в целом, после первого "Следующий" выборку можно и на начало сбросить, так что принцип понятен.

Но вот именно от такого кода и хочется избавиться в первую очередь. Собственно, эти процедуры я и "затеял", чтобы уйти от "мониторинга момента смены ключа".
Чем мне не нравится такой подход, это во-первых тем, что логика алгоритма несколько "размазывается" по коду. Мы имеем заполнение внутри цикла, создание и запись документа там же, а еще такие же блоки за пределами цикла. Причем, когда мы записываем документ внутри цикла, имеется документ относящийся к предыдущей итерации выборки, а данные в выборке соответствуют уже новому. Все это, что ни говори, повышает сложность кода. Да, что я говорю, думаю все отписавшиеся не раз писали код, который мониторил бы смену одного из полей и в зависимости от этого что-то происходил.
А еще мне очень не нравится то, что код дублируется. Хорошо, когда это одна строка "ЗаполнитьЗначенияСвойств", но когда по смене ключа предусматриваются более обширные действия, блок в начале (до начала цикла) и блок в цикле нужно не забывать обновлять одновременно. Так же как и "Записать()", если нужна не просто запись, а еще какие-то финализирующие действия.
А хочется стройной конструкции, где на одном уровне вложенности документ создавался бы, затем как-то заполнялся (следующая вложенность) и потом на том же уровне и записывался. Без разделения и дублирования.
native-api; user597343_netcpv22; i132; +3 Ответить
19. i132 122 28.04.12 19:25 Сейчас в теме
(18) >первая строка проглатывается
упс, спасибо, не заметил действительно обработку первой строки пропустил. старый пост (15) переписал.
6. Yashazz 4709 25.04.12 12:21 Сейчас в теме
Хм, никогда не пользуюсь указанным обходом. Работаю с плоской таблицей значений, можно как угодно выкручивать, сортировать и обходить, безо всяких доп.функций и страшных вложений циклов. В самом хитром случае учреждаются доп.колонки для управления обходом (прям в запросе, или одним обходом таблицы), а дальше рулёжка уже по ним.
Да, и СКД рулит, конечно. Чего её "городить", дело-то простое, а выигрыш иной раз нехилый.
17. Созинов 28.04.12 17:55 Сейчас в теме
(6) Yashazz,
Согласен с вами, но при большом объеме иногда удобнее прогуливаться по иерархии.

Как раз на прошлой неделе столкнулся с такой проблемой, делал перенос с 7.7 на 8.2 (да знаю, что есть куча обработок и Конвертация данных, которую пока не освоил к сожалению), каждый раз делать запросы или сортировать/обходить таблицу со всей номенклатурой, контрагентами и т.д. накладно (хотя какая разница, один раз перенос будет).
Автору + - еще одно интересное решение в копилку, думаю пригодится, хотя использовать буду редко.

(12) romansun,
Спасибо за наводку.
7. dandrontiy 25.04.12 13:00 Сейчас в теме
Круто, но применение непонятно.
И мне почему то удобней не выборками пользоваться, а ТаблицаЗначений = Запрос.Выполнить().Выгрузить();
И мне кажется это к тому же просто быстрее. Как раз применимо для случая, когда надо что-то чем то заполнить, нет разве ?
8. karakozov 25.04.12 13:45 Сейчас в теме
Решение конечно для конкретной задачи, такой подход возможно имеет смысл в ситуации когда таблица имеет очень большой объем.И выбирать ее несколько раз для каждой выборки в рамках одной процедуры очень долго.Может быть конечно так разъяснено что не совсем понятно цель.В общем все от ситуации.
9. Yashazz 4709 25.04.12 16:22 Сейчас в теме
(8) Вопрос знатокам - выборка, полученная из результата запроса методом "Выбрать", или сам результат, кэшируется где-либо или болтается в оперативке? Если да, то в клиентской или где?
10. zfilin 2337 25.04.12 22:18 Сейчас в теме
Друзья, но когда мне нужно обойти плоскую таблицу, мне же нужно понимать момент, когда у меня появляется другой склад в первой колонке, чтобы, если взять уже приведенный пример, создать новый документ с ДРУГИМ складом. Как же это реализовать в плоской выборке?
Т.е. тот случай, когда на разных "уровнях группировок" реализуется разное поведение, разный код.
user1299321; kniga888; Gesperid; +3 Ответить
11. zfilin 2337 25.04.12 22:20 Сейчас в теме
Т.е. я сейчас не защищаю свои функции, но интересен сам принцип.
12. romansun 193 26.04.12 11:05 Сейчас в теме
я последнее продолжительное время возвращаю запросом дерево, да, с составным ключом

циклы упрощаются до невозможности

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

особенно помогла в этом метода "конвертации" даты в строку прям в запросе для успешного склеивания
taraas; veiuper; Gesperid; AllexSoft; invertercant; +5 Ответить
13. MGraf 3 27.04.12 12:14 Сейчас в теме
(12) romansun, напишите пожалуйста публикацию! Хотя бы пару строк с примером :)
AllexSoft; +1 Ответить
20. romansun 193 10.05.12 16:14 Сейчас в теме
(13) ох.. это ж писать надо :)

идея-то, в общем, простая. Вот такой упрощенно пример: есть таблица с кучей колонок (Организация, Контрагент, ДоговорКонтрагента, Номенклатура, Сумма, Количество и т.п.)

Нужно по этим строкам создавать документы, в шапку которых пихать реквизиты (Организация, Контрагент, ДоговорКонтрагента), в ТЧ пихать (Номенклатура, Сумма, Количество).

В запросе создаем поле "Ключ", которое определяем уникальными значениями для соответствующих интересующих нас полей. В нашем примере это "Организация", "Контрагент", "ДоговорКонтрагента". Т.е.

ВЫБРАТЬ
 ВложенныйЗапрос.Организация.Код + ВложенныйЗапрос.Контрагент.Код + ВложенныйЗапрос.ДоговорКонтрагента.Код КАК Ключ
...


(отмечу, что обычно договор это подчиненный справочник к контрагенту со сквозной нумерацией, т.е. все кода уникальны независимо от владельца, посему контрагент в этом ключе не нужен - договора будет достаточно. Но оставим для полноты примера :) )

данное поле "Ключ" будет однозначно уникальным для будущих документов. Т.е. мы получили составной уникальный ключ.

А дальше просто "итожим" по нему

ИТОГИ
   МАКСИМУМ(Организация),
   МАКСИМУМ(Контрагент),
   МАКСИМУМ(ДоговорКонтрагента)
ПО
   Ключ


максимум для этих полей определяем только для того, чтобы получить их в вернем уровне дерева, чтобы потом подставить в наш документ

в 1С-ном коде будет обычный цикл обхода дерева, где по итерации цикла на верхнем уровне создаем новый документ, а по итерациям на втором - заполняем его ТЧ. При этом нам совершенно не надо задумываться создавать ли новый документ на данной итерации цикла, или писать всё еще в предыдущий... и т.п. "приятные" вопросы.

И самое вкусное - если вдруг возникнет необходимость "доразбить" создаваемые документы еще по какому-нить полю, мы просто дописываем его в "Ключ" (например "... + БанковскиеСчета.Код КАК Ключ") и всё.

Таким образом можно делать достаточно сложные ключи. Можно использовать в качестве слагаемых, соответственно, результаты каких-то ВЫБОР КОГДА ТОГДА и т.п.

(14)
Хм. Насколько я понимаю, в запросе можно создать составной ключ склеиванием строк. Но поддерживается ли уникальность при конвертации ссылочных типов в строку? Т.е. вы получаете представление ссылки или просто представление, как наименование, код, НомерДок и т.д?


достаточно просто текстового представления уникального поля (группы полей) - код, наименование и т.п. С числами сложнее, а с датами еще сложнее, ибо их не сложишь как строку, да. А нормальной конвертации в 1С-ных запросах нет. Но числовые коды редко когда бывают, всё-таки. Насчет дат (да и чисел, кстати, тоже) за нас уже всё придумали (23 пост - отлично всё работает)
http://www.forum.mista.ru/topic.php?id=388253

Соответственно, дату (и число) можно представить строкой и приклеить к ключу.
fortran; О.Ж; odinsmot; pieceofmind; CepeLLlka; Onaisoft; user1299321; Borey; LomayaZakat; andew; taraas; soci0pat; Мах; cheburashka; Liss111; huzden; RadoLex; Daynestro07; MbIwb; 7fortune; Gorr; skalex; Lord_Alexandr; TeMochkiN; slavik_s; python.pm; Mozgolom1988; klinval; DexterMorgan777; MI_HAN; Михаська; YuriFm; swimdog; Angry; AllexSoft; ftm; kayen; DoctorRoza; zfilin; +39 Ответить
14. zfilin 2337 27.04.12 13:43 Сейчас в теме
(12) romansun, Хм. Насколько я понимаю, в запросе можно создать составной ключ склеиванием строк. Но поддерживается ли уникальность при конвертации ссылочных типов в строку? Т.е. вы получаете представление ссылки или просто представление, как наименование, код, НомерДок и т.д?
native-api; +1 Ответить
21. DoctorRoza 17.05.12 09:46 Сейчас в теме
Достаточно интересная статья, написано доходчиво и наглядно, сразу чувствуется высокий уровень автора! Предложенная идея больше смахивает на "лабораторную" раскопку 1С.
22. RainyAugust22 265 12.11.12 07:27 Сейчас в теме
хорошая статья,спасибо за инфу.
23. xomaq 16 12.11.12 08:26 Сейчас в теме
Огромное спасибо автору!!
Как раз сегодня мучился с подобной задачей. С кодом, приведенным автором, у меня все заработало!!
Респект и уважуха!!!
24. kit 73 23.11.12 00:27 Сейчас в теме
Хорошая статья. Тоже сижу разбираюсь с обходом группировок в запросе, а тут как раз в тему.
25. Evgen.Ponomarenko 567 13.08.13 13:01 Сейчас в теме
Действительно, актуально!
26. dimk@a 14.08.13 10:56 Сейчас в теме
Спасибо, хорошая статья. И в обсуждении как всегда много важного!
27. olbu 08.10.15 12:31 Сейчас в теме
А если переделать запрос та вот так:
ВЫБРАТЬ
	ТоварыНаСкладахОстатки.Склад КАК Склад,
	ТоварыНаСкладахОстатки.Номенклатура,
	ТоварыНаСкладахОстатки.ХарактеристикаНоменклатуры,
	ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
ИЗ
	РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
ИТОГИ
	СУММА(КоличествоОстаток)
ПО
	Склад
Показать


Верхняя группировка будет по складу, а нижняя - по номенклатуре + характеристике.
Или я не верно понял?
28. zfilin 2337 09.10.15 15:46 Сейчас в теме
В таком простом случае, да сработает. Но это все же немного не то.
А если две составных группировки?
Например склад+контрагент и товар+характеристика.
29. EvgeniuXP 04.02.16 23:14 Сейчас в теме
Вот вам применение: есть документы, там 13 реквизитов, надо выявить одинаковые документы, если их два и более то один провести, остальные пометить на удаление. Методом группировок мы отсеиваем одинаковые, оставляем только одинаковые два и более документа, потом группируем по всем 13 реквизитам и на выходе имеем на самом нижнем уровне одинаковые записи двух и более документов. При первом входе проводим, при втором и последующих - метим на удаление.
30. iott 09.01.17 03:29 Сейчас в теме
Полезная статья по группировкам! Мне оказалась полезной!

Получается, что на уровне выборки по складу номенклатуры еще нет, а на уровне выборки по характеристике ее... все еще нет. Бида.

"Бида."....тут опечатка или так задумано? =)
31. zfilin 2337 10.01.17 16:17 Сейчас в теме
32. i.kovtun 180 29.07.17 12:38 Сейчас в теме
Саша, спасибо :) Быстро загуглилось и пригодилось!
33. zfilin 2337 05.08.17 00:34 Сейчас в теме
(32) О, приветствую! Ну, вот, хорошо что пригодилось. Я когда-то полголовы себе об это сломал. Значит не зря.
34. andrey1508 107 26.09.19 09:00 Сейчас в теме
Посмотрите как это реализовано на диске ИТС
https://its.1c.ru/db/pubqlang#content:64:hdoc

&НаСервереБезКонтекста

Процедура ВыполнитьЗапрос()

   Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |        ПриходнаяНакладнаяСостав.Товар КАК Товар,
    |        ПриходнаяНакладнаяСостав.Количество КАК Количество
    |ИЗ
    |        Документ.ПриходнаяНакладная.Состав КАК ПриходнаяНакладнаяСостав
    |УПОРЯДОЧИТЬ ПО
    |        Товар
    |ИТОГИ
    |        СУММА(Количество)
    |ПО
    |        Товар ИЕРАРХИЯ";

    РезультатЗапроса = Запрос.Выполнить();

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

КонецПроцедуры

&НаСервереБезКонтекста

Процедура ВыдатьВсеВложения(ИерархическаяВыборка)

   Сообщение = Новый СообщениеПользователю;
   Пока ИерархическаяВыборка.Следующий() Цикл
       Сообщение.Текст = "Товар: " + ИерархическаяВыборка.Товар.Наименование +
           " Количество: " + ИерархическаяВыборка.Количество() +
           " Тип записи: " + ИерархическаяВыборка.ТипЗаписи() +
           " Уровень: " + ИерархическаяВыборка.Уровень() +
           " Группировка: " + ИерархическаяВыборка.Группировка();
       Сообщение.Сообщить();

       // Продолжим выборку подчиненных записей
       СпособВыборки = ОбходРезультатаЗапроса.ПоГруппировкамСИерархией;
       Если ИерархическаяВыборка.ТипЗаписи() = ТипЗаписиЗапроса.ИтогПоИерархии Тогда
            ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки, ИерархическаяВыборка.Группировка());
       Иначе
            ДочерняяВыборка = ИерархическаяВыборка.Выбрать(СпособВыборки);
       КонецЕсли;

        ВыдатьВсеВложения(ДочерняяВыборка);
   КонецЦикла;
КонецПроцедуры
Показать
volex; eeeio; +2 Ответить
35. itxr 33 17.10.19 08:47 Сейчас в теме
Спасибо огромное! Решил задачу над которой мучался несколько часов за 2 минуты!
36. пользователь 02.03.21 09:12
Сообщение было скрыто модератором.
...
37. пользователь 25.06.21 14:03
Сообщение было скрыто модератором.
...
38. user873507 01.09.21 22:00 Сейчас в теме
автору спасибо за статью
я нашел ответ на свой вопрос и разобрался где могут быть полезны эти параметры, я про 2й и 3й в методе "выбрать"
мне надо вывести довольно простой отчет с двумя группировками но вывести так чтобы 1я группа была в строках а 2я в колонках.
вывожу программно на макет.
И только вот такая строка
ВыборкаДень.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам,"УчастокПроизводства", "Все");
дала мне возможность вывести, а именно "присоединить" ячейки в точном соответствии с названиями этих колонок, названия это сами участки которые тоже из этого же запроса.
В обычном варианте получались сдвиги влево, т.е. "пустые" ячейки просто пропускались и я видел
в 1й строке - 6 колонок, во 2й - 6 колонок, в 3й - 4 колонки, в 5й - 5 колонок.
про итоги вообще молчу.
Оставьте свое сообщение