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