Разработка и Конфигурация · 13 мин
Как создать диалог в 1С: от вопроса пользователю до формы ввода данных
Практическое руководство по созданию диалогов в 1С: вопрос пользователю, ввод строки и числа, выбор значения, модальные и немодальные окна с примерами кода.
Диалог в 1С — это интерактивное окно, которое программа показывает пользователю, чтобы получить подтверждение действия, запросить ввод данных или предложить выбор из списка. Без диалогов не обходится ни один сценарий: удаление документа требует подтверждения, печать без сохранения — предупреждения, а подбор параметров обработки — полноценной формы ввода.
В платформе 1С:Предприятие 8.3 существует несколько механизмов диалогов: асинхронные методы ПоказатьВопрос, ПоказатьВводСтроки, ПоказатьВводЧисла, ПоказатьВводДаты, выбор из списка значений и открытие управляемых форм в режиме блокировки. Старые синхронные методы (Вопрос(), ВвестиСтроку()) считаются устаревшими и не работают в веб-клиенте, поэтому в новых разработках применяются только асинхронные варианты с описанием оповещения.
Главная сложность для начинающего разработчика — понять логику асинхронного вызова: результат диалога приходит не сразу, а в отдельную процедуру-обработчик после того, как пользователь нажал кнопку. Ниже разобраны все основные типы диалогов с готовыми примерами кода, которые можно переносить в свою конфигурацию и адаптировать под конкретную задачу.
Как устроены диалоги в 1С: асинхронная модель
Ключевая особенность современной платформы — запрет модальных вызовов. Метод ПоказатьВопрос не останавливает выполнение кода: он отображает окно и сразу возвращает управление. Когда пользователь отвечает, платформа вызывает процедуру, которую вы заранее передали в объекте ОписаниеОповещения. Туда же передаётся результат — нажатая кнопка или введённое значение.
Такой подход обязателен для веб-клиента и мобильной платформы, где модальные окна технически невозможны. Если конфигурация работает в режиме совместимости с версией 8.2, старые методы ещё могут выполняться, но при обновлении режима код перестанет компилироваться. Поэтому даже в доработках типовых решений стоит сразу использовать асинхронный синтаксис.
Типовая структура вызова всегда одинакова: сначала создаётся описание оповещения с именем процедуры-обработчика, затем вызывается метод показа диалога, а логика продолжения размещается в обработчике. Процедура-обработчик должна существовать в том же модуле и иметь строго определённый набор параметров.
Как показать вопрос пользователю с кнопками
Диалог вопроса — самый частый сценарий: подтверждение удаления, согласие на перезапись данных, выбор между вариантами действия. Для него используется метод ПоказатьВопрос, которому передаются описание оповещения, текст вопроса и набор кнопок из системного перечисления РежимДиалогаВопрос.
&НаКлиенте
Процедура УдалитьСтрокиНажатие(Команда)
Оповещение = Новый ОписаниеОповещения("УдалитьСтрокиЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение,
"Удалить все строки табличной части?",
РежимДиалогаВопрос.ДаНет,
20,
КодВозвратаДиалога.Нет,
"Подтверждение действия",
КодВозвратаДиалога.Нет);
КонецПроцедуры
&НаКлиенте
Процедура УдалитьСтрокиЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
Объект.Товары.Очистить();
КонецЕсли;
КонецПроцедурыПараметры метода задают поведение окна: таймаут в секундах (0 — без ограничения), кнопку по умолчанию, заголовок окна и код возврата при истечении таймаута. Кнопку по умолчанию безопаснее назначать отменяющему действию — например, «Нет» при удалении, чтобы случайное нажатие Enter не запустило необратимую операцию.
Доступные наборы кнопок фиксированы: ДаНет, ДаНетОтмена, ОК, ОКОтмена, ПовторитьОтмена, ПрерватьПовторитьПропустить. Если нужны произвольные надписи вроде «Сохранить и закрыть», стандартный вопрос не подойдёт — потребуется собственная форма, открываемая в режиме диалога.
Как запросить ввод строки, числа или даты
Когда от пользователя нужно не «да/нет», а конкретное значение — комментарий, количество, дату отгрузки — применяются методы ПоказатьВводСтроки, ПоказатьВводЧисла и ПоказатьВводДаты. Все они работают по той же асинхронной схеме с описанием оповещения.
&НаКлиенте
Процедура УказатьПричинуНажатие(Команда)
Оповещение = Новый ОписаниеОповещения("УказатьПричинуЗавершение", ЭтотОбъект);
ПоказатьВводСтроки(Оповещение, "", "Укажите причину отмены заказа", 200, Ложь);
КонецПроцедуры
&НаКлиенте
Процедура УказатьПричинуЗавершение(Строка, ДополнительныеПараметры) Экспорт
Если Строка = Неопределено Тогда
Возврат; // пользователь нажал Отмена
КонецЕсли;
Объект.ПричинаОтмены = Строка;
КонецПроцедурыВажный нюанс обработки результата: при нажатии «Отмена» в обработчик приходит Неопределено, а при подтверждении — введённое значение (в том числе пустая строка). Проверку на отмену нужно выполнять до любых действий с результатом, иначе пустой ввод затрёт существующие данные. Для чисел дополнительно задаётся максимальная длина и точность, для дат — состав даты (дата, время или дата и время).
Метод ПоказатьВводСтроки поддерживает многострочный ввод: последний параметр, равный Истина, превращает поле в многострочное. Это удобно для комментариев и причин отказа, где одной строки недостаточно.
Как предложить выбор из списка значений
Когда варианты ответа известны заранее, лучше не просить пользователя вводить текст, а показать список выбора. Для этого создаётся объект СписокЗначений, заполняется вариантами и передаётся в метод ПоказатьВыборИзСписка. Пользователь видит аккуратный список с картинками, если они заданы, и выбирает один пункт.
Результатом в обработчике будет не само значение, а элемент списка — объект с полями Значение и Представление. Это позволяет хранить в значении ссылку на объект базы, а пользователю показывать понятное наименование. При нажатии «Отмена» или Escape в обработчик приходит Неопределено.
Для выбора объекта из базы данных (контрагента, номенклатуры, договора) список значений не подходит — вместо него открывается форма выбора соответствующего справочника через ОткрытьФорму с параметром режима выбора. Форма выбора поддерживает поиск, отбор и иерархию, чего простой список не умеет.
Как открыть собственную форму как диалоговое окно
Стандартные диалоги покрывают простые случаи, но для ввода нескольких связанных параметров — например, периода, склада и флага «только остатки» — нужна собственная форма. Она создаётся в конфигураторе как общая форма или форма обработки, а открывается с блокировкой окна владельца.
&НаКлиенте
Процедура НастроитьОтборНажатие(Команда)
Оповещение = Новый ОписаниеОповещения("НастроитьОтборЗавершение", ЭтотОбъект);
ПараметрыФормы = Новый Структура("Склад", Объект.Склад);
ОткрытьФорму("Обработка.ПодборТоваров.Форма.НастройкаОтбора",
ПараметрыФормы, ЭтотОбъект, , , , Оповещение,
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедурыРежим БлокироватьОкноВладельца делает форму диалоговой: пользователь не может переключиться на родительское окно, пока не закроет открытое. Результат форма возвращает через метод Закрыть(Результат) — обычно это структура с введёнными параметрами. Если пользователь закрыл форму крестиком, в обработчик придёт Неопределено, и этот случай нужно обрабатывать так же, как отмену.
Передать данные внутрь открываемой формы можно через параметры (структура, указанная вторым аргументом), а получить обратно — только через результат закрытия. Пытаться обращаться к реквизитам открытой формы извне после её закрытия нельзя: в момент вызова обработчика форма уже уничтожена.
Сравнение способов диалога
Подтверждения и выбор из фиксированных кнопок. Ограничение: нельзя задать произвольные надписи кнопок.
Ввод одного простого значения. Ограничение: одно поле, нет проверки по маске и связи с данными базы.
Выбор из заранее известного набора вариантов. Ограничение: список формируется кодом, без поиска и отборов.
Сложный ввод нескольких параметров, произвольные кнопки, проверки. Ограничение: требует создания формы и больше кода.
Как проверить диалог и обработать все исходы
Каждый диалог имеет минимум два исхода — подтверждение и отмену, — а с таймаутом появляется третий. Надёжный обработчик проверяет сначала отмену (Неопределено или код отмены), затем выполняет основную логику. Пропущенная проверка отмены — самая частая причина ошибок: код пытается работать со значением, которого нет.
Как проверить диалог
Основная логика выполняется, результат применяется
Ничего не происходит или возникает ошибка — проверьте имя процедуры в ОписанииОповещения и ключевое слово Экспорт
Данные не изменяются, ошибок нет
Данные затираются пустым значением — отсутствует проверка на Неопределено
Выполняется безопасное действие по умолчанию
Запускается деструктивная операция — неверно выбран код возврата по таймауту
Диалог открывается и возвращает результат
Ошибка о модальных методах — в коде остались устаревшие Вопрос() или ВвестиСтроку()
Дополнительно стоит протестировать диалог под пользователем с ограниченными правами: если после подтверждения код выполняет запись данных, недостаток прав приведёт к ошибке уже внутри обработчика. Такие ситуации лучше перехватывать через Попытка...Исключение с понятным сообщением пользователю.
Типичные ошибки при создании диалогов
Отдельная группа проблем связана с контекстом выполнения. Диалоги доступны только в клиентских процедурах (директива &НаКлиенте): попытка показать вопрос из серверного кода приведёт к ошибке компиляции. Если решение должно приниматься на сервере, архитектуру нужно перестроить — сначала спросить пользователя на клиенте, потом вызывать серверную процедуру с полученным ответом.
Если один и тот же вопрос задаётся из нескольких мест конфигурации, вынесите его в общий клиентский модуль: одна процедура показа и универсальный обработчик с передачей дополнительных параметров через ОписаниеОповещения избавят от дублирования кода и разного поведения в похожих ситуациях.
Что важно запомнить
Все диалоги в современной 1С асинхронны: показ и обработка результата разнесены в разные процедуры, связанные ОписаниемОповещения. Для подтверждений — ПоказатьВопрос, для ввода — ПоказатьВводСтроки/Числа/Даты, для сложных сценариев — собственная форма с блокировкой окна владельца. Всегда обрабатывайте отмену через проверку на Неопределено и назначайте кнопкой по умолчанию безопасное действие.
Частые вопросы о диалогах в 1С
Можно ли задать свои надписи на кнопках вопроса?
Стандартный метод ПоказатьВопрос поддерживает только фиксированные наборы кнопок из перечисления РежимДиалогаВопрос. Для произвольных надписей создаётся собственная форма с нужными кнопками, которая открывается в режиме БлокироватьОкноВладельца и возвращает выбранный вариант через Закрыть().
Почему код после ПоказатьВопрос выполняется сразу, не дожидаясь ответа?
Это нормальное поведение асинхронной модели: метод только открывает окно и возвращает управление. Всю логику, зависящую от ответа пользователя, нужно переносить в процедуру-обработчик, указанную в ОписанииОповещения. Код, идущий в той же процедуре после вызова, выполнится до ответа.
Как показать диалог из серверной процедуры?
Никак — диалоги доступны только на клиенте. Правильная схема: на клиенте показать вопрос, в обработчике получить ответ и затем вызвать серверную процедуру, передав выбор пользователя параметром. Если архитектура требует диалога «изнутри» серверной логики, её нужно разбить на два вызова.
Что приходит в обработчик, если пользователь просто закрыл окно?
Для вопроса — код возврата, соответствующий кнопке закрытия или заданный параметром по умолчанию. Для ввода значений и форм — значение Неопределено. Поэтому обработчик всегда начинается с проверки результата, и только потом выполняется основная логика.
Как сделать, чтобы вопрос закрывался автоматически через несколько секунд?
У метода ПоказатьВопрос третий параметр — таймаут в секундах. По его истечении диалог закрывается сам, а в обработчик приходит код возврата, указанный последним параметром. Для безопасности этим кодом должна быть отмена действия, а не подтверждение.
Работают ли диалоги в мобильном клиенте и тонком клиенте?
Да, асинхронные методы ПоказатьВопрос, ПоказатьВводСтроки и открытие форм с блокировкой поддерживаются во всех клиентах: толстом, тонком, веб-клиенте и мобильной платформе. Не работают только устаревшие модальные методы Вопрос() и ВвестиСтроку(), от которых следует отказаться.