Как программно вызвать расчет сотрудника в документе «Начисление зарплаты» в 1С:ЗУП 3.1?

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

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

Анализ проблемы: Почему прямой вызов из формы не работает?

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

Проанализируем, что представляет собой эта переменная. Это сложная структура, которая содержит метаданные о том, как программа должна обрабатывать конкретную таблицу начислений. В неё входят имена реквизитов (например, Результат, Сотрудник, ДатаНачала), пути к данным формы и флаги режимов расчета. Без корректно заполненной структуры ОписаниеТаблицы типовой код расчета не сможет определить, в какие колонки записывать результат и откуда брать исходные показатели.

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

Решение №1: Использование серверной логики (рекомендуемый способ)

Вместо того чтобы пытаться имитировать действия пользователя на форме, мы рекомендуем использовать программный интерфейс (API) конфигурации ЗУП 3.1. Наиболее правильный путь — заполнить объект документа на сервере и вызвать методы из общих модулей, которые отвечают за расчет логики документа.

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

  1. Подготовка данных: При заполнении документа из Excel необходимо заполнить не только таблицу Начисления, но и вспомогательные таблицы, такие как Показатели.
  2. Связь через Идентификаторы: Это критически важный момент. Каждая строка в таблице Начисления должна иметь уникальный ИдентификаторСтрокиВидаРасчета. Этот же идентификатор должен быть указан в таблице Показатели для соответствующих значений (например, «Оклад» или «Процент премии»), иначе расчетный механизм не поймет, к какому начислению относятся данные показатели.
  3. Вызов модуля расчета: Для выполнения расчета документа целиком (или по конкретным сотрудникам) следует использовать методы общих модулей, таких как РасчетЗарплатыЛогика или ПроведениеРасчетов.

Пример кода для вызова расчета на сервере:


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

Решение №2: Инициализация ОписанияТаблицы (если форма необходима)

Если ваша задача жестко завязана на интерактивное взаимодействие с формой и вы всё же решили вызывать РассчитатьСотрудника, вам потребуется воссоздать структуру ОписаниеТаблицы. Проанализируем её состав, полученный через отладчик:

Типовая структура ОписаниеТаблицы для таблицы «Начисления» включает в себя более 40 полей. Основные из них:

В модуле формы документа ЗУП обычно есть функция, которая возвращает массив таких описаний. Вместо ручного создания структуры, попробуем найти её в реквизитах формы. Обычно это переменная или параметр ОписаниеТаблицРасчета, который инициализируется в ПриСозданииНаСервере.

Выясним, как передать эти данные в процедуру:


// На клиенте внутри вашей формы
&НаКлиенте
Процедура ВыполнитьРасчет(СотрудникСсылка)
    
    // Получаем форму документа
    ПараметрыФормы = Новый Структура("Ключ", СсылкаНаДокумент);
    ФормаДокумента = ПолучитьФорму("Документ.НачислениеЗарплаты.Форма.ФормаДокумента", ПараметрыФормы);
    
    // В ЗУП 3.1 описания таблиц часто хранятся в скрытых реквизитах или кэше формы
    // Мы можем попытаться найти нужное описание в массиве описаний формы
    ОписаниеНачислений = Неопределено;
    Для Каждого Описание Из ФормаДокумента.ОписаниеТаблицРасчета Цикл
        Если Описание.ИмяТаблицы = "Начисления" Тогда
            ОписаниеНачислений = Описание;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если ОписаниеНачислений <> Неопределено Тогда
        ФормаДокумента.РассчитатьСотрудника(СотрудникСсылка, ОписаниеНачислений);
    КонецЕсли;

КонецПроцедуры

Важные нюансы при заполнении из Excel

Разберем ситуацию с заполнением показателей подробнее. Часто программисты совершают ошибку, заполняя только сумму начисления. Однако ЗУП — это система, работающая «от обратного»: она рассчитывает результат на основании показателей и формул.

Рассмотрим правильную последовательность действий:

  1. Создаем новую строку в табличной части Начисления.
  2. Генерируем новый УникальныйИдентификатор и записываем его в ИдентификаторСтрокиВидаРасчета.
  3. Добавляем строки в табличную часть Показатели. Для каждой строки показателя обязательно указываем тот же ИдентификаторСтрокиВидаРасчета, который мы сгенерировали для начисления.
  4. Только после этого вызываем процедуру расчета. Если показатели заполнены верно, процедура сама рассчитает поле Результат согласно формуле начисления.

Посмотрим на пример кода инициализации идентификатора:


НоваяСтрока = Объект.Начисления.Добавить();
НоваяСтрока.Сотрудник = ВыбранныйСотрудник;
НоваяСтрока.Начисление = ВыбранноеНачисление;
// Генерация связи
НоваяСтрока.ИдентификаторСтрокиВидаРасчета = Новый УникальныйИдентификатор();

// Заполнение показателя (например, Оклад)
СтрокаПоказателя = Объект.Показатели.Добавить();
СтрокаПоказателя.ИдентификаторСтрокиВидаРасчета = НоваяСтрока.ИдентификаторСтрокиВидаРасчета;
СтрокаПоказателя.Показатель = Справочники.ПоказателиРасчетаЗарплаты.НайтиПоНаименованию("Оклад");
СтрокаПоказателя.Значение = 50000;

Резюме

Проанализировав проблему, мы пришли к выводу, что наиболее стабильный и «чистый» способ программного расчета в ЗУП 3.1 — это выполнение операций на стороне сервера. Использование РасчетЗарплатыЛогика.РассчитатьДокумент() избавляет разработчика от необходимости эмулировать контекст формы и вручную собирать сложные структуры ОписаниеТаблицы. Помните о связности таблиц через идентификаторы — это ключ к корректной работе всех внутренних механизмов расчета зарплаты.

← На главную