ВЫБОР: назначить категорию и сумму пяти своим количествам

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

При количествах 0,1,4,5,8 оптовая граница сначала равна 5, затем 8. Одна строка получает только первую истинную альтернативу; ИНАЧЕ формирует значение для нуля, сохраняя саму строку.

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

Полный серверный общий модуль учебной базы 8.5.1.1343; все значения и источники собственные. Локальные Python-проверки не являются выполнением BSL или запросов в 1С; код здесь не запускался.

Подготовка

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

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

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

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

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

  6. Все helper-процедуры входят в модуль. Количество должно быть целым от 0 до 10, код — целым от 1 до 5; минимум — целым от 1 до 10.

  7. Встроенные отрицательные опыты запускаются до создания менеджера; неизвестные рабочие источники и внешние данные не используются.

Процедура ВыполнитьПример() Экспорт
    Источник = СоздатьСвоиКоличества();
    ПроверитьОтказКоличества(Источник, -1);
    ПроверитьОтказКоличества(Источник, "5");
    ПроверитьОтказКоличества(Источник, 1.5);
    ДобавитьСвоёКоличество(Источник, 1, 0);
    ДобавитьСвоёКоличество(Источник, 2, 1);
    ДобавитьСвоёКоличество(Источник, 3, 4);
    ДобавитьСвоёКоличество(Источник, 4, 5);
    ДобавитьСвоёКоличество(Источник, 5, 8);
    Минимум = 5;
    ПроверитьСвойМинимум(Минимум);
    Менеджер = Новый МенеджерВременныхТаблиц;
    Попытка
        Создание = Новый Запрос;
        Создание.МенеджерВременныхТаблиц = Менеджер;
        Создание.Текст = "ВЫБРАТЬ Данные.Код КАК Код, Данные.Количество КАК Количество
        |ПОМЕСТИТЬ ВТСвоиКоличества
        |ИЗ &Источник КАК Данные";
        Создание.УстановитьПараметр("Источник", Источник);
        Создание.Выполнить();
        Запрос = Новый Запрос;
        Запрос.МенеджерВременныхТаблиц = Менеджер;
        Запрос.Текст = "ВЫБРАТЬ
        |    Позиции.Код КАК Код,
        |    Позиции.Количество КАК Количество,
        |    ВЫБОР
        |        КОГДА Позиции.Количество >= &Минимум ТОГДА ""Оптовая""
        |        КОГДА Позиции.Количество > 0 ТОГДА ""Обычная""
        |        ИНАЧЕ ""Нет количества""
        |    КОНЕЦ КАК Категория,
        |    ВЫБОР
        |        КОГДА Позиции.Количество >= &Минимум ТОГДА Позиции.Количество * &Цена * 0.9
        |        ИНАЧЕ Позиции.Количество * &Цена
        |    КОНЕЦ КАК Сумма
        |ИЗ ВТСвоиКоличества КАК Позиции
        |УПОРЯДОЧИТЬ ПО Код";
        Запрос.УстановитьПараметр("Минимум", Минимум);
        Запрос.УстановитьПараметр("Цена", 100);
        ПервыйВыбор = Запрос.Выполнить().Выгрузить();
        Ожидание = Новый Массив;
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 1, 0, "Нет количества", 0));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 2, 1, "Обычная", 100));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 3, 4, "Обычная", 400));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 4, 5, "Оптовая", 450));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 5, 8, "Оптовая", 720));
        ПроверитьСвойВыбор(ПервыйВыбор, Ожидание);
        Минимум = 8;
        ПроверитьСвойМинимум(Минимум);
        Запрос.УстановитьПараметр("Минимум", Минимум);
        ВторойВыбор = Запрос.Выполнить().Выгрузить();
        Ожидание = Новый Массив;
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 1, 0, "Нет количества", 0));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 2, 1, "Обычная", 100));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 3, 4, "Обычная", 400));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 4, 5, "Обычная", 500));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 5, 8, "Оптовая", 720));
        ПроверитьСвойВыбор(ВторойВыбор, Ожидание);
        Ожидание = Новый Массив;
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 1, 0, "Нет количества", 0));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 2, 1, "Обычная", 100));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 3, 4, "Обычная", 400));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 4, 5, "Оптовая", 450));
        Ожидание.Добавить(Новый Структура("Код,Количество,Категория,Сумма", 5, 8, "Оптовая", 720));
        ПроверитьСвойВыбор(ПервыйВыбор, Ожидание);
        Если Источник.Количество() <> 5 Тогда
            ВызватьИсключение "Собственный источник количеств изменился";
        КонецЕсли;
    Исключение
        Менеджер.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Менеджер.Закрыть();
КонецПроцедуры

Функция СоздатьСвоиКоличества()
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Код", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2, 0, ДопустимыйЗнак.Неотрицательный)));
    Таблица.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(2, 0, ДопустимыйЗнак.Неотрицательный)));
    Возврат Таблица;
КонецФункции

Процедура ДобавитьСвоёКоличество(Таблица, Код, Количество)
    Если ТипЗнч(Код) <> Тип("Число") Или ТипЗнч(Количество) <> Тип("Число") Тогда
        ВызватьИсключение "Код и количество должны быть числами";
    КонецЕсли;
    Если Код < 1 Или Код > 5 Или Код <> Цел(Код) Тогда
        ВызватьИсключение "Код должен быть целым от 1 до 5";
    КонецЕсли;
    Если Количество < 0 Или Количество > 10 Или Количество <> Цел(Количество) Тогда
        ВызватьИсключение "Количество должно быть целым от 0 до 10";
    КонецЕсли;
    НоваяСтрока = Таблица.Добавить();
    НоваяСтрока.Код = Код;
    НоваяСтрока.Количество = Количество;
КонецПроцедуры

Процедура ПроверитьСвойМинимум(Минимум)
    Если ТипЗнч(Минимум) <> Тип("Число") Тогда
        ВызватьИсключение "Минимум должен быть одним числом";
    КонецЕсли;
    Если Минимум < 1 Или Минимум > 10 Или Минимум <> Цел(Минимум) Тогда
        ВызватьИсключение "Минимум должен быть целым от 1 до 10";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьОтказКоличества(Таблица, НеверноеКоличество)
    Отклонено = Ложь;
    Попытка
        ДобавитьСвоёКоличество(Таблица, 1, НеверноеКоличество);
    Исключение
        Отклонено = Истина;
    КонецПопытки;
    Если Не Отклонено Тогда
        ВызватьИсключение "Неверное количество прошло подготовку";
    КонецЕсли;
    Сообщить("Неверное количество отклонено до добавления строки");
КонецПроцедуры

Процедура ПроверитьСвойВыбор(Таблица, Ожидание)
    Если Таблица.Колонки.Количество() <> 4 Или Таблица.Количество() <> Ожидание.Количество() Тогда
        ВызватьИсключение "Размер собственного результата ВЫБОР не совпал";
    КонецЕсли;
    Если Ожидание.Количество() > 0 Тогда
        Для Индекс = 0 По Ожидание.Количество() - 1 Цикл
            Если Таблица[Индекс].Код <> Ожидание[Индекс].Код
                Или Таблица[Индекс].Количество <> Ожидание[Индекс].Количество
                Или Таблица[Индекс].Категория <> Ожидание[Индекс].Категория
                Или Таблица[Индекс].Сумма <> Ожидание[Индекс].Сумма Тогда
                ВызватьИсключение "Полный состав собственного результата ВЫБОР не совпал";
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    Сообщить("Проверены все категории и суммы: " + Строка(Таблица.Количество()));
КонецПроцедуры

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

  1. Создать свою типизированную таблицу кодов и количеств. До добавления строк проверить отказ для -1, строки "5" и дробного 1.5; ноль при этом разрешён.

  2. Добавить ровно пять строк: 1/0,2/1,3/4,4/5,5/8. Поместить их в приватную ВТСвоиКоличества собственного менеджера.

  3. Первый ВЫБОР вычисляет Категория. КОГДА Количество>=Минимум стоит перед Количество>0: количество 5 удовлетворяет обоим, но результат только Оптовая.

  4. При количестве 1 или 4 первое условие ложно, второе истинно, поэтому Категория=Обычная. Для нуля оба ложны, применяется ИНАЧЕ Нет количества.

  5. Второй ВЫБОР вычисляет числовую Сумма. Оптовая ветвь умножает собственное количество на фиксированную цену 100 и коэффициент 0.9; ИНАЧЕ берёт полную цену.

  6. При Минимум=5 проверить все четыре поля пяти строк: категории Нет количества,Обычная,Обычная,Оптовая,Оптовая и суммы 0,100,400,450,720.

  7. Поменять единственный параметр Минимум на 8 и выполнить тот же запрос: строка количества 5 становится Обычная/500; строка количества 8 остаётся Оптовая/720.

  8. Повторно проверить первый результат: в нём строка количества 5 сохраняет Оптовая/450. Изменение параметра влияет на следующее выполнение, а не на ранее выгруженную таблицу.

  9. В запросе нет ГДЕ: нулевая строка остаётся в результате с вычисленными значениями. ВЫБОР выбирает значение выражения, а не удаляет записи.

  10. Проверка размера выполняется до обращения по индексу. Затем проверяется код, количество, категория и сумма каждой строки; менеджер закрывается при успехе и исключении.

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

  1. Три сообщения об отклонённом количестве; источник после этого содержит только пять явно добавленных строк.

  2. При границе 5 полные строки: 1/0/Нет количества/0; 2/1/Обычная/100; 3/4/Обычная/400; 4/5/Оптовая/450; 5/8/Оптовая/720.

  3. При границе 8 меняется только строка 4/5: Обычная/500. Первый снимок сохраняется; все три проверки полного состава завершаются без исключений.

  4. Проверяйте границы непосредственно ниже, на самой границе и выше: здесь 4,5,8. Для другой границы сначала пересчитайте и замените ожидаемый полный состав.

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

Последовательная обработка КОГДА, вычисление ИНАЧЕ, строковая и числовая ветви показаны в законченном модуле с двумя независимыми выполнениями.

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

  1. Если переставить Количество>0 выше оптовой альтернативы, все положительные количества получат Обычная: первая истинная альтернатива завершает операцию выбора.

  2. Цена 100 и коэффициент 0.9 — собственные фиксированные числа; пример не задаёт правила округления, НДС, реальные скидки или цены конфигурации.

  3. Здесь ИНАЧЕ указан явно и все ветви Категория имеют тип Строка, все ветви Сумма — Число. Смешанные типы и отсутствие ИНАЧЕ этим опытом не исследованы.

  4. Допустимые количества и минимум ограничены нашей подготовкой. Это не ограничение числа альтернатив ВЫБОР в платформе: нативная страница разрешает неограниченное количество альтернатив.

  5. Python-модель проверяет пять фиксированных количеств и явные ожидаемые результаты. Она не запускает серверный модуль 1С.

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

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

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

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

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