Эмуляция диалога Вопрос через 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С и рефакторинга.

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

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

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

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

Внешняя обработка для 1С, которая ищет в коде нарушения стандартов БСП и платформы (модальные вызовы, запросы в цикле, незакрытый привилегированный режим и др.) и часть из них чинит автоматически. Работает по фрагменту кода и по всей выгрузке конфигурации, с фоновым режимом через БСП и отчётом по найденному.

5 стартмани

27.08.2026    162    0    KonMa    0    

1

Перенос данных 1C Рефакторинг и качество кода Программист 1С 8.3 Бесплатно (free)

Правила обмена умеют лежать в двух местах сразу: в макете конфигурации, где их находит глобальный поиск и где их так удобно поправить, и в регистре сведений, откуда они на самом деле исполняются. Пока не проверишь, какой источник включён у плана обмена, правка макета выглядит сделанной и не делает ничего. Разбор задачи, где одно и то же значение ставки оказалось зашито в четырёх местах трёх разных слоёв: карта соответствий в модуле веб-сервиса, обработчик "ПослеЗагрузки" в правиле обмена, числовой ВЫБОР с внутренним ИНАЧЕ 0 внутри сгенерированных правил и общий модуль интеграции с внешним поставщиком чеков. Отдельно - почему у истории с вернувшимися карточками нет доказанной причины, хотя признак сузили до одного вида номенклатуры, и как тестовый прогон на пяти записях сломал сходимость итогового отчёта.

27.08.2026    270    nedomolkov.ivan    0    

1

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

Режим снимка(snapshot) убрал почти все дедлоки: с 73 в час до 7-8. Через несколько дней выяснилось, что разделяемые замки раньше сами обеспечивали сериализацию там, где код читал, решал и писал. После включения снимка эта защита пропала. Пришлось пересмотреть код: 234 места с намерением записи, 59 оставили разделяемыми, чтобы не получить взаимные блокировки. Проверка "хватит ли данных" часто стояла выше открытия транзакции - такие места линтер и ревьюер не видят. Дальше - про поддельные блокировки, опасность смены умолчания и шесть проверок.

25.08.2026    470    nedomolkov.ivan    1    

4

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

Обработка читает исходники других внешних обработок и отчётов прямо из базы и отвечает на два вопроса: с какой из них начинать смотреть и что именно в ней смотреть. На выходе HTML-отчёт: индекс качества от 0 до 100, светофор, оценка технического долга в минутах и находки с номером строки, фрагментом кода и подсветкой синтаксиса. Двадцать восемь правил: запрос в цикле, транзакция без отката, небезопасное выполнение строки, тяжёлые схемы компоновки. Считается всё на чистом BSL, без интернета, внешних компонент и отдельного сервиса рядом, поэтому анализируемый код не покидает машину. Прогон по двум десяткам обработок выстраивает их по индексу качества, худшие сверху, и сразу видно, с чего начинать разбор.

10 стартмани

20.08.2026    498    2    nedomolkov.ivan    2    

4

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

Библиотека из 6 слоев анализа, от внешней обработки до готового отчёта. Каталог из двадцати восьми правил, у каждого свой уровень и вес. И всё это крутится на чистом BSL, без Java, без git, без какого-то внешнего сервера анализа и без отправки чужого кода наружу. Разбираю, как устроен этот анализатор внешних обработок и по каким признакам он решает, что код плохой. Почему запрос в цикле получает шестьдесят баллов, как правило вообще проходит фильтр перед релизом и почему часть правил у меня помечена как сломанные. Проверял я его на себе: взял семнадцать своих обработок, которые лежат на площадке и продаются. Получил 239 замечаний и пятнадцать рабочих дней технического долга. У самой худшей индекс качества - 20 из 100 и красный светофор. А ещё расскажу, где у инструмента границы, за которые он не заходит, и про грабли - самая дорогая из них молчала.

20.08.2026    838    nedomolkov.ivan    0    

1

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

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

20.08.2026    826    n_mezentsev    10    

2

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

Передача двух модулей BSL в Cursor AI для классического сравнения без использования искусственного интеллекта (ИИ) и для проведения code review с помощью ИИ.

12.08.2026    2735    ScaNNer    0    

5

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

К нам на проект сложного обновления пришла конфигурация «1С:ERP УХ» с доработанным отчетом, построенным на базе типового «Задолженность поставщикам по срокам». После обновления целевая форма открывалась без учета переданных данных.

05.08.2026    974    1c-izh    4    

4
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 1130 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) Вообще я предупреждал: "когда Вы не планируете его использовать где-то на других платформах и Веб-клиентах"
Для отправки сообщения требуется регистрация/авторизация