Как программно передать данные из обычной формы в управляемую форму документа в 1С

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

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

Разбор основной ошибки: Ссылка против Объекта

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


// Ошибочный подход
ЭлементыФормы.СписокДокументов.ТекущиеДанные.Согласование.Примечание = "Текст"; 

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

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

Способ 1: Использование структуры параметров (Рекомендуемый для УФ)

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

Сначала мы подготовим данные на стороне исходной (обычной) формы. Создадим структуру и заполним её необходимыми значениями:


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

// Если мы открываем существующий документ и хотим передать доп. данные
ПараметрыОткрытия.Вставить("МойСпециальныйПараметр", "Важная информация");
ПараметрыОткрытия.Вставить("Ключ", СсылкаНаДокумент); 

ОткрытьФорму("Документ.Согласование.Форма.ФормаДокумента", ПараметрыОткрытия, ЭтаФорма);

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // 1. Если данные переданы через "ЗначенияЗаполнения", 
    // 1С может заполнить их автоматически, если имена совпадают.
    
    // 2. Если нужно обработать произвольный параметр:
    Если Параметры.Свойство("МойСпециальныйПараметр") Тогда
        Объект.Примечание = Объект.Примечание + " | " + Параметры.МойСпециальныйПараметр;
    КонецЕсли;
КонецПроцедуры

Способ 2: Получение формы как объекта (Классический метод)

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


// В контексте обычной формы
мФорма = Документы.Согласование.ПолучитьФорму("ФормаДокумента");

// Теперь мы можем обращаться к реквизитам управляемой формы напрямую
// Важно: реквизит должен быть объявлен в управляемой форме как основной или программный
мФорма.ПараметрДоступа = "Значение"; 

// Также можно обратиться к самому объекту документа, который редактируется в форме
// В управляемых формах это обычно реквизит с именем "Объект"
мФорма.Объект.Примечание = "Сформировано автоматически";

мФорма.Открыть();

Выясним преимущества этого метода: он более нагляден для программистов, привыкших к работе с VBA или ранними версиями 1С 8.0/8.1. Однако стоит помнить, что прямое обращение к реквизитам формы может быть менее эффективным с точки зрения производительности при работе в тонком клиенте, так как требует большего количества серверных вызовов для инициализации объекта формы.

Способ 3: Механизм "ОбработкаЗаполнения" в модуле объекта

Если ваша задача — заполнить данные в новом документе на основании другого, наиболее «чистым» с точки зрения архитектуры 1С будет использование механизма ОбработкаЗаполнения. Это позволяет разделить логику визуального отображения (форму) и логику данных (модуль объекта).

Рассмотрим, как это реализовать. В модуле объекта Документ.Согласование пропишем процедуру:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
        Если ДанныеЗаполнения.Свойство("Примечание") Тогда
            ЭтотОбъект.Примечание = ДанныеЗаполнения.Примечание;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

При вызове ОткрытьФорму() из обычной формы, как мы рассматривали в первом способе, передача структуры в ключе ЗначенияЗаполнения автоматически инициирует выполнение этого кода в модуле объекта. Это гарантирует, что данные будут заполнены правильно, даже если документ создается не через форму, а программно в коде другой обработки.

Использование владельца формы

В некоторых случаях удобно передать ссылку на вызывающую форму как Владельца. Это позволяет открытой форме «видеть» контекст того, кто её открыл. В управляемой форме доступ к владельцу осуществляется через свойство ЭтаФорма.Владелец.

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

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

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

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

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

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

← На главную