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

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

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

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

Способ 1. Использование механизма «Менеджер расчета зарплаты»

Этот метод считается наиболее надежным и «чистым» с точки зрения методологии 1С, так как он использует те же алгоритмы, которые применяет сама система при нажатии кнопки «Рассчитать» в документе. Суть метода заключается в том, чтобы программно инициализировать объект МенеджерРасчета, загрузить в него данные сотрудника и выполнить расчет. Чтобы не изменять данные в базе, все операции проводятся внутри транзакции, которая в конце отменяется.

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

  1. Инициализация менеджера: Создаем объект через РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета.
  2. Подготовка данных: Нам необходимо заполнить таблицу сотрудников и установить настройки (указать, что мы рассчитываем именно начисления).
  3. Выполнение расчета: Вызываем метод РассчитатьЗарплату.
  4. Анализ результата: Извлекаем данные из коллекции МенеджерРасчета.Зарплата.Начисления.

Проанализируем пример кода для реализации этого метода:


УстановитьПривилегированныйРежим(Истина);
НачатьТранзакцию();

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

СотрудникиДляНачислений = МенеджерРасчета.ТаблицаСотрудников;
СотрудникиДляРассчета = Новый Массив;

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

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

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

// Здесь мы получаем доступ к рассчитанным данным, включая показатели базы
ТаблицаРезультатов = МенеджерРасчета.Зарплата.Начисления;

ОтменитьТранзакцию();
УстановитьПривилегированныйРежим(Ложь);

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

Способ 2. Запрос к виртуальной таблице «База» регистра расчета

Если данные уже записаны в регистр расчета Начисления, мы можем воспользоваться механизмом платформы для получения базы. Для этого используется виртуальная таблица РегистрРасчета.Начисления.БазаОсновныеНачисления.

Посмотрим на пример запроса, который позволяет определить, какие начисления входят в базу конкретного вида расчета (например, нашей премии):


ВЫБРАТЬ
    НачисленияБазовыеВидыРасчета.ВидРасчета КАК БазовыйВидРасчета
ПОМЕСТИТЬ ВТ_БазовыеВиды
ИЗ
    ПланВидовРасчета.Начисления.БазовыеВидыРасчета КАК НачисленияБазовыеВидыРасчета
ГДЕ
    НачисленияБазовыеВидыРасчета.Ссылка = &ВидРасчетаПремия;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    НачисленияБаза.ВидРасчета КАК ВидРасчета,
    НачисленияБаза.НомерСтроки КАК НомерСтроки,
    НачисленияБаза.РезультатБаза КАК СуммаВходящаяВБазу,
    НачисленияБаза.Сотрудник КАК Сотрудник
ИЗ
    РегистрРасчета.Начисления.БазаОсновныеНачисления(
        &ИзмеренияОсновногоРегистра,
        &ИзмеренияБазовогоРегистра,
        &Разрезы,
        ВидРасчета = &ВидРасчетаПремия И Регистратор = &Регистратор
    ) КАК НачисленияБаза

При использовании этого метода важно правильно настроить параметры виртуальной таблицы:

Преимущество: Это работает быстро и не требует эмуляции расчета. Недостаток: Если после расчета премии базовые начисления (например, оклад) были изменены или пересчитаны без пересчета самой премии, виртуальная таблица может вернуть актуальные (измененные) данные, которые не будут соответствовать сумме, фактически зафиксированной в премии.

Способ 3. Получение данных через механизмы среднего заработка

Часто задача получения базы премии связана с расчетом среднего заработка (как упоминал автор темы в сообщении 53). В ЗУП 3.1 существует регистр сведений ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий. Хотя он хранит уже «пропорциональные» суммы, в нем можно отследить связь начислений с конкретным периодом и регистратором.

Если же стоит задача изменить логику вхождения премии в средний заработок в зависимости от наличия командировок, рассмотрите возможность использования показателей. Как предложено в сообщении 56, можно создать технический показатель Командировка, который будет принимать значение 1 или 0, и использовать его прямо в формуле премии:

Оклад + ?(Командировка = 0, Надбавка, Надбавка * ДоляОтработки)

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

Выбирая метод, проанализируйте следующие факторы:

  1. Момент вызова: Если вам нужна база в момент заполнения документа — используйте Способ 1 (Менеджер расчета).
  2. Отчетность: Если нужно вывести расшифровку уже существующих документов — используйте Способ 2 (Запрос к Базе).
  3. Производительность: Запросы к виртуальным таблицам работают значительно быстрее, чем инициализация менеджера расчета зарплаты.
  4. Сложные формулы: Если премия рассчитывается не просто процентом, а по сложной формуле с множеством показателей, только Менеджер расчета даст вам 100% гарантию корректности данных, так как он «прокручивает» формулу целиком.

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

← На главную