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