К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как создать диалог в 1С: от вопроса пользователю до формы ввода данных

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

Диалог в 1С — это интерактивное окно, которое программа показывает пользователю, чтобы получить подтверждение действия, запросить ввод данных или предложить выбор из списка. Без диалогов не обходится ни один сценарий: удаление документа требует подтверждения, печать без сохранения — предупреждения, а подбор параметров обработки — полноценной формы ввода.

В платформе 1С:Предприятие 8.3 существует несколько механизмов диалогов: асинхронные методы ПоказатьВопрос, ПоказатьВводСтроки, ПоказатьВводЧисла, ПоказатьВводДаты, выбор из списка значений и открытие управляемых форм в режиме блокировки. Старые синхронные методы (Вопрос(), ВвестиСтроку()) считаются устаревшими и не работают в веб-клиенте, поэтому в новых разработках применяются только асинхронные варианты с описанием оповещения.

Главная сложность для начинающего разработчика — понять логику асинхронного вызова: результат диалога приходит не сразу, а в отдельную процедуру-обработчик после того, как пользователь нажал кнопку. Ниже разобраны все основные типы диалогов с готовыми примерами кода, которые можно переносить в свою конфигурацию и адаптировать под конкретную задачу.

Как устроены диалоги в 1С: асинхронная модель

Ключевая особенность современной платформы — запрет модальных вызовов. Метод ПоказатьВопрос не останавливает выполнение кода: он отображает окно и сразу возвращает управление. Когда пользователь отвечает, платформа вызывает процедуру, которую вы заранее передали в объекте ОписаниеОповещения. Туда же передаётся результат — нажатая кнопка или введённое значение.

Такой подход обязателен для веб-клиента и мобильной платформы, где модальные окна технически невозможны. Если конфигурация работает в режиме совместимости с версией 8.2, старые методы ещё могут выполняться, но при обновлении режима код перестанет компилироваться. Поэтому даже в доработках типовых решений стоит сразу использовать асинхронный синтаксис.

Типовая структура вызова всегда одинакова: сначала создаётся описание оповещения с именем процедуры-обработчика, затем вызывается метод показа диалога, а логика продолжения размещается в обработчике. Процедура-обработчик должна существовать в том же модуле и иметь строго определённый набор параметров.

Как показать вопрос пользователю с кнопками

Диалог вопроса — самый частый сценарий: подтверждение удаления, согласие на перезапись данных, выбор между вариантами действия. Для него используется метод ПоказатьВопрос, которому передаются описание оповещения, текст вопроса и набор кнопок из системного перечисления РежимДиалогаВопрос.

bsl
&НаКлиенте
Процедура УдалитьСтрокиНажатие(Команда)

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

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

&НаКлиенте
Процедура УдалитьСтрокиЗавершение(Результат, ДополнительныеПараметры) Экспорт

	Если Результат = КодВозвратаДиалога.Да Тогда
		Объект.Товары.Очистить();
	КонецЕсли;

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

Параметры метода задают поведение окна: таймаут в секундах (0 — без ограничения), кнопку по умолчанию, заголовок окна и код возврата при истечении таймаута. Кнопку по умолчанию безопаснее назначать отменяющему действию — например, «Нет» при удалении, чтобы случайное нажатие Enter не запустило необратимую операцию.

Доступные наборы кнопок фиксированы: ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить. Если нужны произвольные надписи вроде «Сохранить и закрыть», стандартный вопрос не подойдёт — потребуется собственная форма, открываемая в режиме диалога.

Как запросить ввод строки, числа или даты

Когда от пользователя нужно не «да/нет», а конкретное значение — комментарий, количество, дату отгрузки — применяются методы ПоказатьВводСтроки, ПоказатьВводЧисла и ПоказатьВводДаты. Все они работают по той же асинхронной схеме с описанием оповещения.

bsl
&НаКлиенте
Процедура УказатьПричинуНажатие(Команда)

	Оповещение = Новый ОписаниеОповещения("УказатьПричинуЗавершение", ЭтотОбъект);
	ПоказатьВводСтроки(Оповещение, "", "Укажите причину отмены заказа", 200, Ложь);

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

&НаКлиенте
Процедура УказатьПричинуЗавершение(Строка, ДополнительныеПараметры) Экспорт

	Если Строка = Неопределено Тогда
		Возврат; // пользователь нажал Отмена
	КонецЕсли;
	Объект.ПричинаОтмены = Строка;

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

Важный нюанс обработки результата: при нажатии «Отмена» в обработчик приходит Неопределено, а при подтверждении — введённое значение (в том числе пустая строка). Проверку на отмену нужно выполнять до любых действий с результатом, иначе пустой ввод затрёт существующие данные. Для чисел дополнительно задаётся максимальная длина и точность, для дат — состав даты (дата, время или дата и время).

Метод ПоказатьВводСтроки поддерживает многострочный ввод: последний параметр, равный Истина, превращает поле в многострочное. Это удобно для комментариев и причин отказа, где одной строки недостаточно.

Как предложить выбор из списка значений

Когда варианты ответа известны заранее, лучше не просить пользователя вводить текст, а показать список выбора. Для этого создаётся объект СписокЗначений, заполняется вариантами и передаётся в метод ПоказатьВыборИзСписка. Пользователь видит аккуратный список с картинками, если они заданы, и выбирает один пункт.

Результатом в обработчике будет не само значение, а элемент списка — объект с полями Значение и Представление. Это позволяет хранить в значении ссылку на объект базы, а пользователю показывать понятное наименование. При нажатии «Отмена» или Escape в обработчик приходит Неопределено.

Для выбора объекта из базы данных (контрагента, номенклатуры, договора) список значений не подходит — вместо него открывается форма выбора соответствующего справочника через ОткрытьФорму с параметром режима выбора. Форма выбора поддерживает поиск, отбор и иерархию, чего простой список не умеет.

Как открыть собственную форму как диалоговое окно

Стандартные диалоги покрывают простые случаи, но для ввода нескольких связанных параметров — например, периода, склада и флага «только остатки» — нужна собственная форма. Она создаётся в конфигураторе как общая форма или форма обработки, а открывается с блокировкой окна владельца.

bsl
&НаКлиенте
Процедура НастроитьОтборНажатие(Команда)

	Оповещение = Новый ОписаниеОповещения("НастроитьОтборЗавершение", ЭтотОбъект);
	ПараметрыФормы = Новый Структура("Склад", Объект.Склад);
	ОткрытьФорму("Обработка.ПодборТоваров.Форма.НастройкаОтбора",
		ПараметрыФормы, ЭтотОбъект, , , , Оповещение,
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

Режим БлокироватьОкноВладельца делает форму диалоговой: пользователь не может переключиться на родительское окно, пока не закроет открытое. Результат форма возвращает через метод Закрыть(Результат) — обычно это структура с введёнными параметрами. Если пользователь закрыл форму крестиком, в обработчик придёт Неопределено, и этот случай нужно обрабатывать так же, как отмену.

Передать данные внутрь открываемой формы можно через параметры (структура, указанная вторым аргументом), а получить обратно — только через результат закрытия. Пытаться обращаться к реквизитам открытой формы извне после её закрытия нельзя: в момент вызова обработчика форма уже уничтожена.

Сравнение способов диалога

ПоказатьВопрос

Подтверждения и выбор из фиксированных кнопок. Ограничение: нельзя задать произвольные надписи кнопок.

ПоказатьВводСтроки/Числа/Даты

Ввод одного простого значения. Ограничение: одно поле, нет проверки по маске и связи с данными базы.

ПоказатьВыборИзСписка

Выбор из заранее известного набора вариантов. Ограничение: список формируется кодом, без поиска и отборов.

Собственная форма с блокировкой

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

Как проверить диалог и обработать все исходы

Каждый диалог имеет минимум два исхода — подтверждение и отмену, — а с таймаутом появляется третий. Надёжный обработчик проверяет сначала отмену (Неопределено или код отмены), затем выполняет основную логику. Пропущенная проверка отмены — самая частая причина ошибок: код пытается работать со значением, которого нет.

Контрольные точки

Как проверить диалог

Нажатие кнопки подтверждения
Норма

Основная логика выполняется, результат применяется

Тревожный признак

Ничего не происходит или возникает ошибка — проверьте имя процедуры в ОписанииОповещения и ключевое слово Экспорт

Нажатие Отмены и Escape
Норма

Данные не изменяются, ошибок нет

Тревожный признак

Данные затираются пустым значением — отсутствует проверка на Неопределено

Таймаут вопроса
Норма

Выполняется безопасное действие по умолчанию

Тревожный признак

Запускается деструктивная операция — неверно выбран код возврата по таймауту

Работа в веб-клиенте
Норма

Диалог открывается и возвращает результат

Тревожный признак

Ошибка о модальных методах — в коде остались устаревшие Вопрос() или ВвестиСтроку()

Дополнительно стоит протестировать диалог под пользователем с ограниченными правами: если после подтверждения код выполняет запись данных, недостаток прав приведёт к ошибке уже внутри обработчика. Такие ситуации лучше перехватывать через Попытка...Исключение с понятным сообщением пользователю.

Типичные ошибки при создании диалогов

Типичные ошибки
01
Использование устаревших Вопрос() и ВвестиСтроку() — код не работает в веб-клиенте и ломается при смене режима совместимости.
02
Обработчик оповещения без ключевого слова Экспорт — платформа не находит процедуру, диалог завершается ошибкой.
03
Отсутствие проверки на Неопределено — при отмене ввода данные затираются пустым значением.
04
Кнопка по умолчанию на деструктивном действии — случайный Enter подтверждает удаление вместо отмены.
05
Логика после вызова ПоказатьВопрос в той же процедуре — код выполняется сразу, не дожидаясь ответа; продолжение должно быть только в обработчике.
06
Попытка прочитать реквизиты закрытой формы вместо использования результата Закрыть() — форма уже уничтожена, обращение невозможно.

Отдельная группа проблем связана с контекстом выполнения. Диалоги доступны только в клиентских процедурах (директива &НаКлиенте): попытка показать вопрос из серверного кода приведёт к ошибке компиляции. Если решение должно приниматься на сервере, архитектуру нужно перестроить — сначала спросить пользователя на клиенте, потом вызывать серверную процедуру с полученным ответом.

Если один и тот же вопрос задаётся из нескольких мест конфигурации, вынесите его в общий клиентский модуль: одна процедура показа и универсальный обработчик с передачей дополнительных параметров через ОписаниеОповещения избавят от дублирования кода и разного поведения в похожих ситуациях.
ПЗ
Практическое замечание
Итог

Что важно запомнить

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

Частые вопросы о диалогах в 1С

Можно ли задать свои надписи на кнопках вопроса?

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

Почему код после ПоказатьВопрос выполняется сразу, не дожидаясь ответа?

Это нормальное поведение асинхронной модели: метод только открывает окно и возвращает управление. Всю логику, зависящую от ответа пользователя, нужно переносить в процедуру-обработчик, указанную в ОписанииОповещения. Код, идущий в той же процедуре после вызова, выполнится до ответа.

Как показать диалог из серверной процедуры?

Никак — диалоги доступны только на клиенте. Правильная схема: на клиенте показать вопрос, в обработчике получить ответ и затем вызвать серверную процедуру, передав выбор пользователя параметром. Если архитектура требует диалога «изнутри» серверной логики, её нужно разбить на два вызова.

Что приходит в обработчик, если пользователь просто закрыл окно?

Для вопроса — код возврата, соответствующий кнопке закрытия или заданный параметром по умолчанию. Для ввода значений и форм — значение Неопределено. Поэтому обработчик всегда начинается с проверки результата, и только потом выполняется основная логика.

Как сделать, чтобы вопрос закрывался автоматически через несколько секунд?

У метода ПоказатьВопрос третий параметр — таймаут в секундах. По его истечении диалог закрывается сам, а в обработчик приходит код возврата, указанный последним параметром. Для безопасности этим кодом должна быть отмена действия, а не подтверждение.

Работают ли диалоги в мобильном клиенте и тонком клиенте?

Да, асинхронные методы ПоказатьВопрос, ПоказатьВводСтроки и открытие форм с блокировкой поддерживаются во всех клиентах: толстом, тонком, веб-клиенте и мобильной платформе. Не работают только устаревшие модальные методы Вопрос() и ВвестиСтроку(), от которых следует отказаться.