Как программно рассчитать документ Отпуск в ЗУП 3.1 на сервере без открытия формы

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

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

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

Анализ проблемы: почему метод формы не подходит для фонового задания

Проанализируем типичную ситуацию. Когда пользователь нажимает кнопку на форме, срабатывает экспортная процедура РассчитатьНачисления(). Если попытаться вызвать её из кода внешней обработки или фонового задания, система выдаст ошибку, так как внутри этой процедуры (или в вызываемых ею методах) обязательно встретятся обращения к объектам типа Форма, клиентским общим модулям или интерактивным методам (например, ПоказатьВопрос или ОткрытьФорму).

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

Использование серверных модулей для расчета

Выясним, какие инструменты предоставляет нам конфигурация ЗУП 3.1 для серверного расчета. Ключевым звеном здесь является общий модуль РасчетЗарплатыРасширенный. Именно в нем сосредоточена логика, позволяющая инициировать расчет объекта документа без привязки к его экранному представлению.

Рассмотрим основной метод, который следует использовать — ЗаполнитьИРассчитатьДокумент. Этот метод выполняет комплекс действий: от заполнения табличных частей по кадровым данным до расчета сумм начислений и среднего заработка.

Пример программного вызова может выглядеть следующим образом:


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

// Заполняем документ основными данными (кадровый приказ и т.д.)
// Вызов специализированных процедур заполнения
// ...

// Выполняем расчет на сервере
ПараметрыРасчета = РасчетЗарплатыРасширенный.ПараметрыРасчетаДокумента();
ПараметрыРасчета.ЗаписыватьРезультаты = Истина;
ПараметрыРасчета.ПересчитатьДокументПолностью = Истина;

РасчетЗарплатыРасширенный.ЗаполнитьИРассчитатьДокумент(ДокументОбъект, ПараметрыРасчета);

// Записываем рассчитанный документ
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

Подготовка данных и расчет среднего заработка

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

Для корректного программного расчета нам нужно убедиться, что:

  1. Заполнены данные о периоде, за который берется средний заработок (обычно 12 месяцев).
  2. Вызваны процедуры модуля УчетСреднегоЗаработка. В современных релизах РасчетЗарплатыРасширенный.ЗаполнитьИРассчитатьДокумент берет это на себя, но в случае кастомных алгоритмов может потребоваться явный вызов обновления данных среднего заработка.

Если нам необходимо только обновить расчеты в уже существующем документе, мы можем использовать упрощенную схему:


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

Механизм фонового расчета документов

Разберем штатную возможность системы, которая появилась в последних версиях ЗУП 3.1. Разработчики 1С внедрили механизм очереди расчета документов. Если в настройках расчета зарплаты (раздел Настройка — Расчет зарплаты) включена опция «Выполнять расчет документов при редактировании», система автоматически старается производить вычисления.

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

Преимущества работы через очередь:

Практические советы по отладке

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

  1. Включите в настройках пользователя режим «Без автоматического расчета документов».
  2. Откройте документ Отпуск.
  3. Включите замер производительности в конфигураторе.
  4. Нажмите кнопку Рассчитать на форме документа.
  5. Остановите замер и проанализируйте дерево вызовов.

Ищите процедуры, которые находятся в модулях с флагом Сервер или Вызов сервера. Обычно это процедуры, начинающиеся с Рассчитать... или ВыполнитьРасчет... внутри общих модулей подсистемы РасчетЗарплаты. Наша задача — найти ту точку входа, которая получает на вход ДокументОбъект и не имеет параметров типа Форма.

Резюме по исправлению ошибок утверждения

Стоит отметить, что в старых релизах существовала проблема (баг 10214751), когда при утверждении документа из списка (через контекстное меню) он мог остаться нерассчитанным. Разработчики 1С решили эту проблему радикально — в новых версиях кнопка Утвердить в списке просто скрывается, если документ требует расчета. Это еще раз подтверждает важность полноценного вызова серверных расчетных процедур при программном создании документов, чтобы статус документа позволял проводить его дальше по бизнес-процессу.

Используя методы модуля РасчетЗарплатыРасширенный и механизм ОчередьРасчетаДокументов, мы можем эффективно автоматизировать процесс начисления отпускных, полностью исключив зависимость от клиентского интерфейса и обеспечив высокую скорость обработки данных.

← На главную