Почему в УПП не сохраняется ТекущееПодразделениеКомпании и как получить актуальные подразделения сотрудников

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

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

Выясним причину очистки реквизита при записи объекта

Проанализируем структуру типового решения УПП 1.3. В конфигурации кадровые данные разделены на два независимых контура:

  1. Регламентированный учет — ведется в разрезе юридических лиц (организаций). Данные фиксируются документами регламентированного кадрового учета (приказы о приеме, переводах, увольнениях) и записываются в периодический регистр сведений РаботникиОрганизаций. Подразделения берутся из справочника ПодразделенияОрганизаций.
  2. Управленческий учет — предназначен для планирования и анализа по компании в целом без привязки к конкретным юридическим лицам. Движения формируются кадровыми документами по компании и попадают в регистр сведений Работники. В этом контуре используется справочник Подразделения.

Реквизиты справочника СотрудникиОрганизаций с префиксами Текущее... (например, ТекущееПодразделениеКомпании, ТекущаяДолжностьКомпании) не являются источником первичных данных. Они представляют собой денормализованные кэширующие поля. Эти реквизиты служат исключительно для ускорения отрисовки списков и динамических форм. При любой стандартной записи элемента или проведении кадровых документов типовые процедуры перезаписывают эти поля актуальными срезами из регистров. Если в базе управленческий кадровый учет отключен или документы по компании не проводятся, система при перезаписи всегда будет принудительно обнулять данные реквизиты. Напрямую редактировать их в форме бессмысленно.

Как получить актуальное подразделение сотрудника через регистры сведений

Разберем по шагам, как выстроить правильную выборку работающих сотрудников с их подразделениями, если учет ведется только по организациям, а отчет требуется построить в структуре управленческих подразделений.

Для сопоставления структуры организации со структурой компании в УПП предусмотрен специальный регистр сведений — СоответствиеПодразделенийИПодразделенийОрганизаций. Актуальное состояние сотрудников на заданную дату хранится в таблице среза последних регистра РаботникиОрганизаций.

Посмотрим на пример запроса, связывающего эти данные:


ВЫБРАТЬ
    РаботникиОрганизацийСрезПоследних.Сотрудник КАК Сотрудник,
    РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации КАК ПодразделениеОрганизации,
    СоответствиеПодразделенийИПодразделенийОрганизаций.Подразделение КАК Подразделение,
    РаботникиОрганизацийСрезПоследних.Период КАК ДатаИзменения
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних(&Период, ) КАК РаботникиОрганизацийСрезПоследних
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СоответствиеПодразделенийИПодразделенийОрганизаций КАК СоответствиеПодразделенийИПодразделенийОрганизаций
        ПО РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации = СоответствиеПодразделенийИПодразделенийОрганизаций.ПодразделениеОрганизации
            И РаботникиОрганизацийСрезПоследних.Организация = СоответствиеПодразделенийИПодразделенийОрганизаций.Организация
ГДЕ
    РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)

Обратим внимание на ключевые моменты построения этого запроса:

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

Почему в результате запроса поле «Подразделение» остается пустым (NULL)

При использовании левого соединения нередко возникает ситуация, когда для части сотрудников поле Подразделение возвращает NULL, хотя регламентированное подразделение заполнено. Проанализируем возможные причины:

  1. Отсутствует запись в регистре сопоставления. Регистр сведений СоответствиеПодразделенийИПодразделенийОрганизаций не заполняется автоматически. Если кадровик создал новое подразделение организации и перевел туда людей, но администратор не указал соответствие управленческому подразделению в этом регистре, связь не сработает. Для выявления таких разрывов полезно регулярно запускать проверку незаполненных соответствий.
  2. Несовпадение организации. Если в регистре соответствия подразделение привязано к одной организации, а сотрудник числится в другой, левое соединение по двум полям также вернет пустое значение.

Построение древовидной структуры подразделений

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

Рассмотрим штатные и эффективные способы вывода древовидной структуры:

  1. Использование итогов запроса по иерархии. В тексте запроса определяем секцию итогов:
    
    ИТОГИ ПО
        Подразделение ИЕРАРХИЯ
    

    При обходе выборки во встроенном языке используем режим иерархического обхода:

    
    Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
    Пока Выборка.Следующий() Цикл
        // Вывод родительских и дочерних узлов в дерево или табличный документ
    КонецЦикла;
    
  2. Выгрузка в объект «ДеревоЗначений». Если данные требуется отобразить в интерфейсе обычной формы, результат запроса можно выгрузить напрямую:
    
    ДеревоДанных = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
    ЭлементыФормы.ДеревоРезультата.СоздатьКолонки();
    
  3. Использование Системы компоновки данных (СКД). При разработке отчета оптимальным решением является СКД. В настройках структуры отчета для группировки по полю Подразделение достаточно установить тип группировки «Иерархия». Платформа самостоятельно построит корректное дерево произвольной глубины вложенности без необходимости ручного программирования рекурсий.
← На главную