Почему в отчете Фактические отпуска не отображаются данные при наличии нескольких исправлений

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

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

Анализ типового механизма запроса

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


|ВЫБОР
|    КОГДА НЕ ФактическиеОтпускаСторно.Сотрудник ЕСТЬ NULL
|            И ФактическиеОтпуска.Количество > 0
|        ТОГДА ИСТИНА
|    ИНАЧЕ ЛОЖЬ
|КОНЕЦ КАК СторнируемаяЗапись,
|ВЫБОР
|    КОГДА НЕ ФактическиеОтпускаСторно.Сотрудник ЕСТЬ NULL
|            И ФактическиеОтпуска.Количество < 0
|        ТОГДА ИСТИНА
|    ИНАЧЕ ЛОЖЬ
|КОНЕЦ КАК СторноЗапись
|ПОМЕСТИТЬ ВТФактическиеОтпускаСоСторноПризнаками
|ИЗ
|    ВТФактическиеОтпуска КАК ФактическиеОтпуска
|        ЛЕВОЕ СОЕДИНЕНИЕ ВТФактическиеОтпуска КАК ФактическиеОтпускаСторно
|        ПО ФактическиеОтпуска.Сотрудник = ФактическиеОтпускаСторно.Сотрудник
|            И ФактическиеОтпуска.ВидЕжегодногоОтпуска = ФактическиеОтпускаСторно.ВидЕжегодногоОтпуска
|            И ФактическиеОтпуска.ДатаНачала = ФактическиеОтпускаСторно.ДатаНачала
|            И ФактическиеОтпуска.ДатаОкончания = ФактическиеОтпускаСторно.ДатаОкончания
|            И (ФактическиеОтпуска.Количество = -ФактическиеОтпускаСторно.Количество)
|            И ФактическиеОтпуска.Регистратор <> ФактическиеОтпускаСторно.Регистратор

Затем в финальном запросе записи, помеченные как СторнируемаяЗапись или СторноЗапись, отсекаются простым фильтром ГДЕ НЕ СторнируемаяЗапись И НЕ СторноЗапись. Эта логика идеально работает для схемы «один первичный документ — одно исправление», но полностью ломается при возникновении цепочки исправлений.

Выясним причину ошибки при цепочке исправлений

Рассмотрим на конкретном примере, что происходит в регистре накопления ФактическиеОтпуска, когда документ исправляется дважды (например, из-за пересчета среднего заработка после начисления годовой премии):

  1. Документ №1 (Первичный): Количество = 10 дней.
  2. Документ №2 (Первое исправление): Сторнирует Документ №1 (-10 дней) и начисляет новое значение (+12 дней).
  3. Документ №3 (Второе исправление): Сторнирует Документ №2 (-12 дней) и начисляет финальное значение (+12.5 дней).

Когда выполняется ЛЕВОЕ СОЕДИНЕНИЕ таблицы самой с собой по условию Количество = -Количество, для записи из Документа №2 (+12 дней) находится пара в Документе №3 (-12 дней). Обе записи получают флаги сторно и исключаются. Однако, если количество дней в цепочке совпадает (например, в обоих исправлениях было по 12 дней), то из-за множественного соединения «всех со всеми» по датам и количеству, под исключение может попасть даже финальная, актуальная запись. В результате отчет по сотруднику становится абсолютно пустым.

Вариант решения №1: Группировка и суммирование (рекомендуемый)

Самым надежным способом решения проблемы является отказ от попыток найти «пару» для каждой записи. Вместо этого проанализируем возможность свертки данных по ключевым полям. Выясним, какие поля определяют уникальность отпуска: это Сотрудник, ВидЕжегодногоОтпуска, ДатаНачала, ДатаОкончания и РабочийПериод.

Перепишем узел запроса, заменив соединение на группировку:


ВЫБРАТЬ
    ФактическиеОтпуска.Сотрудник КАК Сотрудник,
    ФактическиеОтпуска.ВидЕжегодногоОтпуска КАК ВидЕжегодногоОтпуска,
    ФактическиеОтпуска.ДатаНачала КАК ДатаНачала,
    ФактическиеОтпуска.ДатаОкончания КАК ДатаОкончания,
    СУММА(ФактическиеОтпуска.Количество) КАК КоличествоДней,
    ФактическиеОтпуска.РабочийПериодС КАК РабочийПериодС,
    ФактическиеОтпуска.РабочийПериодПо КАК РабочийПериодПо
ИЗ
    ВТФактическиеОтпуска КАК ФактическиеОтпуска
СГРУППИРОВАТЬ ПО
    ФактическиеОтпуска.Сотрудник,
    ФактическиеОтпуска.ВидЕжегодногоОтпуска,
    ФактическиеОтпуска.ДатаНачала,
    ФактическиеОтпуска.ДатаОкончания,
    ФактическиеОтпуска.РабочийПериодС,
    ФактическиеОтпуска.РабочийПериодПо
ИМЕЮЩИЕ
    СУММА(ФактическиеОтпуска.Количество) <> 0

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

Вариант решения №2: Анализ поля Основание

В регистре накопления Фактические отпуска существует поле Основание. При создании цепочки исправлений это поле зачастую ссылается на самый первый, исходный документ отпуска. Рассмотрим алгоритм фильтрации с учетом этого поля:

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

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

  1. Откройте Универсальный отчет по регистру накопления Фактические отпуска.
  2. Установите отбор по интересующему сотруднику.
  3. Посмотрите на колонку Активность. Убедитесь, что все записи активны.
  4. Если вы видите длинную цепочку записей с одинаковыми датами начала и окончания, но разными регистраторами и знаками (плюс/минус) — вы столкнулись именно с этой архитектурной особенностью типового запроса.

Таким образом, для корректного отображения фактических отпусков в условиях частых пересчетов (например, при выплате квартальных или годовых премий, влияющих на средний заработок прошлых периодов), типовой запрос отчета требует модификации в части обработки сторно-записей. Использование агрегатной функции СУММА с группировкой по измерениям является наиболее стабильным программным решением данной проблемы.

← На главную