Как получить последний документ в цепочке исправлений для сотрудника

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

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

Метод 1. Использование регистров сведений (Рекомендуемый подход)

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

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


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

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

Метод 2. Прямой запрос к таблицам документов с фильтрацией исправлений

Если же специфика вашей задачи требует обращения именно к таблицам документов (например, нужно вытащить реквизиты, которых нет в регистрах), нам придется реализовать логику отсечения исправленных документов самостоятельно. Выясним причину, почему простая группировка по дате может подвести. В 1С документ-исправление обычно имеет ту же ДатаНачала (реквизит события), но более позднюю дату самого документа (Дата).

Посмотрим на алгоритм исключения «промежуточных» документов через проверку реквизита ИсправляемыйДокумент. Почти во всех кадровых документах ЗУП есть этот скрытый реквизит. Если он заполнен, значит текущий документ является исправлением. А если ссылка на наш документ встречается в поле ИсправляемыйДокумент у какого-то другого документа — значит, наш документ уже не актуален.

Разберем по шагам, как построить такой запрос:

  1. Выбираем все проведенные документы по сотруднику во временную таблицу.
  2. Исключаем из выборки те документы, ссылки которых фигурируют в качестве исправляемых в других записях.

// Помещаем все подходящие документы во временную таблицу
ВЫБРАТЬ
    Док.Ссылка КАК Ссылка,
    Док.Сотрудник КАК Сотрудник,
    Док.Дата КАК ДатаДокумента
ПОМЕСТИТЬ ВсеДокументы
ИЗ
    Документ.КадровыйПеревод КАК Док
ГДЕ
    Док.Проведен = ИСТИНА
    И Док.ДатаНачала >= &ДатаНачала;

////////////////////////////////////////////////////////////////////////////////
// Выбираем только те, которые сами никем не исправлены
ВЫБРАТЬ
    Т1.Сотрудник,
    Т1.Ссылка
ИЗ
    ВсеДокументы КАК Т1
ГДЕ
    НЕ Т1.Ссылка В (
        ВЫБРАТЬ
            ВТ_Испр.ИсправляемыйДокумент
        ИЗ
            Документ.КадровыйПеревод КАК ВТ_Испр
        ГДЕ
            ВТ_Испр.ИсправляемыйДокумент <> ЗНАЧЕНИЕ(Документ.КадровыйПеревод.ПустаяСсылка)
    )

Метод 3. Группировка по максимальному моменту времени

Проанализируем ситуацию, когда за один день по сотруднику может быть введено несколько разных документов одного типа (например, два перевода), и нам нужно получить именно последний по времени ввода. В 1С наиболее точным способом идентификации «последнего» объекта является Момент Времени, который включает в себя дату, время и уникальную ссылку.

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


ВЫБРАТЬ
    МАКСИМУМ(Док.Дата) КАК МаксДата,
    Док.Сотрудник КАК Сотрудник
ПОМЕСТИТЬ МаксимальныеДаты
ИЗ
    Документ.Командировка КАК Док
ГДЕ
    Док.Проведен = ИСТИНА
ГРУППИРОВАТЬ ПО
    Док.Сотрудник;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    МАКСИМУМ(Док.Ссылка) КАК ПоследняяСсылка,
    Док.Сотрудник
ИЗ
    Документ.Командировка КАК Док
ВНУТРЕННЕЕ СОЕДИНЕНИЕ МаксимальныеДаты КАК Даты
    ПО Док.Сотрудник = Даты.Сотрудник
    И Док.Дата = Даты.МаксДата
ГРУППИРОВАТЬ ПО
    Док.Сотрудник

Важный момент: Мы используем МАКСИМУМ(Ссылка) на тот случай, если два документа были созданы в одну и ту же секунду. Ссылка в 1С (GUID) при создании новых объектов в рамках одной информационной базы обычно монотонно возрастает (технически это зависит от настроек генерации, но для задач запроса это стандартный способ «разрезания» одинаковых дат).

Особенности работы с данными состояний

В сообщениях форума упоминался регистр ДанныеСостоянийСотрудников. Это крайне полезный объект, если вам нужно узнать, в каком состоянии находится сотрудник «сейчас» или на определенную дату (в отпуске, в командировке или работает). Мы рекомендуем использовать именно его для анализа текущей занятости, так как этот регистр является «результирующим» — он хранит итог всех проведенных документов отклонений.

Пример получения состояния:


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

Подведение итогов

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

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

← На главную