ПоказатьВводЗначения: получить составной результат без вечной блокировки

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

Своё окно позволяет цену либо код скидки. Результат обрабатывается по типу, а отсутствие вызова callback при неоткрытом окне не оставляет отключённую кнопку.

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

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

Подготовка

  1. В отдельной учебной базе платформы 8.5.1.1343 создайте внешнюю обработку УчебнаяФорма85 с пустой управляемой основной формой. Используйте тонкий клиент Windows.

  2. В свойствах формы → События назначьте ПриСозданииНаСервере. Вставьте полный модуль урока, включая клиентские и серверные помощники, на уровне модуля.

  3. Не создавайте вручную ЗначениеПримера, ПолеПримера и кнопку: код создаёт их полностью. Каждый урок запускайте в отдельной копии своей формы.

  4. Сохраните свою EPF и откройте её в учебной базе. Собственное количество начинается с 3, цена книги задана в коде как 250; исходный расчёт равен 750.

  5. Связанный реквизит помечен как СохраняемыеДанные для изучения поведения формы. Это признак реквизита формы, а не автоматическая запись книги, файла или документа в базу.

  6. Команда расчёта имеет ИзменяетСохраняемыеДанные = Ложь. Уроки изменяют только свой интерфейс и значения собственной формы, не конфигурацию и не рабочие данные.

  7. Запуск и вид в 1С не проверены. Компоновку, сочетания клавиш и расположение команд осмотрите вручную в указанном клиенте; не переносите настройки на рабочие формы без отдельной проверки.

  8. В этой партии каждое окно ввода запускает собственная кнопка УчебноеДействие. Изучайте один полный модуль за раз; никакие значения ввода не исполняются как код.

Перем АктивныйЗапрос;

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


    КомандаДействия = ЭтаФорма.Команды.Добавить("УчебноеДействие");
    КомандаДействия.Действие = "УчебноеДействие";
    КомандаДействия.Заголовок = "Выполнить собственный учебный шаг";
    КомандаДействия.Подсказка = "Действие только над данными учебной формы";
    КомандаДействия.ИзменяетСохраняемыеДанные = Ложь;
    Кнопка = Элементы.Добавить("КнопкаУчебноеДействие", Тип("КнопкаФормы"));
    Кнопка.ИмяКоманды = КомандаДействия.Имя;
    Кнопка.Заголовок = КомандаДействия.Заголовок;
КонецПроцедуры

&НаКлиенте
Процедура УчебноеДействие(Команда)
    ДоВвода = ЗначениеПримера;
    Маркер = Новый УникальныйИдентификатор;
    КонтекстВвода = Новый Структура("Маркер,ДоВвода", Маркер, ДоВвода);
    АктивныйЗапрос = Маркер;
    Оповещение = Новый ОписаниеОповещения("ПослеСобственногоВвода", ЭтаФорма, КонтекстВвода);
    Попытка
        ТипВвода = Новый ОписаниеТипов("Число,Строка", Новый КвалификаторыЧисла(8, 2, ДопустимыйЗнак.Неотрицательный), Новый КвалификаторыСтроки(20));
        ПоказатьВводЗначения(Оповещение, Неопределено, "Введите свою цену или код УЧЕБНЫЙ10", ТипВвода);
    Исключение
        АктивныйЗапрос = Неопределено;
        ВызватьИсключение;
    КонецПопытки;
    Сообщить("Запрос ввода сделан; результат обрабатывается только в процедуре завершения");

КонецПроцедуры

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

&НаКлиенте
Процедура ПослеСобственногоВвода(Введено, ДополнительныеПараметры) Экспорт
    Если Не ЭтаФорма.Открыта() Тогда
        Возврат;
    КонецЕсли;
    Если ДополнительныеПараметры.Маркер <> АктивныйЗапрос Тогда
        Сообщить("Устаревший ответ собственного диалога не применяется");
        Возврат;
    КонецЕсли;
    АктивныйЗапрос = Неопределено;
    ДоВвода = ДополнительныеПараметры.ДоВвода;
    Если Введено = Неопределено Тогда
        Сообщить("Отмена: собственные данные не менялись");
        Возврат;
    КонецЕсли;
    Если ЗначениеПримера <> ДоВвода Тогда
        Сообщить("Количество изменилось за время диалога. Повторите ввод для актуальной заявки");
        Возврат;
    КонецЕсли;
    ПроверитьСобственноеКоличество();
    Если ТипЗнч(Введено) = Тип("Число") Тогда
        Если Введено <= 0 Или Введено > 1000 Тогда
            ВызватьИсключение "Собственная учебная цена должна быть больше 0 и не выше 1000";
        КонецЕсли;
        Цена = Введено;
        Скидка = 0;
    ИначеЕсли ТипЗнч(Введено) = Тип("Строка") Тогда
        Код = ВРег(СокрЛП(Введено));
        Если Код <> "УЧЕБНЫЙ10" Тогда
            ВызватьИсключение "Урок принимает только собственный код УЧЕБНЫЙ10";
        КонецЕсли;
        Цена = 250;
        Скидка = 10;
    Иначе
        ВызватьИсключение "Ожидалась собственная цена или строковый учебный код";
    КонецЕсли;
    Сумма = Окр(ЗначениеПримера * Цена * (100 - Скидка) / 100, 2);
    Сообщить(ТипЗнч(Сумма) = Тип("Число"));
    Сообщить(Сумма = Окр(ДоВвода * Цена * (100 - Скидка) / 100, 2));
    Сообщить(ЗначениеПримера = ДоВвода);
    Сообщить(СтрШаблон("Собственная цена %1; скидка %2%; количество %3; сумма %4", Цена, Скидка, ЗначениеПримера, Сумма));

КонецПроцедуры

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

  1. Сохранить собственный UUID и количество в структуре оповещения. Начальное значение ввода Неопределено и описание Число/Строка заданы явно.

  2. Вызвать ПоказатьВводЗначения с четырьмя аргументами. Сам вызов не возвращает пользовательское значение.

  3. Установленная справка предупреждает: если форма не открылась, процедура оповещения не вызывается. Поэтому урок не отключает кнопку бессрочно и допускает новый запрос с новым маркером.

  4. Получив результат, проверить свою открытую форму, актуальный маркер, отмену и снимок количества. Затем отличить число от строки.

  5. Для цены 100 получить 300, для собственного УЧЕБНЫЙ10 — 675. При другом типе или недопустимом содержимом дать явное исключение до рабочего действия.

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

  1. Оба допустимых варианта выводят три Истина, количество остаётся 3. Отмена не меняет его.

  2. Проверьте два параметра экспортного обработчика и дополнительную структуру. Если диалог не появился, собственная кнопка не отключена и можно повторить запрос, не дожидаясь отсутствующего callback.

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

Контракт составного callback и документированное отсутствие гарантии вызова обработчика отражены прямо в полном коде.

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

  1. Не создавайте цикл или обработчик ожидания, который принудительно ожидает неподтверждённый callback.

  2. Маркер не является платёжным токеном и не передаётся в сеть: он отличает только собственные запросы интерфейса.

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

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

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

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

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

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