Получить консультацию

Как задать вопрос пользователю в 1С и обработать ответ

В этой небольшой статье мы рассмотрим три способа, как в 1С показать пользователю вопрос.

В 1С Предприятие есть возможность средствами встроенного языка показать пользователю окно с вопросом и несколькими вариантами ответа, например “Вы уверены, что хотите уничтожить все документы с начала времен?” и ответы “Да, Нет, Я подумаю, Отмена”.

Метод "Вопрос"

Простейший способ показать вопрос пользователю – метод глобального контекста Вопрос. Этот метод является синхронным и к тому же модальным, и не рекомендуется к использованию, однако все еще встречается как в различных обработках и отчетах, так и в конфигурациях. Использовать его очень просто – мы указываем строку вопроса, варианты ответа, и обрабатываем выбранный пользователем вариант.

&НаКлиенте
Процедура КомандаВопрос(Команда)
	Ответ = Вопрос("Вы видите текст вопроса?", РежимДиалогаВопрос.ДаНет);
	Сообщить("Ваш ответ "+ Ответ);
КонецПроцедуры

Но, как всегда, есть нюансы. У этого метода есть несколько необязательных параметров, такие как таймаут, кнопка по умолчанию, заголовок, и кнопка таймаута (на ней будут отображаться оставшиеся секунды до таймаута). Кроме того, помимо системных режимов диалога (“Да/Нет”, “Ок/Отмена” и других), разработчик может задать свой список значений с вариантами ответа на вопрос.

&НаКлиенте
Процедура ВопросИзСписка(Команда)	
	СписокКнопок = Новый СписокЗначений;
	СписокКнопок.Добавить("Синий", "Синий");
	СписокКнопок.Добавить("Зеленый", "Зеленый");
	СписокКнопок.Добавить("Красный", "Красный");
	Ответ = Вопрос("Какой провод перерезать?", СписокКнопок, 20,,,"Красный");
	Сообщить("Вы перерезали "+ Ответ + " провод");
КонецПроцедуры

Ну и вишенка на торте. Мало кто знает, а еще меньше тех кто пользуется – вопрос можно задавать в виде форматированной строки. Попробуйте, вдруг вам понравится:)

1С вопрос пользователю
&НаКлиенте
Процедура ВопросСРаскраской(Команда)	
	СписокКнопок = Новый СписокЗначений;
	СписокКнопок.Добавить("Синий", "Синий");
	СписокКнопок.Добавить("Зеленый", "Зеленый");
	СписокКнопок.Добавить("Красный", "Красный");
	
	ФорматированнаяСтрока = Новый ФорматированнаяСтрока("Какой провод перерезать? Варианты: ",
	Новый ФорматированнаяСтрока("Синий; ", , WebЦвета.Синий),
	Новый ФорматированнаяСтрока("Зеленый; ", , WebЦвета.Зеленый),
	Новый ФорматированнаяСтрока("Красный.", , WebЦвета.Красный));
	
	Ответ = Вопрос(ФорматированнаяСтрока, СписокКнопок, 20,,,"Красный");
	Сообщить("Вы перерезали "+ Ответ + " провод");	
КонецПроцедуры

Метод ПоказатьВопрос

Так как 1С планомерно отходит от модальности и синхронных методов, которые блокируют интерфейс и/или работу программы, рассмотрим асинхронный метод ПоказатьВопрос. Помимо всех параметров, рассмотренных выше, данный метод имеет еще один параметр: ОписаниеОповещенияОЗавершении. В этот параметр передается специальный объект с типом ОписаниеОповещения. Чтобы не мучиться и не писать в ручную, можно воспользоваться меню рефакторинга и преобразовать вызов.

Кликаем правой кнопкой на методе Вопрос в коде, в контекстном меню выбираем Рефакторинг / Нерекомендуемые синхронные вызовы / Преобразовать вызов. И платформа сама разделит наш метод на ПоказатьВопрос и обработку оповещения.

1С Вопрос - рефакторинг вызова
&НаКлиенте
Процедура КомандаВопрос(Команда)
	Ответ = Неопределено;
	ПоказатьВопрос(Новый ОписаниеОповещения("КомандаВопросЗавершение", ЭтотОбъект), "Вы видите текст вопроса?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры

&НаКлиенте
Процедура КомандаВопросЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт	
	Ответ = РезультатВопроса;
	Сообщить("Ваш ответ "+ Ответ);	
КонецПроцедуры

Разумеется, получившийся код можно и нужно “причесать” – можно вынести описание оповещения в отдельную переменную, добавить дополнительные параметры, убрать ставший лишним код и т.д.

Метод ВопросАсинх

Начиная с версии 8.3.18 в платформе 1С появились новые асинхронные методы, работа с которыми во многом похожа на  asinc / await в JavaScript. Мы объявляем метод с ключевым словом Асинх, и в этом методе становится возможным использовать асинхронные методы. Перед вызовом метода ВопросАсинх мы указываем еще одно ключевое слово “Ждать”. Сам по себе метод ВопросАсинх не останавливает выполнение кода, и если не указать “Ждать”, то весь код ниже будет выполнен, и результат может быть не тот, что ожидался. По большому счету, это синтаксический сахар, призванный упростить код и облегчить жизнь разработчику.
Попробуйте убрать ключевое слово “Ждать” и сравните поведение программы 😉

&НаКлиенте
Асинх Процедура КомандаВопросАсинх(Команда)
	Ответ = Ждать ВопросАсинх("Вы заметили, что это асинхронный вопрос?", РежимДиалогаВопрос.ДаНет,,,"А ведь это асинхронный вопрос!");
	Сообщить("Ваш ответ "+ Ответ);
КонецПроцедуры

В остальном, этот метод имеет все те же параметры, что и метод “Вопрос”, который мы рассмотрели в самом начале.

Ответы

В зависимости от того, как мы задали параметр “Кнопки”, ответы могут быть самые различные. Если использовать РежимДиалогаВопрос, то у ответа тип значения будет КодВозвратаДиалога. Если же указать кнопки в виде списка значений, то в поле Ответ будет содержаться значение, привязанное к соответствующей кнопке. Типы значений в списке кнопок можно задавать самые различные. А следовательно, и логику обработки ответа можно реализовать самую разную, в зависимости от полученного значения и его типа.

&НаКлиенте
Процедура ОтветыРазныхТипов(Команда)
	СписокКнопок = Новый СписокЗначений;
	СписокКнопок.Добавить(2, "2");
	СписокКнопок.Добавить("Привет", "Привет");
	//В конфигурации должен быть справочник Организации с предопределенным элементом ОсновнаяОрганизация
	СписокКнопок.Добавить(ПредопределенноеЗначение("Справочник.Организации.ОсновнаяОрганизация"), "Справочник");
	СписокКнопок.Добавить(ТекущаяДата(), "Сегодня");
	СписокКнопок.Добавить(КодВозвратаДиалога.Пропустить, "Пропустить");
	Ответ = Вопрос("какой тип значения у выбранного ответа?", СписокКнопок);
	
	Если ТипЗнч(Ответ) = Тип("Число") Тогда
		Ответ = Ответ*2;
	ИначеЕсли ТипЗнч(Ответ) = Тип("Строка") Тогда
		Ответ = Ответ + " программист 1С!";
	ИначеЕсли ТипЗнч(Ответ) = Тип("СправочникСсылка.Организации") Тогда
		ОткрытьЗначение(Ответ);
	ИначеЕсли ТипЗнч(Ответ) = Тип("Дата") Тогда
		Ответ = НачалоДня(Ответ);			
	Иначе
		//Код ответа Пропустить, ничего не делаем
	КонецЕсли;	
	
	Сообщить("Тип значения " + ТипЗнч(Ответ) + "; значение " + Ответ);

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

Пользуйтесь асинхронными методами, задавайте пользователям коварные вопросы, и до новых встреч!

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

пятнадцать − 4 =

К НАЧАЛУ