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