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

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

При проектировании интеграций, разработке веб-сервисов (API) или создании регламентных заданий в среде 1С:Предприятие 8 разработчики часто сталкиваются с серьезной архитектурной проблемой. Необходимо программно создать и заполнить документ, но вся ключевая бизнес-логика расчетов, заполнения связанных реквизитов и табличных частей «зашита» разработчиками конфигурации в модуле управляемой формы.

Попытка вызвать эти методы напрямую из фонового задания или веб-сервиса заканчивается неудачей. Поскольку фоновые процессы выполняются исключительно на сервере вне контекста клиентского сеанса, получить форму привычным методом ПолучитьФорму() или использовать ключевое слово ЭтаФорма невозможно. Рассмотрим, почему возникает это ограничение и какие существуют практические способы решения этой задачи без полного дублирования кода.

Почему возникает эта проблема? Архитектурные ограничения платформы

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

Когда вы пытаетесь запустить код на сервере (в веб-сервисе или регламентном задании), у платформы физически отсутствует клиентское окружение. Из-за этого вызов методов формы извне не предусмотрен архитектурой. Более того, передача формы в качестве параметра в процедуры общих модулей без контекста (или попытка передать ее с клиента на сервер вне контекстного вызова) приводит к ошибке сериализации: «Отсутствует отображение типа».

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

Решение 1. Имитация формы через «Структуру-обманку» (Duck Typing)

Большинство расчетных процедур в общих модулях типовых конфигураций, принимающих форму в качестве параметра, на самом деле используют лишь несколько ее свойств: реквизит Объект (содержащий данные документа), коллекцию Элементы или некоторые специфические переменные формы.

Во встроенном языке 1С применяется динамическая типизация (так называемая «уткотипизация» или duck typing). Это означает, что если объект ведет себя как форма (имеет те же свойства), то система примет его. Мы можем создать на сервере обычную структуру, которая будет полностью имитировать свойства управляемой формы.

Рассмотрим пример программного заполнения данных, когда процедура общего модуля требует передачи формы:


// Создаем структуру, имитирующую форму документа
ПараметрыИмитацииФормы = Новый Структура;

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

ПараметрыИмитацииФормы.Вставить("Объект", НовыйДокумент);

// Если вызываемый метод обращается к элементам формы, имитируем их структуру
ЭлементыИмитации = Новый Структура;
ЭлементыИмитации.Вставить("Показатели", Новый Структура("ТекущиеДанные", Неопределено));
ПараметрыИмитацииФормы.Вставить("Элементы", ЭлементыИмитации);

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

// Вызываем процедуру типового общего модуля, передавая нашу структуру вместо реальной формы
РасчетЗарплатыРасширенныйФормы.ЗаполнитьПоказателиДокумента(ПараметрыИмитацииФормы);

// После выполнения расчетов переносим данные в документ и записываем его
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);

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

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

Решение 2. Отложенный расчет на клиенте при открытии (Метод автора темы)

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

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

Разберем реализацию этого алгоритма:

Шаг 1. В фоновом режиме создаем документ и взводим признак того, что он требует заполнения. Для этого можно использовать дополнительный реквизит, признак проведения или анализировать пустоту табличных частей.

Шаг 2. В расширении конфигурации переопределяем процедуру формы документа ПриОткрытии:


&НаКлиенте
Процедура Расширение_ПриОткрытииПосле(Отказ)
    
    // Проверяем, требует ли документ интерактивного заполнения
    Если Не Объект.Проведен И ТабличныеЧастиПусты() Тогда
        
        РежимДиалога = РежимДиалогаВопрос.ДаНет;
        Оповещение = Новый ОписаниеОповещения("ПослеВопросаОРасчете", ЭтотОбъект);
        
        ПоказатьВопрос(Оповещение, 
                       "Документ загружен автоматически и не рассчитан. Выполнить расчет сейчас?", 
                       РежимДиалога);
                       
    КонецЕсли;
    
КонецПроцедуры

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

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

Недостатки: Документы остаются непроведенными до тех пор, пока их физически не откроет пользователь в интерфейсе. Метод не подходит для полностью автоматических систем без участия человека.

Решение 3. Прямое обращение к API расчетного ядра (Менеджер расчета)

В современных ERP-системах и ЗУП 3.1 разработчики постепенно уходят от практики жесткой привязки расчетов к формам. Под капотом интерфейсных вызовов скрываются мощные экспортные функции общих модулей, которые могут оперировать сырыми данными таблиц значений.

Вместо симуляции формы вы можете использовать низкоуровневые методы программного интерфейса (API) конфигурации. Например, для расчета начислений можно обратиться напрямую к функциям общего модуля РасчетЗарплатыРасширенный.

Алгоритм действий выглядит следующим образом:

  1. Программно создается документ и заполняется минимальный набор данных.
  2. Вызывается специализированная функция общего модуля (например, ДанныеДляЗаполненияТаблицДокумента), куда передается ссылка на созданный документ или структура его параметров.
  3. Метод возвращает набор таблиц значений (расчетные показатели, налоги, взносы, начисления).
  4. Программно заполняются табличные части документа полученными результатами расчетов. Важно корректно связывать строки табличных частей по техническим ключевым полям (например, ИдентификаторСтроки).
  5. Документ записывается и проводится.

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

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

При выборе способа решения ориентируйтесь на следующие правила:

← На главную