Почему не отображается ПоказатьВопрос во внешней обработке заполнения объекта и как это исправить

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При переходе с устаревших редакций конфигураций (например, УТ 11.1) на современные (УТ 11.4, ERP 2.4 и выше) программисты часто сталкиваются с тем, что привычные механизмы взаимодействия с пользователем перестают работать. Одной из самых распространенных проблем является "исчезновение" окна вопроса ПоказатьВопрос во внешних обработках заполнения объектов. Рассмотрим подробно, почему это происходит и как правильно реализовать интерактивный диалог в среде Библиотеки стандартных подсистем (БСП).

Разбор причины проблемы: асинхронность и контекст выполнения

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

Когда внешняя обработка зарегистрирована с вариантом запуска "Вызов клиентского метода", происходит следующее:

  1. Система (БСП) создает временный экземпляр формы или объекта обработки.
  2. Вызывается процедура ВыполнитьКоманду.
  3. Программа доходит до строки ПоказатьВопрос. Поскольку это асинхронный метод, выполнение кода не прерывается.
  4. Процедура ВыполнитьКоманду мгновенно завершается.
  5. БСП, видя окончание выполнения процедуры, немедленно уничтожает временный контекст обработки.

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

Решение №1: Переход на вариант «Открытие формы»

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

Шаг 1. Изменение регистрации обработки

В модуле объекта обработки, в функции СведенияОВнешнейОбработке, необходимо изменить тип команды. Вместо ДополнительныеОтчетыИОбработкиКлиентскийСервер.ТипКомандыВызовКлиентскогоМетода() следует использовать ДополнительныеОтчетыИОбработкиКлиентскийСервер.ТипКомандыОткрытиеФормы().

Рассмотрим пример формирования таблицы команд:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    // ... заполнение общих параметров ...
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Заполнить объект (с вопросом)";
    НоваяКоманда.Идентификатор = "ЗаполнениеСВопросом";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентскийСервер.ТипКомандыОткрытиеФормы();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции

Шаг 2. Получение объектов назначения в форме

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // ОбъектыНазначения - это массив ссылок, переданный из БСП
    Если Параметры.Свойство("ОбъектыНазначения") Тогда
        МассивОбъектов = Параметры.ОбъектыНазначения;
        // Сохраняем массив в реквизит формы для дальнейшего использования
        Для Каждого СсылкаИзМассива Из МассивОбъектов Цикл
            ОбъектыДляОбработки.Добавить(СсылкаИзМассива);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Шаг 3. Реализация диалога в форме

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

Решение №2: Использование правильного владельца в «ОписаниеОповещения»

Если вы все же хотите использовать Вызов клиентского метода (хотя это менее стабильно для асинхронных вызовов), критически важно правильно указать "владельца" оповещения. Часто разработчики пишут ЭтаФорма, подразумевая форму обработки, которой в данный момент может не существовать в интерактивном пространстве.

Проанализируем структуру параметров выполнения команды. В процедуру ВыполнитьКоманду передается параметр ПараметрыВыполненияКоманды. В нем содержится поле ЭтаФорма (или Источник) — это форма документа, из которого запущена обработка. Именно ее нужно передать в ОписаниеОповещения.


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

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

Однако помните: даже при таком подходе есть риск, что контекст выполнения клиентского метода БСП будет закрыт быстрее, чем отрисуется окно. Поэтому вариант с открытием собственной формы обработки (Решение №1) является приоритетным.

Особенности безопасного режима

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

Если вы уверены в коде своей обработки, при регистрации в справочнике "Дополнительные отчеты и обработки" убедитесь, что:

Подведем итоги

Для корректной работы ПоказатьВопрос во внешних обработках заполнения УТ 11.4+ следует:

  1. Использовать тип команды ОткрытиеФормы.
  2. Передавать ссылки на документы через параметр ОбъектыНазначения.
  3. В самой форме реализовывать логику вопроса в процедуре ПриОткрытии или через программное нажатие кнопок.

Такой подход гарантирует, что контекст выполнения не будет потерян, и пользователь гарантированно увидит заданный вопрос.

← На главную