В практике разработчика 1С часто встречается ситуация, когда данные в информационную базу попадают из внешних систем или ведутся с особенностями, не предполагающими создание нового элемента справочника Сотрудники при каждом повторном приеме. В таких случаях в регистре сведений Работники (или аналогичных) накапливается история: прием, перемещения, увольнение и снова прием на тот же элемент справочника. Перед нами стоит задача: получить дату именно последнего приема на работу, игнорируя все предыдущие «трудовые жизни» сотрудника, и сделать это желательно одним эффективным запросом.
Рассмотрим подробно, как реализовать этот алгоритм, проанализируем структуру запроса и разберем технические нюансы, которые помогут избежать ошибок при работе с большими объемами данных.
В конфигурациях на обычных формах (например, в старых редакциях «1С:Розница») сведения о кадровых изменениях обычно хранятся в периодическом регистре сведений. Ключевыми реквизитами для нас являются Период, Сотрудник и Ставка. Логика системы такова:
Ставка > 0 — это событие приема на работу или кадрового перемещения.Ставка = 0 — это событие увольнения.Сложность заключается в том, что обычный срез первых даст нам самую первую дату приема в истории, а срез последних — дату последнего изменения (которая может быть перемещением, а не приемом). Нам же нужно найти «точку отсчета» последнего цикла работы.
Первым делом нам необходимо выяснить, увольнялся ли сотрудник ранее, и если да, то когда это произошло в последний раз. Для этого мы воспользуемся механизмом временных таблиц в запросе. Проанализируем ситуацию: если у сотрудника было несколько увольнений, нас интересует только самое позднее из них.
Рассмотрим структуру первого запроса в пакете:
ВЫБРАТЬ
Работники.Сотрудник КАК Сотрудник,
МАКСИМУМ(Работники.Период) КАК ДатаПоследнегоУвольнения
ПОМЕСТИТЬ ВТ_ПоследниеУвольнения
ИЗ
РегистрСведений.Работники КАК Работники
ГДЕ
Работники.Ставка = 0
СГРУППИРОВАТЬ ПО
Работники.Сотрудник
;
В эту таблицу попадут только те люди, у которых в истории есть хотя бы одна запись с нулевой ставкой. Те, кто работает с момента первого приема и ни разу не увольнялся, в эту таблицу не попадут, и это важно учитывать на следующем этапе.
Теперь, когда у нас есть «точки отсечки» для увольнявшихся сотрудников, нам нужно соединить основную таблицу регистра с нашей временной таблицей. Основная идея заключается в том, чтобы найти минимальную дату записи с положительной ставкой, которая строго больше даты последнего увольнения.
Разберем, как объединить данные для работающих без увольнений и для тех, кто вернулся в компанию. Посмотрим на пример реализации финального запроса:
ВЫБРАТЬ
Работники.Сотрудник КАК Сотрудник,
МИНИМУМ(Работники.Период) КАК ДатаПриема
ИЗ
РегистрСведений.Работники КАК Работники
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПоследниеУвольнения КАК ВТ_Увольнения
ПО Работники.Сотрудник = ВТ_Увольнения.Сотрудник
ГДЕ
Работники.Ставка > 0
И (Работники.Период > ВТ_Увольнения.ДатаПоследнегоУвольнения
ИЛИ ВТ_Увольнения.ДатаПоследнегоУвольнения ЕСТЬ NULL)
СГРУППИРОВАТЬ ПО
Работники.Сотрудник
Проанализируем условие в секции ГДЕ. Здесь мы используем ЕСТЬ NULL для обработки сотрудников, которых нет в таблице увольнений. Для них ограничение по дате не действует, и запрос просто найдет самую раннюю запись о приеме. Для остальных же будут рассматриваться только записи, идущие после последнего увольнения.
При работе с регистрами сведений, объем которых может исчисляться сотнями тысяч записей, критически важно следить за производительностью. Выясним, как ускорить выполнение нашего запроса:
Сотрудник во временной таблице ВТ_ПоследниеУвольнения. Это значительно ускорит операцию соединения.СрезПоследних, чтобы не перебирать историю тех, кто в данный момент уволен.Посмотрим на специфику конфигурации, упомянутой в обсуждении. В старых версиях «Розницы» часто встречается упрощенный кадровый учет. Важно помнить:
Работники могут вноситься не только документами приема, но и ручными операциями или при обмене данными. Всегда проверяйте реквизит Ставка.Организация в условия соединения и группировки, иначе данные по сотруднику «смешаются», если он переходил из одного юрлица в другое в рамках одной базы.ЕСТЬNULL(Ставка, 0), если существует риск появления пустых значений в поле ставки при некорректном обмене данными.Мы разобрали универсальный способ получения даты актуального приема на работу одним запросом. Этот метод надежнее, чем просто поиск максимальной даты, так как он позволяет игнорировать последующие кадровые перемещения и фокусируется именно на начале трудового договора.
Важный момент: Если методология учета в компании позволяет, лучше следовать совету опытных коллег — заводить нового сотрудника в справочнике при повторном приеме. Это избавит от необходимости писать сложные запросы и обеспечит чистоту аналитики. Однако, если вы работаете с «грязными» историческими данными или данными из внешних систем, описанный выше метод с использованием временной таблицы последних увольнений является наиболее технически грамотным и производительным решением в экосистеме 1С:Предприятие 8.