Как программно рассчитать средний заработок в 1С:ЗУП 3.1?

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

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

Понимание архитектуры расчета

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

Для корректного расчета мы будем использовать программный интерфейс, предоставляемый конфигурацией. Основным инструментом для нас послужит общий модуль УчетСреднегоЗаработка и связанные с ним функции.

Подготовка данных для расчета

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

Проанализируем основные этапы:

  1. Определение периода расчета.
  2. Выбор сотрудника и организации.
  3. Инициализация параметров расчета (вид среднего заработка: для отпуска, командировки или пособий).
  4. Вызов метода расчета.

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

Пример программного расчета

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

Сначала определим необходимые переменные и сотрудника:


СотрудникСсылка = Справочники.Сотрудники.НайтиПоКоду("00001");
ДатаНачалаСобытия = ТекущаяДата();
ОрганизацияСсылка = СотрудникСсылка.Организация;

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

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

Более простой и часто используемый подход среди программистов 1С — это использование объектной модели через создание документа в памяти (без записи). Это гарантирует, что отработают все типовые алгоритмы заполнения.

Разберем этот метод подробнее:


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

// Заполняем кадровые данные (важно для подтягивания графиков и стажа)
ДокументОбъект.Заполнить(Неопределено); 

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

В модуле объекта документа или менеджере часто есть экспортные методы. Но чаще всего расчет среднего инициируется через общий модуль РасчетЗарплатыРасширенный или УчетСреднегоЗаработка.

Для чистого расчета через API (без создания объекта документа) код будет выглядеть сложнее, но он работает быстрее. Рассмотрим пример использования калькулятора:


Отказ = Ложь;
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(ОрганизацияСсылка, ДатаНачалаСобытия);

// Заполняем таблицу сотрудников
СтрокаСотрудника = МенеджерРасчета.Сотрудники.Добавить();
СтрокаСотрудника.Сотрудник = СотрудникСсылка;

// Получаем данные для среднего
ПараметрыПолученияДанных = УчетСреднегоЗаработка.ПараметрыПолученияДанныхДляРасчетаСреднего();
ПараметрыПолученияДанных.Организация = ОрганизацияСсылка;
ПараметрыПолученияДанных.Сотрудник = СотрудникСсылка;
ПараметрыПолученияДанных.ПериодРегистрации = НачалоМесяца(ДатаНачалаСобытия);

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

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


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

// Теперь можно прочитать рассчитанное значение
Если ДокументОбъект.СреднийЗаработок.Количество() > 0 Тогда
    Средний = ДокументОбъект.СреднийЗаработок[0].СреднийЗаработокОбщий;
    Сообщить("Рассчитанный средний: " + Средний);
КонецЕсли;

Нюансы при работе с премиями и индексацией

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

В типовом механизме учет премий происходит при сборе базы за расчетный период (обычно 12 месяцев). Если вы используете функцию УчетСреднегоЗаработка.СформироватьДанныеДляРасчетаСреднегоЗаработка, убедитесь, что в структуру параметров переданы корректные настройки порядка учета премий. Они обычно берутся из настроек начислений (планов видов расчета).

Если вы заметили, что цифра отличается от той, что в документе "Отпуск", проверьте следующее:

  1. Правильно ли определен Расчетный период. В коде мы часто забываем сдвинуть его на месяц назад, если событие начинается не с первого числа.
  2. Учтены ли Вводы начальных остатков, если база старая.
  3. Проведена ли индексация заработка. Объект КоэффициентыИндексации должен быть корректно заполнен внутри механизма расчета.

Использование компоновщика данных

Существует еще один профессиональный подход — использование Схемы Компоновки Данных (СКД), которая зашита в макеты регистров расчета. Программисты 1С могут извлечь этот макет и выполнить компоновку программно.

Посмотрим, как это реализуется концептуально. Мы берем макет, устанавливаем параметры (Сотрудник, Период) и выполняем процессор компоновки. Результатом будет таблица значений с базой среднего. Разделив базу на дни/часы, мы получим искомую ставку.


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

Однако этот метод требует поддержки кода при каждом изменении макетов разработчиками 1С. Поэтому мы рекомендуем использовать вызовы общих модулей, таких как УчетСреднегоЗаработка, так как это API поддерживается поставщиком.

Заключение

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

← На главную