В современной разработке на платформе 1С:Предприятие 8.3 (особенно в режиме управляемых форм) программисты часто сталкиваются с необходимостью прервать стандартный процесс записи документа, чтобы запросить у пользователя дополнительные сведения. Поскольку использование модальных окон в актуальных конфигурациях запрещено или не рекомендуется, стандартный метод ОткрытьМодально() не подходит. Разберем детально, как реализовать ожидание ввода данных, сохраняя асинхронную модель работы интерфейса.
Когда мы вызываем метод ОткрытьФорму() внутри процедуры ПередЗаписью, платформа выполняет открытие окна и сразу же продолжает выполнение кода. Процедура завершается, и документ записывается (или закрывается), не дожидаясь, пока пользователь что-то введет в открывшемся окне. Наша задача — "поставить на паузу" процесс записи, дождаться ответа пользователя и только потом продолжить.
Этот способ является стандартным для управляемого приложения. Мы разделим процесс на два этапа: прерывание записи и повторный вызов записи после получения данных. Рассмотрим алгоритм реализации по шагам.
Шаг 1. Добавление вспомогательного реквизита.
На форму документа необходимо добавить реквизит (не путать с реквизитом самого объекта/документа) с типом Булево. Назовем его, например, ДанныеВведены. По умолчанию он будет равен Ложь.
Шаг 2. Перехват события ПередЗаписью.
Проанализируем код процедуры ПередЗаписью на клиенте. Здесь мы будем проверять наш флаг.
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
// Если данные еще не введены и это именно проведение документа
Если НЕ ДанныеВведены И ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
// Прерываем текущую попытку записи
Отказ = Истина;
// Подготавливаем оповещение, которое сработает после закрытия формы ввода
Оповещение = Новый ОписаниеОповещения("ПослеВводаДанных", ЭтотОбъект, ПараметрыЗаписи);
// Открываем вспомогательную форму
// Используем БлокироватьОкноВладельца, чтобы пользователь не мог работать с основным документом
ПараметрыФормы = Новый Структура;
ОткрытьФорму("Документ.НашДокумент.Форма.ФормаВводаДанных", ПараметрыФормы, ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецЕсли;
КонецПроцедуры
Шаг 3. Обработка результата в процедуре оповещения.
После того как пользователь заполнит данные и закроет форму, сработает процедура ПослеВводаДанных. Выясним, как правильно вернуть управление основному документу.
&НаКлиенте
Процедура ПослеВводаДанных(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
// Заполняем реквизиты документа полученными данными
Объект.НужныйРеквизит = Результат.Значение;
// Устанавливаем флаг, что проверка пройдена
ДанныеВведены = Истина;
// Повторно вызываем запись, передавая исходные параметры записи
// (это важно для сохранения режима проведения или флага "Закрыть после записи")
Записать(ДополнительныеПараметры);
// Сбрасываем флаг для последующих правок
ДанныеВведены = Ложь;
КонецЕсли;
КонецПроцедуры
Если ваша конфигурация работает на актуальной версии платформы, мы можем использовать более элегантный код в линейном стиле, используя механизм Асинх. Это позволяет избежать создания отдельных процедур для оповещения.
Разберем пример с использованием метода ОткрытьФормуАсинх():
&НаКлиенте
Асинх Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если НЕ ДанныеВведены Тогда
Отказ = Истина; // Прерываем синхронную операцию
// Ожидаем закрытия формы ввода прямо здесь
Результат = Ждать ОткрытьФормуАсинх("ОбщаяФорма.ВводЗначения");
Если Результат <> Неопределено Тогда
Объект.Данные = Результат;
ДанныеВведены = Истина;
ЭтаФорма.Записать(ПараметрыЗаписи);
ДанныеВведены = Ложь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализируем несколько критических моментов, которые часто упускают разработчики:
Записать(ПараметрыЗаписи) крайне важно передавать структуру, полученную в ПередЗаписью. В ней содержатся системные флаги, такие как ЗакрытьПослеЗаписи. Если их проигнорировать, то при нажатии кнопки "Записать и закрыть" форма документа останется висеть на экране после успешной записи.РежимОткрытияОкнаФормы.БлокироватьОкноВладельца. Это визуально связывает дочернее окно с основным документом и предотвращает случайные действия пользователя в родительской форме.ОповеститьОВыборе(Значение). Это обеспечит корректную передачу данных в параметр Результат обработчика оповещения.ПередЗаписью, вызывая Отказ = Истина, если данные отсутствуют.Если вы работаете в типовой конфигурации (УТ 11, ERP, БП 3.0), рекомендуется использовать механизмы БСП. Рассмотрим метод ОбщегоНазначенияКлиент.ПоказатьВопросПользователю или создание специализированных диалогов через подсистему "Работа с формами". Это гарантирует единообразие интерфейса и корректную работу в различных веб-клиентах. При необходимости можно воспользоваться готовой универсальной формой для ввода различных значений.
Таким образом, правильная реализация ожидания ввода данных сводится к событийной модели: прерываем стандартный поток выполнения, передаем контекст в процедуру обратного вызова и инициируем процесс заново после получения необходимых данных.