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