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