При разработке сложных механизмов, таких как обработка штрихкодов или заполнение документов, часто возникает необходимость запросить у пользователя числовое значение (например, количество товара) непосредственно в середине выполнения алгоритма. Стандартный подход с использованием ОписаниеОповещения и метода ПоказатьВводЧисла заставляет разработчика разрывать единую процедуру на несколько частей, что усложняет чтение и отладку кода. В этой статье мы разберем несколько способов, как можно реализовать ввод количества, сохранив логику процесса максимально линейной и понятной.
Проанализируем современный подход, который появился в платформе с введением механизмов Async/Await. Это наиболее изящное решение проблемы «разрыва кода». Если ваша конфигурация работает на платформе версии 8.3.18 или выше, и в свойствах конфигурации установлен режим использования модальности Не использовать, вы можете применять оператор Ждать.
Рассмотрим пример кода, который позволяет остановить выполнение процедуры до тех пор, пока пользователь не введет число, при этом не создавая отдельные процедуры-обработчики:
&НаКлиенте
Асинхронная Процедура ОбработатьШтрихкод(ДанныеШК)
// Логика до ввода количества
НайденныйТовар = НайтиТоварПоШтрихкоду(ДанныеШК);
// Вызываем окно ввода и ждем результат
Подсказка = "Введите количество для: " + НайденныйТовар;
Результат = Ждать ПоказатьВводЧислаАсинх (Подсказка, 1);
Если Результат <> Неопределено Тогда
Количество = Результат;
// Продолжаем выполнение в той же процедуре
ДобавитьТоварВКорзину(НайденныйТовар, Количество);
КонецЕсли;
КонецПроцедуры
Выясним, в чем преимущество: оператор Ждать приостанавливает выполнение Асинхронная Процедура, сохраняя все локальные переменные. Как только пользователь закрывает окно ввода, выполнение возобновляется со следующей строки.
Разберем ситуацию, когда стандартное системное окно ПоказатьВводЧисла не подходит по дизайну или функциональности (например, если требуется ввод на сенсорном экране с крупными кнопками). В этом случае эффективным решением будет создание собственной формы. Чтобы не разрабатывать диалоговые окна с нуля, можно воспользоваться универсальной формой для ввода значений различных типов.
Пошагово реализуем этот подход:
ВводКоличества.ЧислоВвода и кнопки цифровой клавиатуры (0-9).Вызов такой формы в современных управляемых приложениях без модальности все равно потребует ОписаниеОповещения, если не используется Ждать. Однако, если ваша система допускает использование модальных окон (что не рекомендуется, но встречается в старых решениях), можно использовать ОткрытьФормуМодально. Если же мы придерживаемся стандартов 1С и БСП, то вызов будет выглядеть так:
&НаКлиенте
Процедура ПослеВводаКоличества(Результат, ДополнительныеПараметры) Экспорт
Если ТипЗнч(Результат) = Тип("Число") Тогда
// Продолжаем обработку
ЗавершитьОбработкуШтрихкода(Результат, ДополнительныеПараметры.Товар);
КонецЕсли;
КонецПроцедуры
Если вы разрабатываете решение на базе библиотек 1С, например, используете подсистемы БСП или торговые конфигурации, стоит обратить внимание на уже существующие объекты. В конфигурации 1С:Розница или в подсистеме РМК (Рабочее место кассира) существует форма ФормаВводаЧисла.
Проанализируем преимущества использования готовых форм:
Чтобы найти такую форму в БСП, стоит проверить наличие общей формы ВводКоличестваИЦены. Несмотря на то, что она чаще встречается в ERP или УТ, принципы ее вызова идентичны стандартным формам 1С.
Хотя фирма «1С» активно призывает отказываться от модальности, в некоторых случаях (например, в локальных инструментах администратора) разработчики используют метод ВвестиЧисло. Рассмотрим, почему автор исходного вопроса упоминал его как альтернативу.
Метод ВвестиЧисло полностью останавливает поток выполнения кода в месте вызова (если разрешены модальные окна в свойствах конфигурации). Это позволяет писать код «линейно», без обработчиков ожидания:
Количество = 0;
Если ВвестиЧисло(Количество, "Укажите количество", 10, 3) Тогда
// Код выполнится только после того, как пользователь нажмет ОК
ОбработатьДанные(Количество);
КонецЕсли;
Важное примечание: Использование этого метода заблокирует работу во всех вкладках приложения и не будет работать в веб-клиенте (браузере), если модальные окна запрещены. Поэтому данный метод следует рассматривать только как временное или узкоспециализированное решение.
Посмотрим на ситуацию шире. Если вы столкнулись с проблемой «длинной процедуры», которую неудобно разбивать, возможно, стоит пересмотреть архитектуру обработки событий. В БСП при работе с торговым оборудованием рекомендуется событийная модель.
Вместо одной огромной процедуры ОбработатьШтрихкод, разделите логику на этапы:
Использование состояния формы (реквизитов формы) для хранения промежуточных данных между этими этапами — это стандарт «де-факто» в разработке на 1С. Это позволяет избежать проблем с потерей контекста при асинхронных вызовах и делает код более устойчивым к ошибкам пользователя.
Таким образом, мы выяснили, что наиболее правильным современным решением является использование Ждать ПоказатьВводЧислаАсинх, а при необходимости кастомного интерфейса — создание своей формы в расширении с аналогичным асинхронным вызовом.