Почему в 1С:УПП при расчете зарплаты подставляется старый оклад и как исправить дублирование записей в срезе последних?

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Суть проблемы: когда СрезПоследних возвращает две записи

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

Проанализируем ситуацию: если мы заглянем в регистр сведений ПлановыеНачисленияРаботниковОрганизаций, мы увидим обе записи. Казалось бы, виртуальная таблица СрезПоследних должна вернуть только одну — самую актуальную на дату расчета. Но в реальности запрос может вернуть две строки для одного и того же сотрудника и вида расчета. Это происходит из-за того, что записи отличаются в измерениях или служебных реквизитах, которые не всегда очевидны при беглом просмотре.

Анализ проблемного запроса

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


|ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
|    ПлановыеНачисленияРаботников.Период,
|    ПлановыеНачисленияРаботников.Сотрудник КАК Сотрудник,
|    ПлановыеНачисленияРаботников.Сотрудник.Физлицо КАК ФизЛицо,
|    ВЫБОР
|        КОГДА ПлановыеНачисленияРаботников.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
|                И ПлановыеНачисленияРаботников.ПериодЗавершения <= &парамНачало
|        ТОГДА ПлановыеНачисленияРаботников.ДействиеЗавершения
|        ИНАЧЕ ПлановыеНачисленияРаботников.Действие
|    КОНЕЦ КАК Действие,
|    // ... выбор остальных показателей (Оклад, Тариф и т.д.)
|ПОМЕСТИТЬ ЗаписиПлановыхНачислений
|ИЗ
|    РегистрСведений.ПлановыеНачисленияРаботниковОрганизаций.СрезПоследних(
|            &парамНачало,
|            Организация = &Организация
|                И Сотрудник В
|                    (ВЫБРАТЬ СписокРаботников.Сотрудник ИЗ ВТСписокРаботников КАК СписокРаботников)) КАК ПлановыеНачисленияРаботников
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТСписокРаботников КАК СписокРаботников
|        ПО (СписокРаботников.Сотрудник = ПлановыеНачисленияРаботников.Сотрудник)

При выполнении этого запроса мы обнаруживаем, что для одного сотрудника приходят две строки: одна от 01.01 (из переноса) и одна от 01.09 (из перемещения). Выясним причину такого поведения системы 1С.

Почему СрезПоследних "двоит" записи?

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

  1. Измерение ВидРасчетаИзмерение: В некоторых версиях конфигураций на базе 1С:ЗУП 2.5 существует скрытое измерение ВидРасчетаИзмерение. Если в одной записи оно заполнено, а в другой — нет, СрезПоследних выдаст обе.
  2. Различия в типах данных: В регистре используются составные типы для показателей. Если при программном переносе значение записано как Число, а в кадровом документе оно приведено к определенной точности или имеет другой тип в рамках составного, для базы данных это разные ключи записи.
  3. Пустые ссылки vs Неопределено: Это классическая проблема переноса. В измерениях могут оказаться Неопределено вместо пустой ссылки конкретного типа (например, справочника Документы). Визуально в консоли запросов это выглядит как пустая ячейка, но программно это разные значения.
  4. Реквизит "Первичный документ": Хотя это реквизит, а не измерение, алгоритмы расчета ЗП в УПП часто используют его для дополнительной фильтрации или связи таблиц. Если он не заполнен (как часто бывает при использовании документа Перенос данных), типовые механизмы могут отрабатывать некорректно.

Решение проблемы через типизацию (ВЫРАЗИТЬ)

Проанализируем технический совет: при работе с объединениями запросов (ОБЪЕДИНИТЬ), особенно когда данные попадают во временные таблицы, критически важно использовать функцию ВЫРАЗИТЬ. Это исключает проблему неявного приведения типов составных полей. Рассмотрим, как должен выглядеть фрагмент кода:


ВЫБОР
    КОГДА ПлановыеНачисленияРаботников.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
            И ПлановыеНачисленияРаботников.ПериодЗавершения <= &парамНачало
    ТОГДА ВЫРАЗИТЬ(ПлановыеНачисленияРаботников.Показатель1Завершения КАК ЧИСЛО(15, 2))
    ИНАЧЕ ВЫРАЗИТЬ(ПлановыеНачисленияРаботников.Показатель1 КАК ЧИСЛО(15, 2))
КОНЕЦ КАК Показатель1

Это помогает, если проблема кроется в метаданных временной таблицы, но не решает вопрос "грязных" данных в самом регистре.

Лучшая практика: Использование штатных документов

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

Рассмотрим алгоритм правильного исправления:

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

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

Заключение

Подведем итог: если в УПП 1.3 при расчете зарплаты подтягиваются неверные показатели окладов, в первую очередь проверьте уникальность записей в регистре плановых начислений. Помните, что СрезПоследних — это инструмент, чувствительный к чистоте данных в измерениях. Использование штатных документов ввода сведений вместо универсальных механизмов прямого заполнения регистров — это залог стабильной работы расчетных механизмов системы.

← На главную