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