Эмуляция диалога Вопрос через COM

26.03.25

Разработка - Рефакторинг и качество кода

Диалог "Вопрос" использовался очень интенсивно в старых версиях кода и также его используют в УФ довольно часто. Иногда очень неудобно использовать рефакторинг через асинхронные вызовы ПоказатьВопрос и ВопросАсинх по разным причинам. Есть ещё одно решение, как избежать больших переделок кода, когда Вы не планируете его использовать где-то на других платформах и Веб-клиентах.

Эмуляция диалога Вопрос
 

Эта задача давно назрела, т.к. пока не нашел достойного и работоспособного кода, чтобы обойти ограничение

В старых версиях 1С или в Обычном приложении, почти в каждой процедуре или функции встречается по одному или несколько диалогов Вопрос. Можно, конечно, кардинально изменить код для новой платформы, а можно для версий на стороне Windows Использовать альтернативу: Эмуляция диалога Вопрос через COM объект MSScripting.

Прилагаю пример своего решения, которое отличается только тем, что окно диалога не принадлежит родительскому окну и данный метод не поддерживает Таймер вывода окна.

// Локально выводит диалог "Вопрос", в режиме "Клиент",
//  если включен запрет Модального режима, то тогда используется скрипт MSScriptControl
//
// Параметры:
//  ТекстВопроса  - Строка - текст вопроса
//  Кнопки  - РежимДиалогаВопрос - выбор кнопок вопроса
//  Таймаут  - Число - (необяз.) интервал в секундах
//  КнопкаПоУмолчанию  - КодВозвратаДиалога - (необяз.) значение, которое будет проставлено по умолчанию
//  Заголовок  - Строка - (необяз.) заголовок сообщения
//  КнопкаТаймАута  - КодВозвратаДиалога - (необяз.) значение, которое будет проставлено по истечению времени ожидания
//  ЭтоОшибка  - Булево - (необяз.) для вывода предупреждения об ошибке
//
Функция обПоказатьВопрос(ТекстВопроса, Кнопки, Таймаут=0, КнопкаПоУмолчанию=Неопределено, Заголовок = "", КнопкаТаймАута=Неопределено, ЭтоОшибка=Ложь) Экспорт
Перем ИспользоватьСкрипт,Результат,VBScript,КодВопроса;
	Попытка
		ИспользоватьСкрипт=Метаданные.РежимИспользованияМодальности=Метаданные.СвойстваОбъектов.РежимИспользованияМодальности.НеИспользовать;
	Исключение
		ИспользоватьСкрипт=Ложь; // нет режима модальности
	КонецПопытки;
	Если ИспользоватьСкрипт Тогда
		Попытка
			// Версия начиная с 8.2
			Результат=Неопределено;
			VBScript=Новый COMОбъект("MSScriptControl.ScriptControl.1");
			VBScript.AllowUI=Истина;
			VBScript.Language="VBScript";
			Если Таймаут<>0 Тогда
				VBScript.Timeout=Таймаут*1000;
			Иначе
				VBScript.Timeout=36000000; // 10 часов
			КонецЕсли;
			КодВопроса=0; // vbOKOnly
			Если Кнопки=РежимДиалогаВопрос.ДаНет Тогда
				КодВопроса=4; // vbYesNo
			ИначеЕсли Кнопки=РежимДиалогаВопрос.ДаНетОтмена Тогда
				КодВопроса=3; // vbYesNoCancel
			ИначеЕсли Кнопки=РежимДиалогаВопрос.ОК Тогда
				КодВопроса=0; // vbYesNoCancel
			ИначеЕсли Кнопки=РежимДиалогаВопрос.ОКОтмена Тогда
				КодВопроса=1; // vbOKCancel
			ИначеЕсли Кнопки=РежимДиалогаВопрос.ПовторитьОтмена Тогда
				КодВопроса=5; // vbRetryCancel
			ИначеЕсли Кнопки=РежимДиалогаВопрос.ПрерватьПовторитьПропустить Тогда
				КодВопроса=2; // vbAbortRetryIgnore
			КонецЕсли;
			Если ЭтоОшибка Тогда
				КодВопроса=КодВопроса+16; // vbCritical
			ИначеЕсли КодВопроса<>0 Тогда
				КодВопроса=КодВопроса+32; // vbQuestion
			Иначе
				КодВопроса=КодВопроса+64; // vbInformation
			КонецЕсли;
			Если КнопкаПоУмолчанию=КодВозвратаДиалога.Да
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.ОК
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.Прервать
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.Повторить И Кнопки=РежимДиалогаВопрос.ПовторитьОтмена
				Тогда
				КодВопроса=КодВопроса+0; // vbDefaultButton1
			ИначеЕсли КнопкаПоУмолчанию=КодВозвратаДиалога.Нет
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.Отмена И Кнопки=РежимДиалогаВопрос.ОКОтмена
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.Повторить И Кнопки=РежимДиалогаВопрос.ПрерватьПовторитьПропустить
				Тогда
				КодВопроса=КодВопроса+256; // vbDefaultButton2
			ИначеЕсли КнопкаПоУмолчанию=КодВозвратаДиалога.Пропустить
				Или КнопкаПоУмолчанию=КодВозвратаДиалога.Отмена И Кнопки=РежимДиалогаВопрос.ДаНетОтмена
				Тогда
				КодВопроса=КодВопроса+512; // vbDefaultButton3
			ИначеЕсли КнопкаПоУмолчанию=КодВозвратаДиалога.Таймаут
				Тогда
				КодВопроса=КодВопроса+768; // vbDefaultButton4
			КонецЕсли;
			Попытка
				Результат=VBScript.Eval("MsgBox ("""+СтрЗаменить(ТекстВопроса,Символы.ПС,Символы.Таб)+""","+Формат(КодВопроса,"ЧДЦ=0; ЧН=0; ЧГ=")+","""+Заголовок+""")");
			Исключение
				Ошибка=ОписаниеОшибки();
				Результат=Неопределено;
			КонецПопытки;
			Если Результат=Неопределено Тогда
				Результат=?(КнопкаПоУмолчанию=Неопределено,КодВозвратаДиалога.Таймаут,КнопкаПоУмолчанию);
			ИначеЕсли Результат=1 Тогда // vbOK
				Результат=КодВозвратаДиалога.ОК;
			ИначеЕсли Результат=2 Тогда // vbCancel
				Результат=КодВозвратаДиалога.Отмена;
			ИначеЕсли Результат=3 Тогда // vbAbort
				Результат=КодВозвратаДиалога.Прервать;
			ИначеЕсли Результат=4 Тогда // vbRetry
				Результат=КодВозвратаДиалога.Повторить;
			ИначеЕсли Результат=5 Тогда // vbIgnore
				Результат=КодВозвратаДиалога.Пропустить;
			ИначеЕсли Результат=6 Тогда // vbYes
				Результат=КодВозвратаДиалога.Да;
			ИначеЕсли Результат=7 Тогда // vbNo
				Результат=КодВозвратаДиалога.Нет;
			КонецЕсли;
		Исключение
			Ошибка=ОписаниеОшибки();
		КонецПопытки;
	КонецЕсли;
	Если Результат=Неопределено Тогда
		// Совместимость со старой версией 1С
		Результат=Вычислить("Вопрос(ТекстВопроса,Кнопки,"+?(Таймаут=0,"","Таймаут")+",КнопкаПоУмолчанию,Заголовок"+?(КнопкаТаймАута<>Неопределено,",КнопкаТаймАута","")+")");
	КонецЕсли;
	Возврат Результат;
КонецФункции // обПоказатьВопрос()


Уверен, немало кому пригодится.

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

Вступайте в нашу телеграмм-группу Инфостарт

ПоказатьВопрос ВопросАсинх

См. также

HighLoad оптимизация Рефакторинг и качество кода Программист Бесплатно (free)

Рассказываем о том, как не ухудшить производительность интеграционного решения в процессе разработки и рефакторинга, когда новых фич в коробке все больше, а требования по производительности все выше. На живом примере покажем реализованный подход с использованием таких инструментов, как Docker, Redash, Vanessa Automation.

02.09.2025    1579    user1827916    1    

3

Рефакторинг и качество кода Программист Россия Бесплатно (free)

GRASP-паттерны в 1С: меньше хаоса, больше архитектуры.

28.08.2025    7862    lapinio    46    

55

Рефакторинг и качество кода Программист 1С v8.3 1С:ERP Управление предприятием 2 Россия Бесплатно (free)

Недавно наша команда завершила разработку (на несколько тысяч часов) на проекте по внедрению ERP. Заказчик на этом проекте настоял на том, чтобы вся разработка была выполнена в расширениях. Расскажу, с чем столкнулись на 24-25-ых версиях платформы и какие выводы сделали.

19.08.2025    2794    ovetgana    0    

12

Тестирование QA Рефакторинг и качество кода Программист Бесплатно (free)

За два года ручного тестирования решений на базе платформы 1С я столкнулся с огромным количеством ошибок. Глубокий анализ их причин позволил выделить ТОП-5 наиболее частых источников сбоев в 1С-разработке. Понимание этих коренных причин – первый шаг к их предотвращению. В этой статье я делюсь своими наблюдениями и предлагаю практические пути снижения рисков для каждого типа ошибок.

12.08.2025    2236    Lagger117    3    

3

Рефакторинг и качество кода Программист Бесплатно (free)

Рассказываем о практике Code Review: ее целях, преимуществах и подводных камнях. Автор делает обзор существующих инструментов, а также подробно описывает собственную разработку для анализа правок и комфортного взаимодействия по замечаниям. Инструмент Git Code Review позволяет оставлять ручные комментарии с указанием важности и автоматически проверять код с помощью BSL Language Server. С его помощью можно не только детально изучать измененный код, но и отслеживать трансформацию структуры метаданных в наглядном формате. А главное – Code Review можно проводить как в 1С:Предприятии, так и через специализированный веб-интерфейс, интегрированный с GitHub и GitLab. Статья будет интересна и тем, кто уже практикует Code Review, и тем, кто к этому только подступается.

31.07.2025    5004    salexdv    9    

36

Рефакторинг и качество кода Обновление 1С Программист 1С v8.3 Бесплатно (free)

Проблемы и их решение из реальных проектов сложного обновления 1С, когда нужно было сохранить целостность данных, ускориться и уложиться в оцененные и утвержденные сроки.

02.07.2025    4689    1c-izh    9    

13

Рефакторинг и качество кода Информационная безопасность Пароли Программист 1С v8.3 Россия Абонемент ($m)

Представьте ситуацию: вы пишете обработку для отправки email-уведомлений клиентам. Чтобы подключиться к серверу почты, вам нужны: логин, пароль, SMTP-адрес. Что делает большинство программистов?

1 стартмани

23.06.2025    3323    markbraer    8    

3

Рефакторинг и качество кода Инструментарий разработчика Программист 1С v8.3 Абонемент ($m)

Обработка позволяет анализировать структуру методов в модуле и легко составлять её структуру, канонизировать, используя стандарты 1С.

3 стартмани

20.06.2025    2050    21    MikeLetto    3    

10
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 987 26.03.25 18:54 Сейчас в теме
5. ksuman 24 01.04.25 16:14 Сейчас в теме
(1) Уже сделал, нет вариантов, если я хочу сохранить код совместимым с предыдущими версиями
2. demon_infernal 41 27.03.25 06:09 Сейчас в теме
Уверен, никому не пригодится.
Это как жонглировать раскаленными прутьями. Плюс за умение, минус за распространение.
Вы понимаете, для чего придумали отказ от модального Вопрос и переход на ВопросАсинх или ПоказатьВопрос? Чем не устраивал обычный Вопрос?
4. ksuman 24 01.04.25 16:13 Сейчас в теме
(2) Если конфигурация закрыта от изменения (нельзя включить модальный режим), а в Расширении требуется выполнять сложный код со многими интерактивными вставками, чтобы не усложнять намного процедуры разбивками по кучке малых блоков, мне понадобился такой код.
7. webester 26 07.05.25 07:23 Сейчас в теме
Иногда очень неудобно использовать рефакторинг через асинхронные вызовы ПоказатьВопрос и ВопросАсинх по разным причинам

Можете озвучить хоть какие-то из "разных причин" мешающих использовать асинхронные методы диалогов? Прям не приходит в голову ни одна ситуация в которой есть смысл городить ком объект и не использовать при этом асинхронные вызовы.

И да в большом количестве случаев если у вас кейс в котором вы все время о чем-то спрашиваете пользователя, возможно у вас ошибка в проектировании решения. Может быть есть возможность собрать настройки в одном месте и больше не дергать пользователя вопросами где он может по ошибке выбрать не то, что хотел. Исключения бывают разумеется. Но вопрос "не сделал ля я хню в очередной раз" себе надо задавать.
3. BigB 193 30.03.25 00:04 Сейчас в теме
Особенно пригодится тем, кто сидит на линуксе и маке.
Если что, то это сарказм.
6. ksuman 24 01.04.25 16:17 Сейчас в теме
(3) Вообще я предупреждал: "когда Вы не планируете его использовать где-то на других платформах и Веб-клиентах"
Для отправки сообщения требуется регистрация/авторизация