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