Как вызвать процедуру модуля формы документа из веб-сервиса или серверного контекста

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

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

Анализ проблемы: почему прямой вызов невозможен

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

  1. Изоляция контекстов: Сеанс пользователя, у которого открыта форма на экране, и сеанс веб-сервиса — это две разные реальности. Даже если вы программно создадите экземпляр формы на сервере, это будет «невидимый» объект, никак не связанный с тем, что видит пользователь.
  2. Запрет интерактивности: Модули форм часто содержат вызовы методов Сообщить(), Предупреждение() или ОткрытьФорму(). В сеансе веб-сервиса любые интерактивные действия запрещены и вызывают аварийное завершение работы (Runtime Error).
  3. Ресурсоемкость: Форма — это тяжеловесный объект метаданных. Создавать её на сервере только ради вызова одной функции — крайне неэффективное использование ресурсов сервера «1С:Предприятие».

Решение 1: Вынос логики в Общий модуль (Best Practice)

Наиболее правильным и архитектурно верным решением является вынос общей бизнес-логики в Общий модуль. Это позволяет переиспользовать один и тот же код и в форме документа, и в веб-сервисе, и в регламентных заданиях.

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

1. Создадим (или используем существующий) общий модуль, например, РаботаСРассылкамиСервер. Установим у него свойства «Сервер» и «Вызов сервера».

2. Перенесем процедуру ВыслатьПочту из модуля формы в этот общий модуль и сделаем её экспортной:


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

3. Теперь и в модуле формы, и в веб-сервисе мы будем просто обращаться к этой процедуре:


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

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

Решение 2: Использование модуля менеджера или модуля объекта

Если логика тесно связана с данными конкретного документа, её можно разместить в модуле менеджера или модуле объекта. Разберем разницу:

Модуль менеджера: Идеален для методов, которым не нужно состояние конкретного экземпляра объекта (например, печать по ссылке или массовая обработка данных). Обращение к нему происходит быстро, так как не требует загрузки всего объекта из базы.


// В модуле менеджера документа
Процедура ВыслатьПочтуМенеджер(СсылкаНаДокумент) Экспорт
    // Реализация логики
КонецПроцедуры

// Вызов из веб-сервиса
Документы.ВажныйДокумент.ВыслатьПочтуМенеджер(НужнаяСсылка);

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


// В модуле объекта
Процедура ВыслатьПочтуОбъект() Экспорт
    // Работаем напрямую с реквизитами: ЭтотОбъект.Сумма, ЭтотОбъект.Дата
КонецПроцедуры

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

Решение 3: Оповещение открытой формы (пассивный метод)

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

  1. Веб-сервис записывает данные или устанавливает признак (например, в дополнительный реквизит документа или в регистр сведений).
  2. В форме документа при открытии подключается обработчик ожидания:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ПодключитьОбработчикОжидания("ПроверитьОбновленияФормы", 10); // Проверка каждые 10 секунд
КонецПроцедуры

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

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

Резюме и рекомендации

Подведем итог нашему анализу. Попытка получить фрмДок = обДок.ПолучитьФорму(); фрмДок.ВыслатьПочту(); в веб-сервисе — это путь, ведущий к нестабильной работе системы.

Правильный алгоритм действий:

Такой подход соответствует стандартам разработки фирмы «1С» и обеспечивает высокую производительность и надежность вашей системы при интеграции с внешними сервисами.

← На главную