Расчет общих итогов

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

Синтаксис и применение Расчет общих итогов в платформе 1С:Предприятие. Описание и примеры кода.

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

Расчет общих итогов

Для расчета итогов по всей таблице в предложении ИТОГИ следует указать слово ОБЩИЕ. В этом случае будут вычислены значения агрегатных функций для всех записей таблицы.

Пример:

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

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

Товар

Количество

Номер

Получатель

238

Кран

10

РНк-1

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

Кран

8

РНк-3

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

Кран

44

РНк-4

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

Кран

22

РНк-5

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

Вантус

5

РНк-1

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

Вантус

1

РНк-3

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

Вантус

14

РНк-4

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

Стол

1

РНк-1

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

Стол

15

РНк-2

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

Стол

10

РНк-4

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

Стул

55

РНк-2

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

Стул

5

РНк-3

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

Стул

32

РНк-4

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

Стул

16

РНк-5

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

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

ИТОГИ: общий уровень, магазины и исходные продажи

Сохраняем четыре базовые продажи и добавляем общий итог 1600 и два магазинных итога 800. Контрольной точке даём явный псевдоним ПоМагазинам и обходим уровни отдельно.

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

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

Подготовка

  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);
        Сообщить(ЧислоДеталей = 4);
        Сообщить(СуммаДеталей = 1600);
        Сообщить(Не Общие.Следующий());
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

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

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

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

  3. Псевдоним контрольной точки ПоМагазинам задаёт имя группировки для встроенного языка. Это не переименование колонки Магазин.

  4. Корневой обход ПоГруппировкам получает первый уровень ОБЩИЕ. Проверяем наличие записи, её ТипЗаписи ОбщийИтог и сумму 1600.

  5. Из текущего общего итога создаём дочернюю выборку по точному псевдониму ПоМагазинам. Тип каждой записи должен быть ИтогПоГруппировке, сумма каждого магазина 800.

  6. Из каждого магазина получаем Прямой обход с пустым списком группировок: по документации это детальные записи. Их тип — ДетальнаяЗапись, а число по обоим магазинам — 4.

  7. Суммируем только базовые детали и получаем 1600. Не добавляем к ним общий и магазинные итоги, иначе посчитаем одну продажу несколько раз.

  8. Контроль Не Общие.Следующий() исключает неожиданную вторую корневую запись. Свой менеджер закрывается после завершения или при исключении.

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

  1. После вывода названий магазинов и четырёх продаж конечные четыре проверки дают Истина: 2 магазина, 4 детали, сумма деталей 1600, единственный общий итог.

  2. Север содержит Книга 750 и Ручка 50; Юг — две Книга с суммами 500 и 300. Две одинаковые товарные метки не становятся одной исходной продажей.

  3. Порядок магазинов без явного УПОРЯДОЧИТЬ не обещается. Проверяются типы, количества и суммы, а не первый магазин.

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

Реальный результат запроса разобран по уровням общего итога, магазинных итогов и четырёх собственных базовых строк.

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

  1. СГРУППИРОВАТЬ ПО и ИТОГИ не взаимозаменяемы: первый механизм сворачивает базовые строки, второй создаёт итоговые уровни.

  2. ТипЗаписи — метод выборки, не значение реквизита с похожим именем. Проверяйте его перед трактовкой строки как продажи.

  3. Псевдоним ПоМагазинам относится к контрольной точке. Чтение Магазины.Магазин всё ещё использует имя колонки результата.

  4. Нельзя суммировать 1600 + 800 + 800 и затем ещё базовые продажи как единую выручку.

  5. Итоги по иерархии ссылок, периоды и вложенные таблицы в этот простой источник не входят. Запуска в 1С не было.

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

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

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

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

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