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

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

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

Анализ проблемы: почему нельзя получить форму на сервере?

Рассмотрим типичную ситуацию, с которой сталкиваются разработчики. Нам необходимо сформировать «Оборотно-сальдовую ведомость» программно и получить результат в виде табличного документа, находясь в серверной процедуре. Код может выглядеть примерно так:


&НаСервере
Функция СоздатьИВернуть()
    ОСВ = Отчеты.ОборотноСальдоваяВедомостьПоСчету.Создать();
    // Попытка получить форму, чтобы вызвать метод СформироватьОтчетНаСервере
    // Форма = ... ?
КонецФункции

Проанализируем ситуацию: объект типа УправляемаяФорма — это чисто визуальный объект, предназначенный для взаимодействия с пользователем. Платформа устроена таким образом, что полноценный экземпляр формы существует только на стороне Клиента. На сервере форма появляется лишь на короткое время выполнения серверного вызова, после чего её серверный экземпляр уничтожается. Метод ПолучитьФорму() на сервере не работает, так как серверу «некуда» выводить визуальный интерфейс.

Важно понимать: методы, описанные в модуле формы, физически недоступны для вызова, если сама форма не была инициализирована и открыта в рамках текущего сеанса пользователя. Попытка использовать РеквизитФормыВЗначение также не поможет, так как этот метод служит для преобразования данных текущей формы в объект, а не для «захвата» чужих форм.

Решение 1: Перенос логики в Модуль объекта

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

Рассмотрим по шагам, как это реализовать:

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

После этого наш серверный код станет простым и рабочим:


&НаСервере
Функция СформироватьОтчетПрограммно()
    // Создаем объект отчета
    ОтчетОбъект = Отчеты.ОборотноСальдоваяВедомостьПоСчету.Создать();
    
    // Теперь мы можем вызвать экспортный метод модуля ОБЪЕКТА
    ТабДок = Новый ТабличныйДокумент;
    ОтчетОбъект.СформироватьЭкспорт(ТабДок);
    
    Возврат ТабДок;
КонецФункции

Решение 2: Использование Модуля менеджера или Общих модулей

Проанализируем ситуацию, когда логика должна быть доступна вообще без создания экземпляра объекта (без вызова Создать()). Это особенно актуально для типовых конфигураций (БП 3.0, УТ 11, ERP), где используется Библиотека стандартных подсистем (БСП).

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


// Вызов метода из модуля менеджера не требует создания объекта через .Создать()
Результат = Отчеты.ОборотноСальдоваяВедомость.СформироватьОтчет(Параметры);

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

Решение 3: Программная работа с Системой компоновки данных (СКД)

Если речь идет об отчетах типа ОСВ, которые построены на базе СКД, нам вообще не нужно обращаться к методам формы. Мы можем программно исполнить схему компоновки прямо на сервере. Разберем этот процесс по шагам:

  1. Получим схему компоновки из метаданных.
  2. Загрузим настройки (пользовательские или стандартные).
  3. Инициализируем ПроцессорКомпоновкиДанных.
  4. Выведем результат в ТабличныйДокумент через ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений (или сразу в табличный документ).

Пример кода для серверного формирования без участия модулей формы:


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

Почему метод «РеквизитФормыВЗначение» в данном случае бесполезен?

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

Если вы вызываете этот метод в коде «своей» формы, он вернет объект именно этой формы. Если вы пытаетесь применить его к «чужому» объекту, созданному через Создать(), вы получите ошибку, так как у созданного объекта еще нет никакой формы, из которой можно было бы извлечь реквизиты.

Особенности работы с внешними отчетами и обработками

Если вы работаете с внешним файлом (.erf или .epf), алгоритм остается тем же, но добавляется шаг подключения. Рассмотрим пример:


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

Резюме: В архитектуре 1С 8.3 разделение ответственности между формой и объектом является критически важным. Модуль формы отвечает только за интерфейс, а модуль объекта или общие модули — за бизнес-логику. Чтобы успешно вызвать метод нового объекта на сервере, всегда выносите целевой код в модуль объекта и делайте его экспортным.

← На главную