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

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

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

Как сделать диалог в 1С: ВопросПользователю, ВвестиЗначение, Оповещение и собственные формы. Примеры кода, блокирующие вызовы, типичные ошибки и FAQ.

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

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

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

Какой тип диалога выбрать под задачу

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

ЗадачаМеханизмЧто возвращает
Подтверждение действия (Да/Нет)ПоказатьВопросКодВозвратаДиалога
Ввод строки, числа, датыПоказатьВводСтроки, ПоказатьВводЧисла, ПоказатьВводДатыВведённое значение или Неопределено
Ввод значения произвольного типаПоказатьВводЗначенияЗначение или Неопределено
Выбор из списка значенийСписокЗначений.ВыбратьЭлементЭлемент списка
Выбор файлаДиалогВыбораФайла + НачатьПомещениеФайла / диалог.ПоказатьИмя файла
Сложный ввод нескольких полейСобственная формаПроизвольный результат через Закрыть()
Маршрут решения

Как выбрать действие

Нужно только подтверждение или ввод одного простого значенияИспользуйте стандартные методы ПоказатьВопрос / ПоказатьВводЗначения — форму создавать не нужно
Нужно выбрать элемент справочника или документаОткройте стандартную форму выбора через ОткрытьФорму с РежимВыбора = Истина
Нужно несколько полей, флажки и своя логика проверкиСоздайте собственную общую форму и открывайте её как диалог

Простой вопрос пользователю через ПоказатьВопрос

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

Результат приходит в отдельную процедуру, которую вы указываете в ОписаниеОповещения. Внутри неё сравнивайте результат с перечислением КодВозвратаДиалога. Учитывайте, что при истечении таймаута возвращается значение Таймаут, а не кнопка по умолчанию, — это частая причина логических ошибок.

&НаКлиенте

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

Оповещение = Новый ОписаниеОповещения("УдалитьСтрокиЗавершение", ЭтотОбъект);

ПоказатьВопрос(Оповещение,

"Удалить выбранные строки без возможности восстановления?",

РежимДиалогаВопрос.ДаНет,

20, // таймаут в секундах

КодВозвратаДиалога.Нет);

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

&НаКлиенте

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

Если Результат = КодВозвратаДиалога.Да Тогда

УдалитьВыбранныеСтроки();

КонецЕсли;

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

Третьим параметром можно передать произвольные дополнительные параметры в ОписаниеОповещения — например, ссылку на документ или массив строк. Это избавляет от хранения контекста в реквизитах формы.

Ввод значения: строка, число, дата и произвольный тип

Для ввода одного значения есть семейство методов: ПоказатьВводСтроки, ПоказатьВводЧисла, ПоказатьВводДаты и универсальный ПоказатьВводЗначения. Последний удобен тем, что принимает описание типов — можно попросить пользователя ввести, например, ссылку на справочник, и платформа сама покажет поле с кнопкой выбора.

Если пользователь нажал «Отмена», в обработчик приходит Неопределено. Всегда проверяйте этот случай, иначе дальнейший код запишет пустое значение или упадёт с ошибкой приведения типов.

&НаКлиенте

Процедура ВвестиКоличество(Команда)

Оповещение = Новый ОписаниеОповещения("ВвестиКоличествоЗавершение", ЭтотОбъект);

ПоказатьВводЧисла(Оповещение, 1, "Введите количество", 15, 3);

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

&НаКлиенте

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

Если Число = Неопределено Тогда

Возврат; // пользователь отменил ввод

КонецЕсли;

Если Число <= 0 Тогда

ПоказатьПредупреждение(, "Количество должно быть больше нуля");

Возврат;

КонецЕсли;

УстановитьКоличество(Число);

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

Для выбора из заранее подготовленного набора вариантов используйте СписокЗначений и его метод ПоказатьВыборЭлемента. Это дешевле, чем создавать собственную форму выбора, и выглядит привычно для пользователя.

Валидацию введённого значения делайте в обработчике оповещения, а не до показа диалога. Если значение не прошло проверку, можно сразу показать тот же диалог ввода повторно с поясняющим текстом — это удобнее, чем молча игнорировать ошибку.
ПЗ
Практическое замечание

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

Когда нужно собрать сразу несколько полей, показать таблицу или реализовать нестандартную логику, создают собственную форму. Обычно это общая форма (в ветке «Общие формы» конфигуратора) либо форма обработки. Форма открывается методом ОткрытьФорму с указанием владельца, параметров и обработчика закрытия.

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

&НаКлиенте

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

ПараметрыФормы = Новый Структура("ТекущийПериод", ПериодОтчета);

Оповещение = Новый ОписаниеОповещения("НастроитьОтборЗавершение", ЭтотОбъект);

ОткрытьФорму("ОбщаяФорма.НастройкаОтбора",

ПараметрыФормы,

ЭтотОбъект,

,,,

Оповещение,

РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

&НаКлиенте

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

Если Результат = Неопределено Тогда

Возврат;

КонецЕсли;

ПрименитьНастройки(Результат);

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

На стороне формы диалога в обработчике ПриСозданииНаСервере прочитайте переданные параметры из объекта Параметры и заполните реквизиты формы. Кнопка «ОК» должна собрать значения в структуру и вызвать Закрыть(Структура), кнопка «Отмена» — просто Закрыть() без параметра.

Выбор элемента справочника или документа

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

&НаКлиенте

Процедура ВыбратьКонтрагента(Команда)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("РежимВыбора", Истина);

ПараметрыФормы.Вставить("Отбор", Новый Структура("ПометкаУдаления", Ложь));

Оповещение = Новый ОписаниеОповещения("ВыбратьКонтрагентаЗавершение", ЭтотОбъект);

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора",

ПараметрыФормы, ЭтотОбъект, , , , Оповещение);

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

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

Почему модальные вызовы не работают и что с этим делать

В старом коде встречаются синхронные вызовы: Если Вопрос("Продолжить?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да Тогда .... В конфигурациях со свойством «Режим использования модальности» в значении «Не использовать» такой код вызовет ошибку. Веб-клиент в принципе не поддерживает модальные окна на уровне браузера.

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

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

Типичные ошибки
01
Код после ПоказатьВопрос выполняется сразу, а не после ответа — действия нужно переносить в обработчик оповещения
02
Отсутствует проверка результата на Неопределено — при отмене ввода логика работает с пустым значением
03
Использование синхронного Вопрос() при запрещённой модальности — ошибка выполнения в тонком и веб-клиенте
04
Форма диалога открыта без БлокироватьОкноВладельца — пользователь меняет данные в родительском окне параллельно с диалогом
05
Не обработан таймаут в ПоказатьВопрос — результат Таймаут трактуется как отказ или как согласие

Проверка результата и ограничения

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

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

Как проверить результат

Открытие диалога в тонком клиенте
Норма

Окно появляется, ответ возвращается в обработчик, дальнейшая логика выполняется

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

Ошибка о модальности или обработчик не вызывается

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

Диалог отображается внутри страницы, кнопки доступны, результат корректен

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

Окно не открывается или вылетает ошибка выполнения

Нажатие Отмена / крестика
Норма

В обработчик приходит Неопределено, никакие данные не меняются

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

Записывается пустое значение или возникает исключение

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

По истечении времени выполняется безопасная ветка логики

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

Таймаут трактуется как согласие на опасное действие

Учитывайте и ограничения платформы: на сервере диалоги показать нельзя — все методы показа доступны только в клиентском контексте. Если решение зависит от ответа пользователя, а логика находится в серверной процедуре, сначала спросите пользователя на клиенте и только потом вызывайте серверный метод с полученным параметром.

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

Итог

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

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

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

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

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

Чем ПоказатьВопрос отличается от устаревшего Вопрос()?

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

Как вернуть из формы-диалога несколько значений?

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

Как задать кнопку по умолчанию и таймаут в вопросе?

В ПоказатьВопрос четвёртым параметром передаётся таймаут в секундах (0 — без ограничения), пятым — кнопка по умолчанию из КодВозвратаДиалога. По истечении таймаута в обработчик приходит специальное значение Таймаут, а не кнопка по умолчанию — обработайте этот случай отдельно.

Диалог работает в толстом клиенте, но не в тонком. В чём причина?

Чаще всего используется синхронный модальный вызов (Вопрос, ВвестиЗначение, ОткрытьФормуМодально) при выключенном режиме модальности в свойствах конфигурации. Замените вызовы на асинхронные аналоги с описанием оповещения. Также проверьте директивы компиляции: код с диалогами должен находиться в клиентских процедурах (&НаКлиенте).

Как показать диалог выбора файла?

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