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

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

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

Анализ проблемы: почему стандартное ОткрытьФорму не всегда подходит

Разберем классическую ошибку начинающих разработчиков. Если мы просто вызовем ОткрытьФорму, система создаст совершенно новый экземпляр объекта и его формы. Даже если до этого мы создали объект через Обработки.ИмяОбработки.Создать() и заполнили его реквизиты на сервере, метод ОткрытьФорму никак не свяжет наш уже «готовый» объект с создаваемым окном интерфейса. Нам же требуется передать состояние конкретного объекта в контекст формы. Проанализируем основные способы достижения этой цели.

Способ 1. Использование метода ПолучитьФорму и ручное заполнение

Этот способ считается наиболее простым и наглядным. Мы создаем форму, обращаемся к её основному реквизиту (как правило, это Объект) и заполняем его данными. Посмотрим на пример кода, который решает задачу автора темы:


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

Важно помнить, что метод ПолучитьФорму сразу инициирует событие ПриСозданииНаСервере в самой форме. Если в этом обработчике заложена логика, которая принудительно очищает данные или заполняет их значениями по умолчанию, ваши программные изменения могут быть перекрыты. Поэтому всегда анализируйте код целевой формы перед использованием этого метода.

Способ 2. Применение метода КопироватьДанныеФормы

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

Рассмотрим алгоритм действий:

  1. Создаем экземпляр объекта на сервере.
  2. Вызываем его экспортные методы для заполнения.
  3. На клиенте получаем форму обработки.
  4. Используем КопироватьДанныеФормы для связи объекта и формы.

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

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

Способ 3. Передача через временное хранилище (для внешних обработок)

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

Проанализируем ситуацию с внешним файлом:


&НаСервере
Функция ПолучитьОбъектВнешнейОбработки(ПутьКФайлу)
    ИмяОбработки = ВнешниеОбработки.Подключить(ПутьКФайлу, , Ложь);
    Объект = ВнешниеОбработки.Создать(ИмяОбработки);
    
    // Выполняем логику заполнения
    Объект.ВыполнитьДействие();
    
    Возврат Объект;
КонецФункции

После получения объекта на клиенте мы точно так же используем КопироватьДанныеФормы. Главное преимущество здесь в том, что мы разделяем логику подготовки данных и логику визуализации.

Особенности работы с контекстом исполнения

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

Использование параметров формы «КлючНазначения»

Если ваша задача подразумевает одновременное открытие нескольких окон одной и той же обработки с разными данными, обязательно используйте параметр КлючНазначения. Рассмотрим, как это работает: по умолчанию 1С пытается найти уже открытое окно этой обработки. Если вы укажете уникальный ключ, система создаст новое независимое окно. Это критично, когда вы программно формируете данные для разных организаций или периодов одновременно.


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

Резюме

Мы проанализировали несколько способов решения задачи. Наиболее корректным и стабильным является сочетание методов ПолучитьФорму и КопироватьДанныеФормы. Это позволяет подготовить данные в объекте на сервере, используя все доступные методы модуля объекта, и бесшовно передать их в интерфейс пользователя, даже если у нас нет доступа к редактированию самой формы или её модулей. Помните о разделении контекста «Клиент-Сервер» и всегда проверяйте наличие экспортных методов в целевом объекте.

← На главную