При разработке алгоритмов загрузки данных, интеграций через HTTP-сервисы или выполнении регламентных заданий разработчики часто сталкиваются с необходимостью выполнить расчеты, которые уже написаны в модуле формы документа или справочника. Возникает вопрос: можно ли программно получить форму на стороне сервера и вызвать ее процедуры? Разберем архитектурные особенности клиент-серверного взаимодействия платформы 1С:Предприятие 8.3 и рассмотрим правильные варианты решения этой задачи.
В документации платформы указано, что программный объект формы может существовать как на клиенте, так и на сервере. Однако это утверждение часто интерпретируют неверно. Выясним причину такого ограничения:
ПолучитьФорму() или глобальная функция ОткрытьФорму() доступны исключительно в клиентском контексте (на тонком, толстом или веб-клиенте). На сервере не существует графической подсистемы, поэтому создать экземпляр типа УправляемаяФорма из чистого серверного кода невозможно.ЭтотОбъект или ЭтаФорма внутри модуля формы) существует исключительно в момент выполнения контекстного серверного вызова с директивой &НаСервере, инициированного клиентом. Как только серверная процедура завершается, серверный экземпляр формы уничтожается. Сервер 1С работает по модели без сохранения состояния формы (stateless).УправляемаяФорма не сериализуется. Его невозможно передать через параметры фонового задания, сохранить во временное хранилище или передать в обработчик веб-сервиса.Размещение бизнес-логики (пересчет сумм, скидок, заполнение реквизитов, подстановка цен) в процедурах модуля формы является нарушением стандартов разработки 1С. Форма должна отвечать только за отображение данных и взаимодействие с пользователем.
Рассмотрим, как правильно организовать программный код для повторного использования на сервере:
Посмотрим на пример выноса расчета в модуль объекта документа:
// В Модуле объекта документа:
Процедура РассчитатьСуммуСтроки(СтрокаТЧ) Экспорт
СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;
СтрокаТЧ.СуммаНДС = СтрокаТЧ.Сумма * (СтрокаТЧ.СтавкаНДС / 100);
КонецПроцедуры
Процедура ЗаполнитьРеквизитыПоУмолчанию() Экспорт
// Логика инициализации и пересчетов
Для Каждого Стр Из Товары Цикл
РассчитатьСуммуСтроки(Стр);
КонецЦикла;
КонецПроцедуры
Теперь этот код можно вызвать как из серверных процедур формы при интерактивной работе пользователя, так и в серверном коде загрузки данных без создания формы:
// Вызов из серверного контекста (фоновое задание, HTTP-сервис, внешняя обработка)
ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// Заполнение базовых реквизитов...
ДокументОбъект.ЗаполнитьРеквизитыПоУмолчанию();
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
Проанализируем ситуации, когда изменить исходный код модулей конфигурации нельзя:
&Вместо или &После.V83.Application, в котором методы создания форм доступны. Однако этот способ требует дополнительной клиентской лицензии, доступен только под управлением Windows и ресурсоемок.Таким образом, попытка получить форму на сервере является следствием нарушения архитектурного разделения логики. Оптимальным решением всегда остается перенос расчетных алгоритмов в модуль объекта, модуль менеджера или серверные общие модули.