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