В современных конфигурациях 1С, таких как 1С:ERP Управление предприятием или 1С:Зарплата и управление персоналом 3.1, структура хранения кадровых данных значительно отличается от старых редакций (например, УПП 1.3 или ЗУП 2.5). Часто возникает задача: найти конкретного сотрудника, зная только его должность. Это может потребоваться для автоматического заполнения печатных форм, табелей или отчетов, особенно когда речь идет о руководителях, чьи должности уникальны, но конкретные люди на этих местах могут меняться.
Разберем подробно, почему стандартный поиск через реквизиты справочника Сотрудники может не сработать и какие механизмы платформы 1С:Предприятие 8.3 следует использовать для решения этой задачи.
Многие разработчики, привыкшие к старым конфигурациям, пытаются найти должность непосредственно в справочнике Сотрудники. Однако в ERP должность является срезовым показателем. Это означает, что она не хранится как простой реквизит, а фиксируется в регистрах сведений на определенную дату. То, что мы видим в форме элемента справочника — это «динамическое» значение, которое подтягивается программно для удобства пользователя.
Посмотрим на основные регистры, где хранятся нужные нам данные:
Проанализируем ситуацию, когда нам нужно найти сотрудника на конкретную дату (например, дату формирования табеля). Самый надежный способ — это обращение к виртуальной таблице СрезПоследних регистра сведений КадроваяИсторияСотрудников.
Рассмотрим пример запроса, который позволяет получить сотрудника по ссылке на должность:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КадроваяИсторияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник,
| КадроваяИсторияСотрудниковСрезПоследних.Сотрудник.ФизическоеЛицо.Наименование КАК ФИО
|ИЗ
| РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&Период, Должность = &НужнаяДолжность) КАК КадроваяИсторияСотрудниковСрезПоследних
|ГДЕ
| КадроваяИсторияСотрудниковСрезПоследних.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)";
Запрос.УстановитьПараметр("Период", ДатаТабеля);
Запрос.УстановитьПараметр("НужнаяДолжность", СсылкаНаДолжность);
РезультатЗапроса = Запрос.Выполнить();
Важный нюанс: при использовании этого метода мы обязательно должны исключать уволенных сотрудников, проверяя ВидСобытия. Также стоит помнить, что если на одной должности числится несколько человек (например, в штатном расписании предусмотрено несколько ставок), запрос вернет список всех подходящих сотрудников.
В 1С:ERP чаще всего ведется штатное расписание. В этом случае должность привязана к Позиции штатного расписания (справочник ШтатноеРасписание). Позиция определяет не только название должности, но и конкретное подразделение. Если нам нужно найти руководителя конкретного отдела, лучше искать через регистр ЗанятыеПозицииШтатногоРасписания.
Разберем, как это работает. Позиция штатного расписания — это уникальный объект. Использование этого объекта в поиске исключает ошибку, когда в разных подразделениях есть должности с одинаковым названием, но нам нужен человек только из одного конкретного отдела.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗанятыеПозиции.Сотрудник
|ИЗ
| РегистрСведений.ЗанятыеПозицииШтатногоРасписания.СрезПоследних(&Дата, Позиция = &ВыбраннаяПозиция) КАК ЗанятыеПозиции";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("ВыбраннаяПозиция", ПозицияШтатки);
Для разработчиков в 1С:ERP и ЗУП 3.1 предусмотрен мощный инструмент — общий модуль КадровыйУчет. Вместо написания сложных запросов к регистрам, мы можем воспользоваться встроенными функциями, которые учитывают все нюансы (совместительство, временные переводы и т.д.).
Рассмотрим метод КадровыйУчет.СотрудникиСДолжностями. Проанализируем пример получения списка работающих сотрудников на определенной должности:
// Параметры: ТолькоРаботающие, Дата, Организация, Должность
ПараметрыПоиска = Новый Структура;
ПараметрыПоиска.Вставить("Организация", СсылкаНаОрганизацию);
ПараметрыПоиска.Вставить("Должность", СсылкаНаДолжность);
ТаблицаСотрудников = КадровыйУчет.СотрудникиСДолжностями(Истина, ТекущаяДата(), СсылкаНаОрганизацию, СсылкаНаДолжность);
Если ТаблицаСотрудников.Количество() > 0 Тогда
// Берем первого найденного, если должность уникальна
НужныйСотрудник = ТаблицаСотрудников[0].Сотрудник;
КонецЕсли;
Этот способ является наиболее правильным с точки зрения архитектуры типовых решений, так как он использует отлаженные механизмы фирмы «1С» для получения кадровых данных.
Выясним причину, по которой иногда советуют использовать регистр ТекущиеКадровыеДанные. Этот регистр предназначен для быстрого получения информации «на сегодня». В нем есть поле ТекущаяДолжность. Однако у него есть существенный недостаток для решения задачи с табелем: он не хранит историю. Если вам нужно узнать, кто занимал должность месяц назад, этот регистр вам не поможет. Его стоит использовать только в оперативных задачах, где важна скорость и актуальность данных именно в текущий момент времени.
Для эффективного решения задачи поиска сотрудника по должности в 1С:ERP следует придерживаться следующего алгоритма:
ТекущиеКадровыеДанные.КадроваяИсторияСотрудников.СрезПоследних.Позиции будет гораздо точнее, чем поиск по текстовому названию или ссылке на общую Должность.КадровыйУчет позволяют сократить объем кода и избежать ошибок при обработке сложных кадровых случаев.Использование правильных регистров и методов гарантирует, что ваша программа будет корректно работать даже при смене сотрудников, совмещении должностей или изменении структуры предприятия.