Совместное использование итогов и группировки

Язык запросов

Синтаксис и применение Совместное использование итогов и группировки в платформе 1С:Предприятие. Описание и примеры кода.

Полное описание, параметры и ограничения

Совместное использование итогов и группировки

В случае, если итоги используются совместно с группировкой, и для итогов не указан список агрегатных функций, он будет автоматически формироваться из агрегатных полей списка выборки. В случае если запрос содержит объединение, агрегатные функции будут браться из первого запроса.

Пример:

ВЫБРАТЬ Док.Товар, Док.Ссылка.Получатель, СУММА(Док.Количество)
ИЗ Документ.РасхНакл.Состав КАК Док
СГРУППИРОВАТЬ ПО Док.Товар, Док.Ссылка.Получатель
ИТОГИ ПО Док.Товар

Результат запроса:

Товар

Получатель

Количество

Кран

84

Кран

Урюпинскторг

32

Кран

Маг. "Хозяин"

8

Кран

Маг. "Гигант"

44

Вантус

20

Вантус

Урюпинскторг

5

Вантус

Маг. "Хозяин"

1

Вантус

Маг. "Гигант"

14

Стол

26

Стол

Урюпинскторг

1

Стол

Маг. "Мебель"

15

Стол

Маг. "Гигант"

10

Стул

108

Стул

Урюпинскторг

16

Стул

Маг. "Мебель"

55

Стул

Маг. "Хозяин"

5

Стул

Маг. "Гигант"

32

Практические примеры

СГРУППИРОВАТЬ ПО вместе с ИТОГИ: три базовые группы вместо четырёх продаж

Сначала сворачиваем свои продажи по магазину и товару, затем добавляем итоговые уровни. В ИТОГИ ПО не перечисляем агрегаты повторно: они берутся из СУММА списка выборки.

Где и как запускать

Полный серверный общий модуль учебной базы. Собственные значения в памяти, без чтения или записи рабочих данных.

Подготовка

  1. В отдельной учебной базе 8.5.1.1343 создайте общий модуль УчебныйЯзык: Сервер=Истина, Глобальный=Ложь, ВызовСервера=Ложь, Привилегированный=Ложь. Клиентские и внешнее соединение отключены; ПовторноеИспользованиеВозвращаемыхЗначений=НеИспользовать.

  2. Вставьте весь приведённый текст в этот общий модуль. ВыполнитьПример — экспортная точка входа; остальные процедуры и функции располагаются рядом, а не внутри неё.

  3. В своей внешней учебной обработке создайте управляемую форму, команду Выполнить и кнопку. Клиентский обработчик Выполнить(Команда) вызывает свою процедуру ВыполнитьНаСервере(); она имеет директиву &НаСервереБезКонтекста и одну строку УчебныйЯзык.ВыполнитьПример();. Это серверный вызов общего модуля, а не разрешение клиенту прямо обращаться к серверной библиотеке.

  4. Все товары, количества и строки придуманы в этом модуле. Запись документов, подключение к чужой базе, файлы, сеть и печать не используются. В рабочие общие модули текст не вставляйте.

  5. HTML только показывает BSL. Код в 1С не запускался; перечисленные результаты и отрицательные опыты проверяйте самостоятельно в собственном стенде.

Процедура ВыполнитьПример() Экспорт
    Источник = Новый ТаблицаЗначений;
    Источник.Колонки.Добавить("Магазин", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20)));
    Источник.Колонки.Добавить("Товар", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(20)));
    Источник.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(5, 0, ДопустимыйЗнак.Неотрицательный)));
    Источник.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2, ДопустимыйЗнак.Неотрицательный)));
    Данные = Новый Массив;
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Север", "Книга", 3, 250));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Север", "Ручка", 1, 50));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Юг", "Книга", 2, 250));
    Данные.Добавить(Новый Структура("Магазин,Товар,Количество,Цена", "Юг", "Книга", 1, 300));
    Для Каждого Продажа Из Данные Цикл
        СтрокаИсточника = Источник.Добавить();
        СтрокаИсточника.Магазин = Продажа.Магазин;
        СтрокаИсточника.Товар = Продажа.Товар;
        СтрокаИсточника.Количество = Продажа.Количество;
        СтрокаИсточника.Цена = Продажа.Цена;
    КонецЦикла;
    Если Источник.Количество() <> 4 Или Источник.Итог("Количество") <> 7 Тогда
        ВызватьИсключение "Изменились собственные учебные продажи";
    КонецЕсли;
    Менеджер = Новый МенеджерВременныхТаблиц;
    Попытка
        Создание = Новый Запрос;
        Создание.МенеджерВременныхТаблиц = Менеджер;
        Создание.Текст = "ВЫБРАТЬ
        |    Продажи.Магазин КАК Магазин,
        |    Продажи.Товар КАК Товар,
        |    Продажи.Количество КАК Количество,
        |    Продажи.Цена КАК Цена,
        |    Продажи.Количество * Продажи.Цена КАК Сумма
        |ПОМЕСТИТЬ ВТСобственныеПродажи
        |ИЗ &Источник КАК Продажи";
        Создание.УстановитьПараметр("Источник", Источник);
        Создание.Выполнить();
        Запрос = Новый Запрос;
        Запрос.МенеджерВременныхТаблиц = Менеджер;
        Запрос.Текст = "ВЫБРАТЬ
        |    Продажи.Магазин КАК Магазин,
        |    Продажи.Товар КАК Товар,
        |    СУММА(Продажи.Сумма) КАК Сумма
        |ИЗ ВТСобственныеПродажи КАК Продажи
        |СГРУППИРОВАТЬ ПО Продажи.Магазин, Продажи.Товар
        |ИТОГИ ПО ОБЩИЕ, Магазин КАК ПоМагазинам";
        Результат = Запрос.Выполнить();
        Общие = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
        Если Не Общие.Следующий() Тогда
            ВызватьИсключение "Нет общего итога собственных продаж";
        КонецЕсли;
        Если Общие.ТипЗаписи() <> ТипЗаписиЗапроса.ОбщийИтог Или Общие.Сумма <> 1600 Тогда
            ВызватьИсключение "Неверный общий итог или тип записи";
        КонецЕсли;
        ЧислоМагазинов = 0;
        ЧислоДеталей = 0;
        СуммаДеталей = 0;
        Магазины = Общие.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "ПоМагазинам");
        Пока Магазины.Следующий() Цикл
            Если Магазины.ТипЗаписи() <> ТипЗаписиЗапроса.ИтогПоГруппировке Тогда
                ВызватьИсключение "Ожидалась итоговая запись магазина";
            КонецЕсли;
            Если Магазины.Группировка() <> "ПоМагазинам" Или Магазины.Сумма <> 800 Тогда
                ВызватьИсключение "Неверный итог собственной магазинной группировки";
            КонецЕсли;
            ЧислоМагазинов = ЧислоМагазинов + 1;
            Сообщить(Магазины.Магазин + ": " + Строка(Магазины.Сумма));
            Детали = Магазины.Выбрать(ОбходРезультатаЗапроса.Прямой, "");
            Пока Детали.Следующий() Цикл
                Если Детали.ТипЗаписи() <> ТипЗаписиЗапроса.ДетальнаяЗапись Тогда
                    ВызватьИсключение "Ожидалась базовая запись результата, не ещё один итог";
                КонецЕсли;
                ЧислоДеталей = ЧислоДеталей + 1;
                СуммаДеталей = СуммаДеталей + Детали.Сумма;
                Сообщить(Детали.Магазин + "/" + Детали.Товар + ": " + Строка(Детали.Сумма));
            КонецЦикла;
        КонецЦикла;
        Сообщить(ЧислоМагазинов = 2);
        Сообщить(ЧислоДеталей = 3);
        Сообщить(СуммаДеталей = 1600);
        Сообщить(Не Общие.Следующий());
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

Разбор по шагам

  1. Создать те же четыре исходные строки: у Южного магазина две продажи книги 500 и 300, у Северного книга 750 и ручка 50.

  2. СГРУППИРОВАТЬ ПО Магазин,Товар вычисляет СУММА(Сумма) и сворачивает две южные книги до одной базовой строки 800. Базовых строк результата теперь три, хотя исходных продаж четыре.

  3. ИТОГИ ПО ОБЩИЕ, Магазин без списка функций наследует агрегат СУММА из списка ВЫБРАТЬ — документированное совместное использование механизмов.

  4. Общий итог по-прежнему 1600; оба магазина по 800. Их равенство с предыдущим уроком не означает одинаковое число базовых строк.

  5. Именованная контрольная точка ПоМагазинам обходит два магазинных итога; из них прямой обход деталей даёт три записи уже сгруппированного результата.

  6. ТипЗаписи ДетальнаяЗапись описывает уровень результата, а не наличие ссылки на исходный документ. Здесь такая запись может содержать сумму нескольких собственных продаж.

  7. Контроли считают три базовые группы и сумму 1600. Исходная таблица остаётся из четырёх строк; менеджер закрывается во всех исходах.

Как проверить результат

  1. Четыре конечных проверки Истина: 2 магазина, 3 базовые группы, сумма 1600 и одна запись общего итога.

  2. Юг/Книга выводится один раз с 800, Север/Книга с 750 и Север/Ручка с 50. Это не потеря продажи, а её агрегирование.

  3. Сравните с предыдущим уроком без СГРУППИРОВАТЬ ПО: там деталей 4, здесь 3; итог одинаковый.

Ожидаемый результат

Показано и проверено документированное наследование итоговых агрегатов от сгруппированной базовой выборки.

На что обратить внимание

  1. Базовая строка сгруппированного результата не равна физической строке исходных данных.

  2. При объединении запросов итоговые функции наследуются из первого запроса; этот урок не содержит объединения на итоговом этапе.

  3. Не складывайте итоговые и базовые строки вместе и не меняйте ожидаемое количество на 4 только потому, что в исходной таблице четыре записи.

  4. ПоМагазинам — явно заданное имя группировки, не неизвестный автоматически созданный псевдоним.

  5. Точные результаты требуют проверки в собственной учебной базе 8.5.1.1343; здесь BSL не запускался.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.