Как задать вопрос пользователю при вводе документа на основании в управляемых формах 1С 8.3?

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

Перевод конфигурации на управляемые формы — это не просто обновление интерфейса, а кардинальное изменение архитектуры приложения. В старых версиях платформы 1С:Предприятие (например, 8.2 с обычными формами) разработчики часто использовали интерактивные функции, такие как Вопрос() или Предупреждение(), непосредственно в модулях объектов. Например, в процедурах заполнения документов на основании (ОбработкаЗаполнения) или связанных с ними экспортных процедурах (СкопироватьТовары).

Попытка использовать аналогичный подход в управляемом приложении (даже с использованием немодальных методов типа ПоказатьВопрос) приводит к ошибке компиляции «Тип не определен (ОписаниеОповещения)». Давайте подробно разберем, почему возникает эта проблема, и рассмотрим правильные архитектурные решения для реализации интерактивного взаимодействия с пользователем при создании документов.

Выясняем причину: почему в модуле объекта нельзя задавать вопросы?

В управляемом приложении 1С 8.3 действует жесткое разделение на клиентский и серверный контексты:

  1. Модуль объекта выполняется исключительно на сервере. Все стандартные обработчики событий (включая ОбработкаЗаполнения, ПередЗаписью, ПриЗаписи) работают на стороне сервера, где физически нет и не может быть пользовательского интерфейса.
  2. Интерактивные типы данных доступны только на клиенте. Объект ОписаниеОповещения, методы ПоказатьВопрос и новые асинхронные функции вроде ВопросАсинх предназначены для работы на стороне клиента. Попытка инициализировать их на сервере вызывает ошибку платформы.

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


Решение 1. Реализация через события управляемой формы (ПриСозданииНаСервере и ПриОткрытии)

Если документ создается стандартным платформенным механизмом ввода на основании, то цепочка событий выглядит так: сначала на сервере создается объект и вызывается ОбработкаЗаполнения, а затем создается и открывается управляемая форма этого объекта. Мы можем использовать форму для организации диалога.

Проанализируем алгоритм по шагам:

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

Рассмотрим пример кода, реализующий эту схему с использованием немодальных окон и ОписаниеОповещения:


// В модуле формы управляемого документа

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

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

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

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

Решение 2. Использование современных асинхронных методов (Асинх и Ждать)

В современных версиях платформы 1С 8.3 (начиная с 8.3.18) разработчики могут использовать асинхронные вызовы, которые делают код гораздо более линейным, избавляя от необходимости плодить процедуры-оповещения. Для этого используются ключевые слова Асинх и Ждать.

Давайте посмотрим, как упростится клиентская логика при использовании этого подхода:


// В модуле формы управляемого документа

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

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


Решение 3. Реализация через команды БСП (Библиотека Стандартных Подсистем)

Если вы ведете разработку в современной типовой конфигурации 1С (например, БП, УТ, ERP, КА), то создание документов на основании чаще всего реализуется не платформенными средствами, а программно, через механизмы Библиотеки Стандартных Подсистем (БСП).

Этот подход позволяет перенести интерактивное взаимодействие в самую начальную точку — еще до того, как форма нового документа вообще начнет создаваться. Реализуется это следующим образом:

  1. В модуле менеджера вашего документа-приемника переопределяется процедура ДобавитьКомандыСозданияНаОсновании.
  2. Для команды создания на основании указывается собственный клиентский обработчик (команда) вместо стандартного открытия формы.
  3. В этой клиентской процедуре вы сразу задаете вопрос пользователю с помощью ПоказатьВопрос или ВопросАсинх.
  4. Результат ответа пользователя помещается в структуру параметров заполнения:
    
    ПараметрыЗаполнения = Новый Структура;
    ПараметрыЗаполнения.Вставить("СкопироватьТовары", ОтветПользователя);
    
  5. Полученные параметры передаются в функцию открытия формы нового документа. В модуле объекта в процедуре ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка) вы анализируете ДанныеЗаполнения, которые теперь содержат готовую структуру параметров с ответом пользователя, и выполняете соответствующий алгоритм заполнения на сервере без вызова интерактивных окон.

Решение 4. Использование вспомогательной формы-настройки

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

Реализуем данный сценарий по шагам:

  1. При нажатии кнопки «Создать на основании» (через программную команду) сначала открывается небольшая вспомогательная форма-настройка в режиме диалога (блокируя только интерфейс владельца).
  2. Пользователь в интерактивном режиме указывает нужные параметры заполнения (выбирает галочки, заполняет реквизиты).
  3. При нажатии кнопки «ОК» в этой форме настройки собирается структура параметров, и программно открывается форма целевого документа. Настройки передаются в Параметры.ЗначениеЗаполнения.
  4. В процедуре ОбработкаЗаполнения документа-приемника мы обрабатываем переданные параметры настройки и безусловно заполняем документ по указанным правилам.

Резюме

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

← На главную