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