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