Заменить сумму количества максимумом и вернуть обратно

Учебные задачи

Меняем только выражение итога своей колонки: максимум из 3, 2, 1 равен 3. Затем удаляем определение и создаём новую сумму 6.

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

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

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

  2. СхемаЗапроса редактирует структуру и формирует текст, а Запрос выполняет этот текст. Родительская схема должна оставаться в переменной, пока используются её дочерние объекты.

  3. Не переносите полученные дочерние объекты между разными схемами и не обращайтесь к элементу после его удаления. Упражнения удаления работают только со своей структурой в памяти.

Схема = Новый СхемаЗапроса;
Схема.РежимКомпоновкиДанных = Ложь;
Схема.УстановитьТекстЗапроса("ВЫБРАТЬ Строки.Наименование КАК Наименование, Строки.Количество КАК Количество
|ИЗ (ВЫБРАТЬ ""Книга"" КАК Наименование, 3 КАК Количество
|ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""Книга"", 2
|ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ""Ручка"", 1) КАК Строки
|ИТОГИ СУММА(Количество) ПО ОБЩИЕ, Наименование");
Если Схема.ПакетЗапросов.Количество() <> 1 Тогда
    ВызватьИсключение "Ожидался один собственный запрос итогов";
КонецЕсли;
Выбор = Схема.ПакетЗапросов.Получить(0);
Если ТипЗнч(Выбор) <> Тип("ЗапросВыбораСхемыЗапроса") Тогда
    ВызватьИсключение "Ожидалась выборка собственных итогов";
КонецЕсли;
Если Не Выбор.ОбщиеИтоги Тогда
    ВызватьИсключение "Собственный запрос должен содержать ОБЩИЕ";
КонецЕсли;
Итоги = Выбор.ВыраженияИтогов;
ИтогКоличество = Итоги.НайтиПоПолю("Количество");
Если ИтогКоличество = Неопределено Тогда
    ВызватьИсключение "Не найден собственный итог для замены";
КонецЕсли;
ИтогКоличество.Выражение = Новый ВыражениеСхемыЗапроса("МАКСИМУМ(Количество)");
Запрос = Новый Запрос(Схема.ПолучитьТекстЗапроса());
Максимум = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
ПроверенМаксимум = Ложь;
Пока Максимум.Следующий() Цикл
    Если Максимум.ТипЗаписи() = ТипЗаписиЗапроса.ОбщийИтог Тогда
        ПроверенМаксимум = Максимум.Количество = 3;
    КонецЕсли;
КонецЦикла;
Если Не ПроверенМаксимум Тогда
    ВызватьИсключение "Общий максимум своих чисел не равен 3";
КонецЕсли;
Сообщить(ПроверенМаксимум);
ИндексИтога = Итоги.Индекс(ИтогКоличество);
Если ИндексИтога < 0 Или ИндексИтога >= Итоги.Количество() Тогда
    ВызватьИсключение "Недопустимый индекс своего итога";
КонецЕсли;
Итоги.Удалить(ИндексИтога);
Итоги.Добавить("СУММА(Количество)", "Количество");
Сообщить(Итоги.Количество() = 1);
Запрос = Новый Запрос(Схема.ПолучитьТекстЗапроса());
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
НайденОбщий = Ложь;
Пока Выборка.Следующий() Цикл
    Если Выборка.ТипЗаписи() = ТипЗаписиЗапроса.ОбщийИтог Тогда
        НайденОбщий = Истина;
        Сообщить(Выборка.Количество = 6);
        Детальные = Выборка.Выбрать(ОбходРезультатаЗапроса.Прямой);
        ЧислоСтрок = 0;
        СуммаСтрок = 0;
        Пока Детальные.Следующий() Цикл
            ЧислоСтрок = ЧислоСтрок + 1;
            СуммаСтрок = СуммаСтрок + Детальные.Количество;
        КонецЦикла;
        Сообщить(ЧислоСтрок = 3 И СуммаСтрок = 6);
    КонецЕсли;
КонецЦикла;
Если Не НайденОбщий Тогда
    ВызватьИсключение "Не найден собственный общий итог";
КонецЕсли;
Сообщить(НайденОбщий);
Итоги.Очистить();
Сообщить(Итоги.Количество() = 0);

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

  1. Найденное выражение изменяем новым объектом ВыражениеСхемыЗапроса, не присваиваем строку.

  2. Выполняем текст схемы и ищем именно ОбщийИтог: МАКСИМУМ даёт 3, а не сумму 6.

  3. Допустимый индекс найден до удаления определения; старый ИтогКоличество больше не используется.

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

  5. После проверки восстановленной суммы очищаем только свою коллекцию. Запрос без выражений итогов дальше не выполняется.

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

  1. Шесть сообщений Истина.

  2. Максимум 3, затем восстановленная сумма 6; после очистки выражений 0.

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

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

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

  1. Поле выражения итога только для чтения; его нельзя подменять присваиванием.

  2. Очистка меняет только собственную схему в памяти, не остатки базы.

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

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

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

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

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