При разработке отчетов или алгоритмов расчета в конфигурации 1С:Зарплата и управление персоналом 3.1 программисты часто сталкиваются с необходимостью фильтровать список физических лиц. Самая распространенная и коварная ошибка — попытка отфильтровать сотрудников по реквизиту "Уволен" или дате увольнения в справочнике "Сотрудники". В современной архитектуре платформы 1С:Предприятие 8.3 такой подход некорректен, так как статус работы определяется не прямой ссылкой на справочник, а наличием действующих кадровых документов в регистре сведений.
Чтобы получить достоверный список персонала на конкретную дату, необходимо обращаться к регистру сведений Кадровые назначения. Именно он хранит историю перемещений, приемов и увольнений. Запрос должен учитывать временные срезы, чтобы игнорировать будущие приемы и учитывать уже состоявшиеся увольнения. В этой статье мы детально разберем синтаксис запроса, особенности использования временных срезов и нюансы работы с производственными календарями для точного определения статуса занятости.
Почему нельзя использовать поле "Уволен" напрямую
В справочнике Справочник.Сотрудники существует реквизит ДатаУвольнения, однако полагаться на него в прямом запросе опасно. В конфигурации ЗУП 3.1 состояние сотрудника является производным от его кадрового назначения. Сотрудник может иметь дату увольнения в карточке, но если документ увольнения еще не проведен или помечен на удаление, он фактически продолжает числиться в штате.
Более того, существуют ситуации, когда кадровое назначение закрыто, но сотрудник переведен в другое подразделение или изменил должность без разрыва трудового стажа. Прямая фильтрация по дате увольнения в таком случае исключит таких работников из выборки, что приведет к ошибкам в расчетах. Важно понимать, что истинным индикатором занятости является запись в регистре Кадровые назначения с установленным флагом активности на конкретный момент времени.
⚠️ Внимание: Никогда не используйте условие Где Справочник.Сотрудники.Уволен = Ложь для серьезных расчетов. Этот реквизит обновляется механизмами проведения документов и может быть неактуален в момент выполнения запроса, если транзакция еще не зафиксировала изменения.
Для корректной работы вам необходимо строить запрос, опирающийся на регистры сведений. Это гарантирует, что вы увидите картину именно так, как ее "видит" сама система 1С в момент проведения расчетов зарплаты или формирования отчетов.
Основной запрос к регистру Кадровые назначения
Фундаментом для получения списка работающих является таблица регистра сведений РегистрСведений.КадровыеНазначения. Этот регистр является периодическим и подчиненным регистратору, что позволяет использовать мощный механизм временных срезов платформы. Чтобы выбрать сотрудников, которые числились в организации на конкретную дату, мы используем конструкцию КАК ПЕРИОД.
ВЫБРАТЬ
КадровыеНазначения.Сотрудник КАК Сотрудник,
КадровыеНазначения.Подразделение КАК Подразделение,
КадровыеНазначения.Должность КАК Должность
ИЗ
РегистрСведений.КадровыеНазначения КАК КадровыеНазначения
ГДЕ
КадровыеНазначения.Активность = ИСТИНА
И КадровыеНазначения.Период МЕЖДУ &НачалоПериода И &КонецПериода
В данном примере мы выбираем только активные записи. Однако для получения среза "на дату" лучше использовать явное указание периода в начале запроса. Это позволяет движку 1С оптимизировать выборку и вернуть только те записи, которые действовали в указанный промежуток. Поле Активность играет ключевую роль: оно автоматически становится Ложь, когда фиксируется увольнение или перевод.
Если вам нужно получить список именно на конкретное число, например, на 31 декабря, используйте виртуальную таблицу с указанием периода. Это наиболее производительный способ работы с историческими данными в 1С:ЗУП 3.1.
Используйте конструктор запросов для формирования среза: нажмите кнопку "Период" и выберите "Период с.. по..", это автоматически добавит нужные условия в текст запроса.
Использование временных срезов и параметра ПЕРИОД
Самый надежный способ отфильтровать работающих — это использование ключевого слова ПЕРИОД в секции ИЗ. Синтаксис требует указания даты, на которую нам нужна обновляемые материалы. Система сама определит, какие записи были активны в этот момент, игнорируя те, что начались позже или закончились раньше.
Рассмотрим пример запроса, где мы явно задаем срез по состоянию на дату:
ВЫБРАТЬ
КадровыеНазначения.Сотрудник
ИЗ
РегистрСведений.КадровыеНазначения(
НачалоПериода = &ДатаНач,
КонецПериода = &ДатаКон
) КАК КадровыеНазначения
ГДЕ
КадровыеНазначения.Активность = ИСТИНА
Здесь параметры &ДатаНач и &ДатаКон могут быть установлены в одно и то же значение, если нужен срез на конкретный день. Важно отметить, что если сотрудник был принят 1-го числа, а уволен 30-го, то при запросе периода с 1-го по 30-е он попадет в выборку. Но если запросить срез только на 31-е число, запись с флагом Активность уже не вернется, так как на этот момент назначение закрыто.
⚠️ Внимание: При работе с временными срезами помните о часовых поясах, если ваша база работает в распределенной среде. Дата среза должна соответствовать локальному времени сервера базы данных для избежания расхождений в один день.
Такой подход гарантирует, что вы не захватите сотрудников, которые будут приняты в будущем (например, документы введены заранее), и исключите тех, кто уже уволен.
☑️ Проверка корректности среза
Учет графиков работы и производственного календаря
Иногда понятию "работающий" придают более узкий смысл: сотрудник, который не только числится в штате, но и имеет установленный график работы на текущую дату. В 1С:ЗУП 3.1 за это отвечает регистр сведений РегистрСведений.ГрафикиРаботыСотрудников. Сотрудник может быть активен в кадровом назначении, но находиться в отпуске без сохранения зарплаты или иметь график, где конкретный день является выходным.
Для фильтрации таких случаев необходимо соединять таблицу кадровых назначений с таблицей графиков. Это позволяет отсеять тех, кто формально числится, но фактически не должен выходить на работу в выбранный период.
| Тип сотрудника | Кадровое назначение | График работы | Статус в выборке |
|---|---|---|---|
| Активный работник | Действует | Пятидневка | Включить |
| В отпуске без содержания | Действует | Не установлен | Исключить |
| Уволен | Не активно | Любой | Исключить |
| Внешний совместитель | Действует | Почасовой | Включить |
При формировании отчета о явках или табеля учета рабочего времени такая детализация критически важна. Вы можете проверить наличие записи в регистре графиков, где дата входит в период действия графика.
Если график не найден, это может означать, что сотруднику еще не назначен режим работы, что является ошибкой кадрового делопроизводства. В таком случае логика запроса может предусматривать либо исключение таких записей, либо вывод их в отдельную группу "Требует внимания".
Нюансы неполного рабочего времени
Если сотрудник переведен на неполное рабочее время, его запись в регистре графиков остается активной, но меняется количество часов. Запрос по факту наличия графика все равно вернет такого сотрудника как работающего.
Фильтрация по видам занятости и внешним совместителям
В конфигурации ЗУП 3.1 существует понятие вида занятости: основные сотрудники, внутренние и внешние совместители. Часто возникает задача выбрать только основной персонал, исключив совместителей, или наоборот. Эта информация хранится непосредственно в записи регистра Кадровые назначения в поле ВидЗанятости.
Для фильтрации достаточно добавить условие в секцию ГДЕ. Например, чтобы выбрать только основных работников, используется условие:
И КадровыеНазначения.ВидЗанятости = ЗначениеПеречисления.ВидыЗанятости.ОсновноеМесто
Это позволяет гибко настраивать отчеты для разных подразделений. Например, для расчета премий основному штату могут применяться одни коэффициенты, а для совместителей — другие. Разделение на этапе формирования выборки данных упрощает дальнейшую логику обработки.
⚠️ Внимание: Поле "Вид занятости" может измениться в ходе карьеры сотрудника (например, внешний совместитель стал основным). Всегда используйте срез на дату, чтобы получить актуальный статус на момент расчета, а не текущее значение из карточки.
Также стоит учитывать, что у одного физического лица может быть несколько кадровых назначений в одной организации (например, основная должность и внутреннее совместительство). В таком случае запрос вернет несколько строк на одного сотрудника. Для получения уникального списка используйте оператор СГРУППИРОВАТЬ ПО или агрегатные функции.
Оптимизация производительности запросов
При работе с большими базами данных, где история кадровых перемещений насчитывает сотни тысяч записей, производительность запроса становится критическим фактором. Неправильно составленный запрос к регистру Кадровые назначения может привести к полному сканированию таблицы и зависанию системы.
Главное правило оптимизации — всегда ограничивать период выборки. Даже если вам нужны "все работающие", задавайте разумный диапазон, например, текущий месяц или квартал. Использование поля Период в условии ГДЕ задействует индексы по дате, что значительно ускоряет поиск.
Избегайте использования функций в условиях соединения или фильтрации по полям, участвующим в индексах. Например, конструкция ГОД(Период) = 2023 отключит использование индекса по дате. Лучше использовать диапазон: Период МЕЖДУ '20230101' И '20231231'.
Использование временных срезов (ПЕРИОД) не только упрощает логику кода, но и заставляет движок 1С использовать оптимальные планы выполнения запросов, так как это стандартный паттерн работы с периодическими регистрами.
Дополнительно рекомендуется проверять план выполнения запроса через консоль запросов или режим отладки. Если вы видите операцию "Полное сканирование" (Table Scan) на большой таблице регистра, значит, условия выборки составлены неэффективно и требуют пересмотра.
Часто задаваемые вопросы (FAQ)
Как выбрать сотрудников, которые работают в конкретном подразделении на дату?
Необходимо добавить условие в секцию ГДЕ к вашему запросу по регистру Кадровые назначения: И КадровыеНазначения.Подразделение = &НужноеПодразделение. Убедитесь, что используется срез по периоду, чтобы учесть историю переводов между отделами.
Почему в выборку попадают уволенные сотрудники?
Скорее всего, вы не используете временной срез или не проверяете флаг Активность. Если запрос берется без указания периода, 1С возвращает все записи, включая архивные. Всегда используйте конструкцию РегистрСведений.. (НачалоПериода =.., КонецПериода =..).
Можно ли использовать запрос к справочнику Сотрудники для проверки?
Технически можно проверить поле ДатаУвольнения, но это ненадежно. В ЗУП 3.1 статус определяется документами. Сотрудник может быть уволен в базе, но если документ не проведен, запрос к регистру покажет его как работающего, что является правильным поведением системы до момента фиксации документа.
Как учесть сотрудников, находящихся в длительном отпуске?
Сотрудники в отпуске остаются работающими с точки зрения кадрового учета. Они сохраняют запись в регистре Кадровые назначения с флагом Активность = Истина. Если нужно исключить их, необходимо делать дополнительное соединение с регистром Отсутствия и фильтровать по типу отсутствия.