В этой небольшой статье мы рассмотрим три способа, как в 1С показать пользователю вопрос.
В 1С Предприятие есть возможность средствами встроенного языка показать пользователю окно с вопросом и несколькими вариантами ответа, например “Вы уверены, что хотите уничтожить все документы с начала времен?” и ответы “Да, Нет, Я подумаю, Отмена”.
Метод "Вопрос"
Простейший способ показать вопрос пользователю – метод глобального контекста Вопрос. Этот метод является синхронным и к тому же модальным, и не рекомендуется к использованию, однако все еще встречается как в различных обработках и отчетах, так и в конфигурациях. Использовать его очень просто – мы указываем строку вопроса, варианты ответа, и обрабатываем выбранный пользователем вариант.
&НаКлиенте Процедура КомандаВопрос(Команда) Ответ = Вопрос("Вы видите текст вопроса?", РежимДиалогаВопрос.ДаНет); Сообщить("Ваш ответ "+ Ответ); КонецПроцедуры
Но, как всегда, есть нюансы. У этого метода есть несколько необязательных параметров, такие как таймаут, кнопка по умолчанию, заголовок, и кнопка таймаута (на ней будут отображаться оставшиеся секунды до таймаута). Кроме того, помимо системных режимов диалога (“Да/Нет”, “Ок/Отмена” и других), разработчик может задать свой список значений с вариантами ответа на вопрос.
&НаКлиенте Процедура ВопросИзСписка(Команда) СписокКнопок = Новый СписокЗначений; СписокКнопок.Добавить("Синий", "Синий"); СписокКнопок.Добавить("Зеленый", "Зеленый"); СписокКнопок.Добавить("Красный", "Красный"); Ответ = Вопрос("Какой провод перерезать?", СписокКнопок, 20,,,"Красный"); Сообщить("Вы перерезали "+ Ответ + " провод"); КонецПроцедуры
Ну и вишенка на торте. Мало кто знает, а еще меньше тех кто пользуется – вопрос можно задавать в виде форматированной строки. Попробуйте, вдруг вам понравится:)
&НаКлиенте Процедура ВопросСРаскраской(Команда) СписокКнопок = Новый СписокЗначений; СписокКнопок.Добавить("Синий", "Синий"); СписокКнопок.Добавить("Зеленый", "Зеленый"); СписокКнопок.Добавить("Красный", "Красный"); ФорматированнаяСтрока = Новый ФорматированнаяСтрока("Какой провод перерезать? Варианты: ", Новый ФорматированнаяСтрока("Синий; ", , WebЦвета.Синий), Новый ФорматированнаяСтрока("Зеленый; ", , WebЦвета.Зеленый), Новый ФорматированнаяСтрока("Красный.", , WebЦвета.Красный)); Ответ = Вопрос(ФорматированнаяСтрока, СписокКнопок, 20,,,"Красный"); Сообщить("Вы перерезали "+ Ответ + " провод"); КонецПроцедуры
Метод ПоказатьВопрос
Так как 1С планомерно отходит от модальности и синхронных методов, которые блокируют интерфейс и/или работу программы, рассмотрим асинхронный метод ПоказатьВопрос. Помимо всех параметров, рассмотренных выше, данный метод имеет еще один параметр: ОписаниеОповещенияОЗавершении. В этот параметр передается специальный объект с типом ОписаниеОповещения. Чтобы не мучиться и не писать в ручную, можно воспользоваться меню рефакторинга и преобразовать вызов.
Кликаем правой кнопкой на методе Вопрос в коде, в контекстном меню выбираем Рефакторинг / Нерекомендуемые синхронные вызовы / Преобразовать вызов. И платформа сама разделит наш метод на ПоказатьВопрос и обработку оповещения.
&НаКлиенте Процедура КомандаВопрос(Команда) Ответ = Неопределено; ПоказатьВопрос(Новый ОписаниеОповещения("КомандаВопросЗавершение", ЭтотОбъект), "Вы видите текст вопроса?", РежимДиалогаВопрос.ДаНет); КонецПроцедуры &НаКлиенте Процедура КомандаВопросЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт Ответ = РезультатВопроса; Сообщить("Ваш ответ "+ Ответ); КонецПроцедуры
Разумеется, получившийся код можно и нужно “причесать” – можно вынести описание оповещения в отдельную переменную, добавить дополнительные параметры, убрать ставший лишним код и т.д.
Метод ВопросАсинх
Начиная с версии 8.3.18 в платформе 1С появились новые асинхронные методы, работа с которыми во многом похожа на asinc / await в JavaScript. Мы объявляем метод с ключевым словом Асинх, и в этом методе становится возможным использовать асинхронные методы. Перед вызовом метода ВопросАсинх мы указываем еще одно ключевое слово “Ждать”. Сам по себе метод ВопросАсинх не останавливает выполнение кода, и если не указать “Ждать”, то весь код ниже будет выполнен, и результат может быть не тот, что ожидался. По большому счету, это синтаксический сахар, призванный упростить код и облегчить жизнь разработчику.
Попробуйте убрать ключевое слово “Ждать” и сравните поведение программы 😉
&НаКлиенте Асинх Процедура КомандаВопросАсинх(Команда) Ответ = Ждать ВопросАсинх("Вы заметили, что это асинхронный вопрос?", РежимДиалогаВопрос.ДаНет,,,"А ведь это асинхронный вопрос!"); Сообщить("Ваш ответ "+ Ответ); КонецПроцедуры
В остальном, этот метод имеет все те же параметры, что и метод “Вопрос”, который мы рассмотрели в самом начале.
Ответы
В зависимости от того, как мы задали параметр “Кнопки”, ответы могут быть самые различные. Если использовать РежимДиалогаВопрос, то у ответа тип значения будет КодВозвратаДиалога. Если же указать кнопки в виде списка значений, то в поле Ответ будет содержаться значение, привязанное к соответствующей кнопке. Типы значений в списке кнопок можно задавать самые различные. А следовательно, и логику обработки ответа можно реализовать самую разную, в зависимости от полученного значения и его типа.
&НаКлиенте Процедура ОтветыРазныхТипов(Команда) СписокКнопок = Новый СписокЗначений; СписокКнопок.Добавить(2, "2"); СписокКнопок.Добавить("Привет", "Привет"); //В конфигурации должен быть справочник Организации с предопределенным элементом ОсновнаяОрганизация СписокКнопок.Добавить(ПредопределенноеЗначение("Справочник.Организации.ОсновнаяОрганизация"), "Справочник"); СписокКнопок.Добавить(ТекущаяДата(), "Сегодня"); СписокКнопок.Добавить(КодВозвратаДиалога.Пропустить, "Пропустить"); Ответ = Вопрос("какой тип значения у выбранного ответа?", СписокКнопок); Если ТипЗнч(Ответ) = Тип("Число") Тогда Ответ = Ответ*2; ИначеЕсли ТипЗнч(Ответ) = Тип("Строка") Тогда Ответ = Ответ + " программист 1С!"; ИначеЕсли ТипЗнч(Ответ) = Тип("СправочникСсылка.Организации") Тогда ОткрытьЗначение(Ответ); ИначеЕсли ТипЗнч(Ответ) = Тип("Дата") Тогда Ответ = НачалоДня(Ответ); Иначе //Код ответа Пропустить, ничего не делаем КонецЕсли; Сообщить("Тип значения " + ТипЗнч(Ответ) + "; значение " + Ответ); КонецПроцедуры
Пользуйтесь асинхронными методами, задавайте пользователям коварные вопросы, и до новых встреч!