Почему «СрезПоследних» выдает неактуальные данные и как это исправить?

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

При разработке отчетов или обработок в 1С:Зарплата и Управление Персоналом часто возникает потребность получить актуальное состояние кадровых данных сотрудников. Мы привыкли использовать виртуальную таблицу СрезПоследних, однако при попытке отфильтровать результат по определенному условию, например, исключить уволенных сотрудников, часто получаем неожиданный результат: в выборку попадают записи, которые не являются последними на текущий момент. Давайте разберемся, почему это происходит и как правильно строить запросы.

Суть проблемы: как работает виртуальная таблица

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

  1. Когда вы указываете условие в параметрах виртуальной таблицы (например, ВидСобытия <> &Увольнение), база данных сначала отсекает все записи, соответствующие этому условию, из всей истории регистра.
  2. Только после этого «урезанного» набора данных система пытается вычислить, какая запись является последней.
  3. В итоге вы получаете «последнюю запись среди неуволенных», которой фактически может быть запись о перемещении сотрудника, сделанная месяцы назад, хотя после этого был документ увольнения.

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

Решение 1: Использование блока «ГДЕ»

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

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


ВЫБРАТЬ
    Срез.Сотрудник,
    Срез.Подразделение,
    Срез.ВидСобытия
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&НачПериода, ) КАК Срез
ГДЕ
    Срез.ВидСобытия <> &Увольнение

Именно этот подход гарантирует, что вы получите актуальную последнюю запись, а не «предыдущую перед увольнением».

Решение 2: Двухэтапная выборка

Если задача сложнее (например, нужно отсечь целую группу сотрудников, которые были уволены), можно поступить еще более надежным способом:

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

Это позволяет избежать ошибок при сложных связях и делает код более читаемым и отлаживаемым.

Лучшие практики в ЗУП 3: почему не стоит писать прямые запросы

Работая с 1С:ЗУП 3, важно помнить, что структура метаданных может меняться с обновлениями конфигурации. Если вы будете писать прямые запросы к регистрам, ваш код может «сломаться» после очередного релиза. Фирма «1С» предоставляет мощный программный интерфейс для работы с кадровыми данными.

Вместо того чтобы обращаться напрямую к таблицам КадроваяИсторияСотрудников, рассмотрите использование общего модуля КадровыйУчет. Например, функция ПолучитьКадровыеДанныеСотрудников возвращает структурированный набор данных, в котором уже учтены все нюансы кадрового учета, исправлений и перерасчетов. Это «безопасный» путь, который гарантирует корректность работы вашего отчета в будущих версиях программы.

Важное правило про ресурсы и измерения

Напоследок закрепим правило, которое поможет вам не допускать подобных ошибок в будущем:

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

← На главную