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