В системе 1С:Зарплата и управление персоналом 3.1 (ЗУП) часто возникает необходимость получить список актуальных сотрудников не через стандартные отчеты, а средствами программирования. Это требуется при разработке собственных печатных форм, сложных регламентных заданий или внешних обработок интеграции. Главная сложность заключается в том, что понятие «работающий сотрудник» в конфигурации не хранится в одном единственном поле, а вычисляется динамически на основе даты.
Для корректной выборки данных разработчику необходимо понимать архитектуру хранения кадровых данных. Информация разбросана по нескольким объектам: справочнику ФизическиеЛица, регистру сведений КадровыеДанныеФизическихЛиц и планируемому начислению. Ошибки в логике выборки часто приводят к тому, что в выборку попадают уволенные работники или, наоборот, теряются сотрудники, принятые текущим днем.
В этой статье мы детально разберем алгоритм построения запроса, который гарантированно вернет список лиц, состоящих в трудовых отношениях с организацией на конкретную дату. Мы рассмотрим нюансы работы с периодами действия записей регистров и особенности фильтрации по состоянию приема на работу.
Архитектура хранения кадровых данных
Прежде чем писать код, важно осознать, где именно в базе данных 1С живет информация о факте работы. В конфигурации ЗУП 3.1 основным объектом для хранения сведений о приеме, переводах и увольнениях является регистр сведений КадровыеДанныеФизическихЛиц. Именно здесь фиксируется состояние сотрудника в каждый момент времени.
Каждая запись в этом регистре имеет период действия, определяемый полями ПериодРегистрации и ссылкой на документ-основание. Состояние приема («Принят», «Уволен», «В отпуске») хранится в отдельном измерении или реквизите, в зависимости от конкретной версии релиза платформы и конфигурации. Однако ключевым признаком активного сотрудника является отсутствие записи об увольнении с датой, меньшей или равной интересующей нас дате.
Не стоит путать справочник Сотрудники и справочник ФизическиеЛица. Первый является регистром сведений о работе в конкретной организации, а второй — универсальным справочником людей. Для получения списка работающих нам нужно оперировать данными, привязанными к организации, то есть использовать измерения регистра, связанные с организацией.
⚠️ Внимание: В новых релизах ЗУП 3.1 структура регистра КадровыеДанныеФизическихЛиц может изменяться. Всегда проверяйте наличие реквизита «Состояние» или аналогичного флага в вашей конкретной версии конфигурации перед написанием жестко закодированных условий.
Логика выборки по состоянию приема
Самый надежный способ отфильтровать работающих — это анализ последнего кадрового события. Логика проста: если последнее событие по сотруднику до отчетной даты — это «Прием» или «Перевод», и не было события «Увольнение», значит, сотрудник работает. Однако писать такую логику через вложенные запросы сложно и непроизводительно.
В ЗУП 3.1 существует более элегантное решение — использование виртуальной таблицы или специального среза последних регистраций. Запрос к регистру сведений позволяет получить срез последних записей на дату с помощью ключевого слова КАК ПЕРИОД или функции ПОСЛЕДНИЕ. Это позволяет мгновенно получить состояние дел на любую дату в прошлом или будущем.
При формировании условия отбора критически важно правильно задать границы периода. Если вам нужны сотрудники на 31 декабря, вы должны выбрать записи, у которых ПериодРегистрации меньше или равен этой дате, и среди них взять самые свежие. В языке запросов 1С это делается конструкцией ВЫБРАТЬ.. ИЗ КадровыеДанныеФизическихЛиц.СрезПоследних.
Используйте виртуальную таблицу СрезПоследних для получения актуального состояния сотрудника на любую дату. Это избавит от необходимости вручную искать максимальную дату регистрации в подзапросе.
Фильтрация по состоянию приема осуществляется через поле СостояниеФизическогоЛица (или аналогичное наименование в вашей базе). Значение, соответствующее активному трудовому договору, обычно помечается перечислением СостоянияФизическихЛиц.Принят. Убедитесь, что вы не отфильтровываете сотрудников, находящихся в декрете или длительном отпуске, если ваша задача — получить весь списочный состав.
Формирование запроса к регистру сведений
Рассмотрим практическую реализацию выборки. Основой нашего кода будет объект Запрос. Мы будем обращаться к виртуальной таблице среза последних записей регистра КадровыеДанныеФизическихЛиц. Это обеспечит высокую производительность даже на больших базах данных с тысячами сотрудников.
В тексте запроса необходимо указать параметры организации и даты среза. Организация является обязательным измерением регистра, без нее выборка вернет данные по всем фирмам в базе, что может привести к дублированию физических лиц. Дата среза передается параметром, чтобы один и тот же код можно было использовать для разных отчетных периодов.
ЗапросТекст = "ВЫБРАТЬ
| КадровыеДанныеФизическихЛицСрезПоследних.Сотрудник КАК Сотрудник,
| КадровыеДанныеФизическихЛицСрезПоследних.ФизическоеЛицо КАК ФизическоеЛицо,
| КадровыеДанныеФизическихЛицСрезПоследних.ПодразделениеОрганизации КАК Подразделение
|ИЗ
| РегистрСведений.КадровыеДанныеФизическихЛиц.СрезПоследних(&ДатаСреза, (Сотрудник.Организация = &Организация)) КАК КадровыеДанныеФизическихЛицСрезПоследних
|ГДЕ
| КадровыеДанныеФизическихЛицСрезПоследних.СостояниеФизическогоЛица = &СостояниеПринят";
Обратите внимание на использование параметра &СостояниеПринят. В коде 1С ему должно быть присвоено значение из перечисления Перечисления.СостоянияФизическихЛиц.Принят перед выполнением запроса. Это делает код гибким и понятным для чтения, в отличие от использования магических чисел или строк.
☑️ Проверка корректности запроса
После выполнения запроса результат помещается в временную таблицу или сразу обрабатывается в цикле. Это позволяет избежать проблем с полными тезками.
Обработка результатов выборки в коде
Полученный набор данных ВыборкаИзРезультатаЗапроса необходимо правильно обработать. В зависимости от задачи, вы можете формировать список значений, заполнять табличную часть документа или передавать данные во внешнюю систему. При работе с большими объемами данных рекомендуется использовать буферизацию.
Частая ошибка разработчиков — попытка получить дополнительные реквизиты (например, табельный номер или дату рождения) напрямую из регистра кадровых данных. Этих полей там нет. Их нужно добирать(join) из связанных справочников Сотрудники и ФизическиеЛица либо выполнять отдельный запрос по полученному списку ссылок.
Для оптимизации производительности лучше сразу включить нужные поля в основной запрос, используя соединения ЛЕВОЕ СОЕДИНЕНИЕ. Это позволит получить все необходимые данные (ФИО, ИНН, СНИЛС) одним обращением к базе данных, что критически важно для быстродействия в «толстом» клиенте или при работе через COM-соединение.
⚠️ Внимание: Если вы планируете выгружать данные во внешние системы, убедитесь, что GUID ссылок на физические лица корректно преобразуются. В некоторых случаях требуется выгрузка по уникальным идентификаторам (ИНН/СНИЛС), а не по внутренним ссылкам 1С.
Пример цикла обработки может выглядеть следующим образом:
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить("Сотрудник: " + Выборка.ФизическоеЛицо);
// Дальнейшая логика обработки
КонецЦикла;
Такой подход обеспечивает последовательную обработку каждого сотрудника. Если требуется пакетная обработка (например, массовое создание заявок), данные из выборки лучше сначала скопировать в таблицу значений, а затем работать с ней в памяти, не обращаясь к базе данных лишний раз.
Учет увольнений и кадровых перемещений
Одной из самых коварных ситуаций является обработка сотрудников, которые были уволены и приняты снова в течение одного отчетного периода. Простая фильтрация по дате увольнения может дать сбой, если не учитывать историю изменений. Регистр КадровыеДанныеФизическихЛиц хранит всю историю, поэтому срез последних записей автоматически учитывает повторные приемы.
Если сотрудник был переведен в другое подразделение, в срезе последних записей будет актуальное подразделение. Это важно для отчетов по центрам финансовой ответственности. Однако, если вам нужно знать историю перемещений за период, срез последних записей не подойдет — потребуется анализ всего регистра за период.
Отдельного внимания заслуживают сотрудники, находящиеся в отпуске без сохранения заработной платы или в декрете. С точки зрения регистра кадровых данных, их состояние может отличаться от состояния «Принят». В зависимости от бизнес-задачи, вам может потребоваться расширить условие ГДЕ, добавив туда другие допустимые состояния через оператор ИЛИ.
Нюансы отпуска по уходу за ребенком
Сотрудники в отпуске по уходу за ребенком формально числятся в штате, но их состояние в некоторых конфигурациях может помечаться специальным флагом. Если такие сотрудники не попадают в вашу выборку, проверьте справочник "Состояния физических лиц" и добавьте нужные значения в условие отбора запроса.
Также стоит учитывать внешние совместителей. Они часто проводятся отдельными документами и могут иметь свои особенности в заполнении регистра. Убедитесь, что ваш запрос не фильтрует их по признаку вида занятости, если они должны входить в общий список работающих.
Типичные ошибки и способы их устранения
При разработке кода выборки работающих сотрудников новички часто сталкиваются с рядом типовых проблем. Самая распространенная из них — получение дублей. Это происходит, если в запросе некорректно указаны группировки или если один сотрудник работает в нескольких подразделениях (что возможно в некоторых настройках ЗУП).
Вторая частая ошибка — игнорирование параметра организации. В многофирменных базах без явного указания организации в условии ГДЕ или в параметрах виртуальной таблицы, вы получите объединенный список сотрудников всех фирм. Это приведет к ошибкам при попытке обратиться к реквизитам, специфичным для конкретной организации.
Третья проблема связана с правами доступа (RLS). Если у пользователя, от имени которого запускается код, ограничены права на чтение кадровых данных, запрос вернет пустой результат или усеченный список. В таких случаях необходимо использовать выполнение запроса от имени администратора или явно проверять права перед запуском.
| Ошибка | Причина | Решение |
|---|---|---|
| Дубликаты сотрудников | Отсутствие группировки или связь 1:М | Использовать РАЗЛИЧНЫЕ или группировку по сотруднику |
| Пустой результат | Неверная дата среза или RLS | Проверить дату и права доступа пользователя |
| Попадают уволенные | Неверное условие по состоянию | Проверить значение перечисления СостоянияФизическихЛиц |
| Ошибка выполнения | Неверное имя поля в запросе | Сверить имена полей с конфигурацией через Конфигуратор |
Использование виртуальной таблицы СрезПоследних с параметром организации — это стандарт де-факто для получения актуального списка сотрудников в ЗУП 3.1. Избегайте ручного перебора документов приема и увольнения.
Для отладки запросов удобно использовать консоль запросов. Скопируйте текст запроса из кода, подставьте реальные значения параметров и выполните его в консоли. Это позволит быстро увидеть структуру возвращаемых данных и убедиться в корректности условий отбора без необходимости компиляции модуля.
Часто задаваемые вопросы (FAQ)
Как получить список сотрудников, которые уволились в конкретном месяце?
Для этой задачи срез последних записей не подойдет, так как он показывает текущее состояние. Вам нужно сделать запрос к самому регистру сведений КадровыеДанныеФизическихЛиц (не к срезу) с условием на период регистрации и состоянием «Уволен». Пример условия: ГДЕ ПериодРегистрации МЕЖДУ &НачалоМесяца И &КонецМесяца И Состояние = &Уволен.
Почему в выборке нет сотрудников, принятых сегодня?
Проверьте время среза. Если вы используете дату «Сегодня», а прием оформлен документом с временем, большим чем время выполнения запроса (или если срез берется по состоянию на начало дня), такие сотрудники могут не попасть в выборку. Используйте параметр даты с точностью до секунды или берите срез на «КонецДня».
Можно ли использовать этот метод в внешней обработке?
Да, можно. При подключении к базе 1С из внешней обработки (например, через COM или файловый вариант) логика запросов остается неизменной. Единственное отличие — вам нужно корректно передать параметры типа «Организация» (ссылка) и «Дата» во встроенном языке внешней программы перед выполнением запроса.
Как учесть сотрудников, которые работают по договорам ГПХ?
Сотрудники по договорам ГПХ (гражданско-правового характера) обычно не имеют записи в регистре КадровыеДанныеФизическихЛиц со статусом «Принят», так как они не являются штатными сотрудниками. Для их получения нужно делать отдельный запрос к регистру накопления НачисленияДоходовФизическихЛиц или к документу Договор с физическим лицом, фильтруя по виду договора.