Как получить даты начала и окончания отпуска сотрудников в 1С:ЗУП 3.1

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет
← На главную

При разработке отчетов или обработок в конфигурации «Зарплата и управление персоналом 3.1» программисты часто сталкиваются с необходимостью получить не только текущее состояние сотрудника (например, «Отпуск» или «Болезнь»), но и точные даты этого периода. Стандартные программные интерфейсы (API) подсистемы КадровыйУчет, такие как функция СотрудникиОрганизации, позволяют легко извлечь ФИО, должность или подразделение, но не предоставляют информацию о периодах действия текущего состояния в виде готовых полей КадровыеДанные.

В этой статье мы подробно разберем, как эффективно решить эту задачу, избежав типичных ошибок производительности, таких как запросы в цикле, и сохранив возможность гибкой фильтрации сотрудников.

Анализ проблемы и ограничений типового функционала

Рассмотрим ситуацию: нам нужно получить список сотрудников, которые на данный момент находятся в отпуске, с указанием даты начала и даты окончания этого отпуска. Попытка добавить в строку КадровыеДанные параметры вида «ДатаНачала» или «ДатаОкончания» не приведет к успеху, так как состав полей функции КадровыйУчет.СотрудникиОрганизации жестко предопределен внутри кода конфигурации. Проанализируем основные методы решения этой задачи.

Решение 1. Оптимизированный запрос к регистру «Состояния сотрудников»

Самый простой и логичный способ — обратиться к регистру сведений СостоянияСотрудников. Однако главной ошибкой является выполнение запроса к этому регистру внутри цикла по таблице сотрудников. Чтобы сохранить высокую скорость работы, мы должны сначала получить список нужных нам сотрудников, а затем одним запросом извлечь их состояния.

Выясним, как правильно построить такой запрос. Нам потребуются поля Период (начало состояния) и ДействуетДо (окончание состояния). Рассмотрим пример кода:


// 1. Получаем список сотрудников через типовую функцию
ПараметрыПолучения = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛиц();
ПараметрыПолучения.КадровыеДанные = "Сотрудник, Подразделение, Должность";
// Накладываем нужные отборы (например, по организации)
ПараметрыПолучения.Отборы.Организация = Объект.Организация;

ТаблицаСотрудников = КадровыйУчет.СотрудникиОрганизации(Истина, ПараметрыПолучения);

// 2. Выгружаем ссылки на сотрудников для запроса
МассивСотрудников = ТаблицаСотрудников.ВыгрузитьКолонку("Сотрудник");

// 3. Получаем данные состояний одним запросом
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СостоянияСотрудников.Сотрудник КАК Сотрудник,
    |	СостоянияСотрудников.Состояние КАК Состояние,
    |	СостоянияСотрудников.Период КАК ДатаНачала,
    |	СостоянияСотрудников.ДействуетДо КАК ДатаОкончания
    |ИЗ
    |	РегистрСведений.СостоянияСотрудников КАК СостоянияСотрудников
    |ГДЕ
    |	СостоянияСотрудников.Сотрудник В(&МассивСотрудников)
    |	И СостоянияСотрудников.Период <= &ПериодПроверки
    |	И (СостоянияСотрудников.ДействуетДо >= &ПериодПроверки 
    |		ИЛИ СостоянияСотрудников.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1))";

Запрос.УстановитьПараметр("МассивСотрудников", МассивСотрудников);
Запрос.УстановитьПараметр("ПериодПроверки", ТекущаяДата());

РезультатЗапроса = Запрос.Выполнить().Выгрузить();

В данном примере мы используем условие на ДействуетДо, чтобы найти запись, актуальную на текущий момент. Обратите внимание на проверку пустой даты ДАТАВРЕМЯ(1, 1, 1) — это важно для бессрочных состояний (например, работа в штате).

Решение 2. Использование временных таблиц кадрового учета

Более продвинутый способ, который рекомендуют эксперты, заключается в использовании механизма временных таблиц (ВТ), который предоставляет модуль КадровыйУчет. Это позволяет объединить мощь типовых фильтров ЗУП и гибкость собственных запросов. Разберем этот алгоритм по шагам.

Воспользуемся функцией СоздатьНаДатуВТКадровыеДанныеСотрудников. Этот метод создает в менеджере временных таблиц (МВТ) таблицу, содержащую все основные сведения. Затем мы сможем соединить её с регистром состояний прямо в базе данных, не выгружая данные в память клиента.

Проанализируем пример реализации:


МенеджерВТ = Новый МенеджерВременных Таблиц;

// Формируем описание полей, которые нам нужны от типового механизма
КадровыеДанные = "Сотрудник,Подразделение,Организация";

// Создаем ВТ с сотрудниками
КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников(МенеджерВТ, Истина, ТекущаяДата(), , КадровыеДанные);

// Пишем запрос, который соединяет типовую ВТ и регистр состояний
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВТКадровыеДанные.Сотрудник КАК Сотрудник,
    |	ВТКадровыеДанные.Подразделение КАК Подразделение,
    |	Состояния.Состояние КАК Состояние,
    |	Состояния.Период КАК НачалоОтпуска,
    |	Состояния.ДействуетДо КАК КонецОтпуска
    |ИЗ
    |	ВТКадровыеДанныеСотрудников КАК ВТКадровыеДанные
    |		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСотрудников КАК Состояния
    |		ПО ВТКадровыеДанные.Сотрудник = Состояния.Сотрудник
    |ГДЕ
    |	Состояния.Период <= &Сегодня
    |	И (Состояния.ДействуетДо >= &Сегодня ИЛИ Состояния.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1))
    |	И Состояния.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияСотрудника.Отпуск)";

Запрос.УстановитьПараметр("Сегодня", НачалоДня(ТекущаяДата()));

Результат = Запрос.Выполнить().Выгрузить();

Этот подход является наиболее эффективным, так как фильтрация сотрудников по подразделению или организации происходит внутри типового механизма формирования ВТКадровыеДанныеСотрудников, а получение дат — с помощью быстрого соединения таблиц на стороне СУБД. Для отладки и проверки таких конструкций с вызовом API конфигурации подойдёт консоль запросов с поддержкой методов программного интерфейса ЗУП.

Важные нюансы работы с данными отпусков

При работе с состояниями в ЗУП 3.1 следует учитывать несколько технических особенностей:

  1. Исправления документов: В системе могут существовать документы-исправления. Чтобы получить корректные данные, иногда стоит обращаться не к основному регистру, а использовать программный интерфейс СостоянияСотрудников.СостоянияСотрудников(Параметры), который умеет обрабатывать исправления и вытеснения состояний автоматически.
  2. Виды отпусков: Если вам нужно различать основной, дополнительный отпуск или отпуск за свой счет, информация об этом хранится не в СостоянияСотрудников, а в кадровых приказах или специализированных регистрах накопления, таких как ДанныеОперативногоУчетаРабочегоВремениСотрудников.
  3. Будущие периоды: Если ваша задача — получить не текущий, а «предстоящий» отпуск, условие в запросе Период <= &Сегодня нужно убрать и добавить фильтр по дате начала в будущем.

Использование СКД для динамических отборов

Если ваша цель — предоставить пользователю возможность самостоятельно выбирать, по каким полям фильтровать (например, «показать всех, у кого отпуск заканчивается на следующей неделе»), лучше всего использовать Систему компоновки данных (СКД). Мы можем создать схему, где в качестве набора данных будет выступать запрос к СостоянияСотрудников и справочнику Сотрудники. СКД автоматически построит оптимальный запрос с учетом всех пользовательских фильтров, что избавит разработчика от необходимости вручную прописывать условия ГДЕ в коде. При необходимости получить готовую форму без собственной разработки схемы подойдёт обобщенный отчет по отпускам сотрудников для ЗУП 3.1.

Подведем итог: для получения дат отпуска по каждому сотруднику не следует использовать только функцию КадровыйУчет.СотрудникиОрганизации. Правильный путь — это получение списка ссылок на сотрудников с помощью типовых средств и последующее соединение этого списка с регистром СостоянияСотрудников через запрос или временные таблицы. Это обеспечит максимальную производительность и корректность данных.

← На главную