Как найти дату последнего приема на работу в 1С при наличии истории увольнений?

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

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

Рассмотрим подробно, как реализовать этот алгоритм, проанализируем структуру запроса и разберем технические нюансы, которые помогут избежать ошибок при работе с большими объемами данных.

Анализ исходных данных и постановка задачи

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

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

Шаг 1: Определение последней даты увольнения

Первым делом нам необходимо выяснить, увольнялся ли сотрудник ранее, и если да, то когда это произошло в последний раз. Для этого мы воспользуемся механизмом временных таблиц в запросе. Проанализируем ситуацию: если у сотрудника было несколько увольнений, нас интересует только самое позднее из них.

Рассмотрим структуру первого запроса в пакете:


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

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

Шаг 2: Получение даты первого приема после увольнения

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

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


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

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

Шаг 3: Оптимизация и работа с индексами

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

  1. Индексирование временных таблиц: Всегда добавляйте индексирование по полю Сотрудник во временной таблице ВТ_ПоследниеУвольнения. Это значительно ускорит операцию соединения.
  2. Фильтрация на входе: Если вам нужны данные не по всем сотрудникам сразу, а только по конкретному списку или подразделению, накладывайте этот фильтр в каждом вложенном запросе пакета.
  3. Проверка виртуальных таблиц: Хотя мы используем физическую таблицу регистра, иногда полезно предварительно отобрать работающих сотрудников через СрезПоследних, чтобы не перебирать историю тех, кто в данный момент уволен.

Особенности реализации в «Рознице» на обычных формах

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

Итоги и рекомендации

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

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

← На главную