Сообщения, вопросы и окна ввода во встроенном языке 1С 8.3

· 9 мин

Содержание

Чтобы вывести диалоговое окно в 1С 8.3, на клиенте вызывают ПоказатьПредупреждение() для простого окна с кнопкой «ОК», ПоказатьВопрос() для выбора «Да/Нет» и ПоказатьВводСтроки(), ПоказатьВводЧисла(), ПоказатьВводДаты() для ввода значения. Старые модальные Предупреждение(), Вопрос(), ВводСтроки() работают только там, где в свойствах конфигурации разрешена модальность. Текст без окна выводят через Сообщить() или объект СообщениеПользователю.

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

Какой способ показа окна выбрать

Методы делятся на три поколения. Модальные пришли из 8.2 и обычных форм. Немодальные с ОписаниеОповещения появились в 8.3 вместе с режимом без модальности. Асинхронные …Асинх добавлены в платформе 8.3.18 и позволяют писать тот же диалог без отдельной процедуры-обработчика.

ЗадачаМодальный методНемодальный методАсинхронный (8.3.18+)
Окно с кнопкой «ОК»Предупреждение()ПоказатьПредупреждение()ПредупреждениеАсинх()
Вопрос с кнопкамиВопрос()ПоказатьВопрос()ВопросАсинх()
Ввод строкиВводСтроки()ПоказатьВводСтроки()ВводСтрокиАсинх()
Ввод числаВводЧисла()ПоказатьВводЧисла()ВводЧислаАсинх()
Ввод датыВводДаты()ПоказатьВводДаты()ВводДатыАсинх()
Выбор значения по типуВводЗначения()ПоказатьВводЗначения()ВводЗначенияАсинх()
Выбор из спискаСписок.ВыбратьЭлемент()Список.ПоказатьВыборЭлемента()—

Правило простое:

  • ✅ новая разработка или доработка типовой конфигурации — немодальные методы или Асинх;
  • ✅ старая конфигурация на обычных формах, где модальность включена, — можно оставить модальные;
  • ❌ серверный код — никакие окна не вызываются, только сообщения.

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

Сообщить и СообщениеПользователю: текст без отдельного окна

Сообщить() — самый короткий способ показать пользователю строку. Текст попадает в панель сообщений внизу формы, окно не открывается, код выполняется дальше без паузы.

Сообщить("Обработано документов: " + Формат(Счетчик, "ЧГ=0"));

Метод работает и на клиенте, и на сервере. Сообщения, отправленные с сервера, пользователь увидит, когда управление вернётся на клиент. Число склеивают со строкой через Формат(), иначе 1500 превратится в «1 500» с неразрывным пробелом.

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

&НаСервере
Процедура ПроверитьЗаполнениеНаСервере()
    Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Не указан контрагент";
        Сообщение.Поле = "Контрагент";
        Сообщение.ПутьКДанным = "Объект";
        Сообщение.Сообщить();
    КонецЕсли;
КонецПроцедуры

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

Ещё два способа «сказать» что-то без диалога:

  • 📌 ПоказатьОповещениеПользователя("Выгрузка завершена") — всплывающее уведомление в углу экрана, исчезает само;
  • ⏳ Состояние("Загрузка строк...", 40) — текст и полоса прогресса в строке состояния во время долгой операции.

Перед новой серией сообщений панель очищают процедурой ОчиститьСообщения().

Предупреждение: окно, которое нужно закрыть

Когда пользователь обязан увидеть текст, а не пропустить его в панели внизу, нужен диалог с кнопкой «ОК». Немодальный вариант:

&НаКлиенте
Процедура Выгрузить(Команда)
    ПоказатьПредупреждение(, "Файл сохранён в каталог выгрузки.", 10, "Выгрузка");
КонецПроцедуры

Параметры по порядку:

  1. ОписаниеОповещенияОЗавершении — что выполнить после закрытия окна. Если продолжать ничего не нужно, параметр пропускают, оставляя запятую.
  2. ТекстПредупреждения — строка или форматированная строка.
  3. Таймаут — через сколько секунд окно закроется само. 0 — не закрывать.
  4. Заголовок — текст в шапке окна.

Если после закрытия нужно что-то сделать, создают описание оповещения и выносят продолжение в отдельную экспортную процедуру:

&НаКлиенте
Процедура Закрыть(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеПредупреждения", ЭтотОбъект);
    ПоказатьПредупреждение(Оповещение, "Документ будет закрыт без записи.");
КонецПроцедуры

&НаКлиенте
Процедура ПослеПредупреждения(ДополнительныеПараметры) Экспорт
    Закрыть();
КонецПроцедуры

Модальная Предупреждение("Текст", 10, "Заголовок") останавливает выполнение до нажатия «ОК». Код короче, но в конфигурации без модальности вызов закончится исключением.

Вопрос пользователю: Да, Нет и свои кнопки

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

Немодальный ПоказатьВопрос

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

&НаКлиенте
Процедура ПослеОтветаНаВопрос(Результат, ДополнительныеПараметры) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        ПерезаполнитьНаСервере();
    КонецЕсли;
КонецПроцедуры

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

Код после ПоказатьВопрос() выполняется сразу, не дожидаясь ответа. Всё, что зависит от ответа пользователя, пишите только в процедуре-обработчике. Это главная ошибка при переходе с модального Вопрос().

Свои надписи на кнопках

Вместо перечисления передают СписокЗначений. Значение элемента вернётся в обработчик, представление станет текстом кнопки:

Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Перезаполнить всё");
Кнопки.Добавить("Цены", "Только цены");
Кнопки.Добавить(КодВозвратаДиалога.Отмена, "Отмена");

ПоказатьВопрос(Оповещение, "Что обновить в документе?", Кнопки, , "Цены");

В обработчике Результат будет равен «Все», «Цены» или КодВозвратаДиалога.Отмена. Если окно закрыли по таймауту, придёт КодВозвратаДиалога.Таймаут.

Асинхронный ВопросАсинх

С платформы 8.3.18 тот же диалог пишут линейно, без отдельной процедуры. Процедуру помечают словом Асинх, результат получают оператором Ждать:

&НаКлиенте
Асинх Процедура Удалить(Команда)
    Ответ = Ждать ВопросАсинх("Удалить выделенные строки?", РежимДиалогаВопрос.ДаНет);
    Если Ответ = КодВозвратаДиалога.Да Тогда
        УдалитьСтрокиНаСервере();
    КонецЕсли;
КонецПроцедуры

Окно при этом немодальное, поэтому код работает в веб-клиенте и в конфигурациях без модальности. Нужен режим совместимости конфигурации не ниже 8.3.18.

Окна ввода строки и числа

Когда от пользователя нужно одно значение, отдельную форму рисовать не обязательно. Платформа покажет стандартное окно с полем и кнопками «ОК» и «Отмена».

ВводСтроки и ПоказатьВводСтроки

&НаКлиенте
Процедура ЗадатьКомментарий(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеВводаКомментария", ЭтотОбъект);
    ПоказатьВводСтроки(Оповещение, Объект.Комментарий, "Комментарий к документу", 200, Истина);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаКомментария(Строка, ДополнительныеПараметры) Экспорт
    Если Строка <> Неопределено Тогда
        Объект.Комментарий = Строка;
        Модифицированность = Истина;
    КонецЕсли;
КонецПроцедуры

Параметры: начальное значение, подсказка (заголовок окна), максимальная длина (0 — без ограничения) и многострочность. При нажатии «Отмена» в обработчик приходит Неопределено, это надо проверять всегда.

Модальная форма возвращает Булево, а введённое значение кладёт в переменную, переданную первым параметром:

Код = "";
Если ВводСтроки(Код, "Введите код подтверждения", 6) Тогда
    Сообщить("Введён код: " + Код);
КонецЕсли;

ВводЧисла и ПоказатьВводЧисла

Отличие от строки — два параметра формата: длина и точность. Для суммы до 9 999 999,99 указывают длину 10 и точность 2.

&НаКлиенте
Процедура ЗадатьСкидку(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеВводаСкидки", ЭтотОбъект);
    ПоказатьВводЧисла(Оповещение, 0, "Скидка, %", 5, 2);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаСкидки(Число, ДополнительныеПараметры) Экспорт
    Если Число = Неопределено Тогда
        Возврат;
    КонецЕсли;
    Если Число < 0 Или Число > 100 Тогда
        ПоказатьПредупреждение(, "Скидка должна быть от 0 до 100%");
        Возврат;
    КонецЕсли;
    ПрименитьСкидкуНаСервере(Число);
КонецПроцедуры

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

Ввод даты, значения и выбор из списка

Дата и время

ПоказатьВводДаты(Оповещение, ТекущаяДата(), "Дата отгрузки", ЧастьДаты.Дата) откроет поле с календарём. Третий параметр управляет составом: ЧастьДаты.Дата, ЧастьДаты.Время или ЧастьДаты.ДатаВремя. Как и в других окнах, отмена возвращает Неопределено.

Значение произвольного типа

ПоказатьВводЗначения() открывает поле нужного типа, в том числе ссылочного. Для справочника пользователь получит привычную кнопку выбора:

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

Удобно в обработках, где нужно спросить один параметр перед запуском, а заводить реквизит формы ради этого не хочется.

Выбор из списка и отметка нескольких пунктов

У СписокЗначений есть свои диалоги:

  • 📋 ПоказатьВыборЭлемента(Оповещение, "Заголовок") — выбрать один пункт. В обработчик придёт ЭлементСпискаЗначений или Неопределено, значение берут из свойства .Значение;
  • ☑️ ПоказатьОтметкуЭлементов(Оповещение, "Заголовок") — поставить флажки у нескольких пунктов. После закрытия проверяют свойство Пометка у элементов списка.
&НаКлиенте
Процедура ВыбратьФормат(Команда)
    Список = Новый СписокЗначений;
    Список.Добавить("xlsx", "Excel");
    Список.Добавить("pdf", "PDF");
    Список.Добавить("mxl", "Табличный документ 1С");
    Список.ПоказатьВыборЭлемента(Новый ОписаниеОповещения("ПослеВыбораФормата", ЭтотОбъект), "Формат файла");
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораФормата(Элемент, ДополнительныеПараметры) Экспорт
    Если Элемент <> Неопределено Тогда
        СохранитьВФормате(Элемент.Значение);
    КонецЕсли;
КонецПроцедуры

Когда параметров больше двух-трёх, цепочка стандартных окон утомляет пользователя. Тогда честнее нарисовать свою форму и открыть её через ОткрытьФорму() с описанием оповещения о закрытии и режимом РежимОткрытияОкна.БлокироватьОкноВладельца. Окно-владелец заблокируется, но код будет немодальным.

Модальность, веб-клиент и сервер: где окно не откроется

За поведение отвечает свойство конфигурации «Режим использования модальности». Его меняют в конфигураторе: правой кнопкой по корню дерева конфигурации → «Свойства». Вариантов три:

ЗначениеМодальные методыЧто увидит пользователь
ИспользоватьРаботаютОбычное окно, код ждёт ответа
Использовать с предупреждениямиРаботаютОкно открывается, а проверка модулей отмечает модальные вызовы
Не использоватьВызывают исключениеОшибку вместо окна

Новые конфигурации и актуальные типовые релизы собираются в режиме «Не использовать». Поэтому код с Вопрос() или ВводСтроки(), перенесённый из старой обработки, в них падает. Решение одно — переписать вызовы на Показать… или …Асинх.

В веб-клиенте модальные окна ещё и конфликтуют с браузером: им мешают блокировщики всплывающих окон, а в мобильном клиенте модальности нет совсем. Немодальные методы работают одинаково в тонком, веб- и мобильном клиенте.

Особенности, о которых часто забывают:

  • 🖥️ на сервере окна недоступны вообще. Если решение принимается в серверной процедуре, сначала задайте вопрос на клиенте, потом передайте ответ параметром;
  • ⚙️ в фоновом задании Сообщить() не показывает текст сразу. Сообщения накапливаются, клиент забирает их через ПолучитьСообщенияПользователю() у фонового задания;
  • 🧩 во внешней обработке те же правила: режим модальности берётся из конфигурации, в которой обработку открыли.

Вопрос перед записью документа

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

&НаКлиенте
Перем ЗаписьПодтверждена;

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    Если ЗаписьПодтверждена = Истина Тогда
        ЗаписьПодтверждена = Ложь;
        Возврат;
    КонецЕсли;
    Отказ = Истина;
    Оповещение = Новый ОписаниеОповещения("ПослеВопросаОЗаписи", ЭтотОбъект, ПараметрыЗаписи);
    ПоказатьВопрос(Оповещение, "Документ уже попал в отчётность. Записать изменения?",
        РежимДиалогаВопрос.ДаНет);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопросаОЗаписи(Результат, ПараметрыЗаписи) Экспорт
    Если Результат = КодВозвратаДиалога.Да Тогда
        ЗаписьПодтверждена = Истина;
        Записать(ПараметрыЗаписи);
    КонецЕсли;
КонецПроцедуры

Параметры записи передаются третьим параметром описания оповещения. Так повторная запись пройдёт с тем же режимом: просто запись, проведение или отмена проведения.

Если окно не появляется, а код не падает, проверьте по шагам:

Окно не открылось: что проверить
Выполнено: 0 / 5

Частые вопросы

Можно ли вывести вопрос из модуля объекта или менеджера?
Нет. Модули объектов и менеджеров выполняются на сервере, где окна недоступны. Вопрос задают в модуле формы или общем клиентском модуле и передают результат на сервер.
Как сделать перенос строки в тексте окна?
Используйте Символы.ПС или многострочный литерал с символом | в начале продолжения строки. Для жирного шрифта и цвета передайте вместо строки форматированную строку Новый ФорматированнаяСтрока(...).
Как передать данные в процедуру-обработчик ответа?
Третьим параметром ОписаниеОповещения. Туда кладут структуру, например со ссылкой на строку таблицы, и в обработчике читают её из ДополнительныеПараметры.
Почему обработчик ответа не вызывается и ошибки нет?
Чаще всего процедура не экспортная, имя в ОписаниеОповещения написано с опечаткой или вторым параметром передан не тот модуль. Проблема проявляется только после закрытия окна, поэтому её легко пропустить при беглой проверке.
Окно с таймаутом закрылось само. Что придёт в обработчик?
Для вопроса — КодВозвратаДиалога.Таймаут, если не задана кнопка таймаута. Для окон ввода — Неопределено, как при отмене.