Почему отчет в ЗУП 3.0 выводит данные за весь месяц при выборе произвольного периода?

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

При разработке произвольных отчетов на системе компоновки данных (СКД) в конфигурации Зарплата и управление персоналом 3.0 (ЗУП) программисты часто сталкиваются с тем, что отчет игнорирует конкретные даты начала и конца периода. Например, если указать период с 1 по 2 июля, отчет выведет все начисления за июль. Если же указать со 2 по 3 июля — отчет окажется пустым. Давайте проанализируем эту ситуацию, разберем причины такого поведения платформы и найдем способы решения задачи.

Анализ исходного запроса и структуры данных

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


ВЫБРАТЬ
    НачисленияУдержанияПоСотрудникамОбороты.Организация,
    НачисленияУдержанияПоСотрудникамОбороты.ФизическоеЛицо,
    НачисленияУдержанияПоСотрудникамОбороты.СуммаОборот
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК НачисленияУдержанияПоСотрудникамОбороты

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

Причина №1: Период регистрации в регистрах накопления

Разберем, как устроены регистры накопления в ЗУП 3.0, такие как НачисленияУдержанияПоСотрудникам или ВзаиморасчетыССотрудниками. В отличие от бухгалтерских регистров или регистров в торговых конфигурациях, записи по начислениям зарплаты в ЗУП всегда «привязываются» к началу месяца. Это называется периодом регистрации.

Если сотруднику начислили оклад за июль 2018 года, то в регистре появится запись, где в поле Период будет стоять дата 01.07.2018 00:00:00. Других записей (например, за 15-е или 20-е число) для этого начисления просто не существует.

Проанализируем поведение системы при разных фильтрах:

  1. Период 01.07.2018 — 02.07.2018: Виртуальная таблица видит, что дата 01.07.2018 входит в интервал. Она подтягивает все итоги, зафиксированные на это число (то есть всю зарплату за месяц).
  2. Период 02.07.2018 — 03.07.2018: В этом интервале нет записей с датой 01.07.2018. Поскольку других записей в регистре для этого месяца нет, отчет возвращает пустой результат.

Причина №2: Отсутствие данных о «Периоде действия» в оборотах

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

В представленном запросе данные по командировкам объединяются с данными из регистра расчета РегистрРасчета.Начисления. Однако основная масса данных идет из регистров накопления, которые «не знают» о распределении суммы по дням внутри месяца. Посмотрим на этот участок кода:


ГДЕ Начисления.ПериодРегистрации МЕЖДУ &НачалоПериода И &КонецПериода
И Начисления.Регистратор ССЫЛКА Документ.Командировка

Здесь также используется ПериодРегистрации, что возвращает нас к проблеме первого числа месяца.

Решение №1: Принудительное округление периода до месяца

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

Для этого в СКД на закладке «Параметры» для параметров НачалоПериода и КонецПериода в колонке «Выражение» пропишем следующее:

Таким образом, даже если пользователь выберет 15-е число, система автоматически подставит 1-е число месяца, и данные будут корректными в контексте методологии ЗУП.

Решение №2: Переход на использование Регистров Расчета

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

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

  1. Используем таблицу ФактическийПериодДействия регистра расчета.
  2. В условиях запроса накладываем фильтр на пересечение выбранного периода с фактическим периодом действия записи.
  3. Внимание! Поскольку сумма в регистре хранится целиком за весь период (например, за 20 рабочих дней), нам придется вручную в запросе рассчитывать сумму пропорционально дням, попавшим в выбранный интервал.

Пример логики расчета в запросе:


ВЫБОР
    КОГДА Начисления.ПериодДействияНачало < &НачалоПериода ТОГДА &НачалоПериода
    ИНАЧЕ Начисления.ПериодДействияНачало
КОНЕЦ ... // И далее расчет пропорции суммы

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

Решение №3: Использование предопределенных настроек СКД

В ЗУП 3.0 многие стандартные отборы реализованы через расширения языка запросов СКД. Проанализируем использование фигурных скобок {} в коде автора:


ИЗ РегистрНакопления.ИсчисленныеСтраховыеВзносы.Обороты(&НачалоПериода {(&НачалоПериода)}, &КонецПериода {(&КонецПериода)}, Регистратор, Договорник)

Использование конструкции {(&НачалоПериода)} позволяет СКД заменять параметры на лету. Если вы хотите, чтобы отчет учитывал именно движения (регистраторы) внутри периода, попробуйте изменить периодичность виртуальной таблицы с Авто на Запись или День. Но помните: в регистрах накопления ЗУП это все равно приведет к тому, что записи будут найдены только на 1-е число месяца.

Выводы и рекомендации

Подведем итоги нашего исследования:

  1. Особенности ЗУП: Регистры накопления в ЗУП 3.0 хранят данные в разрезе месяцев (на 1-е число). Попытка получить «обороты» за середину месяца стандартными средствами всегда будет давать либо «всё», либо «ничего».
  2. Исправление отчета: Самый надежный и быстрый способ исправить отчет — установить выражения в параметрах СКД, которые будут приводить выбранные даты к границам месяца.
  3. Смена источника: Если нужна детальная аналитика по дням, необходимо уходить от оборотов регистров накопления к записям регистров расчета с анализом периодов действия.

Проанализируйте, какая именно точность нужна вашим пользователям. В 99% случаев для «Расчетной ведомости» достаточно месячной детализации, так как налоги, взносы и большинство начислений в системе рассчитываются и закрываются строго помесячно.

← На главную