Как получить все должности физического лица во всех организациях в 1С:ЗУП 3.1

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

При разработке в конфигурации 1С:Зарплата и управление персоналом 3.1 программисты часто сталкиваются с архитектурной особенностью: одно физическое лицо может иметь несколько рабочих мест. Это может быть работа в разных организациях (если база многофирменная), внутреннее или внешнее совместительство. В таких случаях простого обращения к справочнику Сотрудники недостаточно, так как нужно собрать актуальный срез данных по всем позициям человека.

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

Понимание архитектуры данных: Физические лица vs Сотрудники

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

Способ 1: Использование программного интерфейса модуля КадровыйУчет

Это самый «чистый» и рекомендуемый способ, так как он использует штатный программный интерфейс (API) конфигурации. Разберем по шагам, как получить массив сотрудников и их должности.

Для начала воспользуемся функцией КадровыйУчет.СотрудникиФизическихЛиц. Она позволяет получить список всех сотрудников человека, учитывая различные условия (дата, организация, архивность). Рассмотрим пример кода:


// Определяем физическое лицо, по которому ищем данные
ФизикСсылка = Справочники.ФизическиеЛица.НайтиПоНаименованию("Иванов Иван Иванович");

// Получаем массив всех сотрудников этого физлица на текущую дату
// Параметры: ФизическиеЛица, ВключатьУволенных, ДатаАктуальности, Организация
МассивСотрудников = КадровыйУчет.СотрудникиФизическихЛиц(ФизикСсылка, Ложь, ТекущаяДата());

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


// Формируем список необходимых полей через запятую
НужныеПоля = "Организация,Подразделение,Должность,ВидЗанятости,ТабельныйНомер";

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

// Перебираем результат
Для Каждого СтрокаДанных Из ТаблицаДолжностей Цикл
    Сообщить("Организация: " + СтрокаДанных.Организация + 
             ", Должность: " + СтрокаДанных.Должность + 
             ", Тип: " + СтрокаДанных.ВидЗанятости);
КонецЦикла;

Важный нюанс: метод КадровыеДанныеСотрудников очень эффективен, так как он внутри себя оптимизирован для работы с большими объемами данных и учитывает права доступа пользователя (RLS).

Способ 2: Оптимизированный запрос к регистру ТекущиеКадровыеДанныеСотрудников

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

Рассмотрим ситуацию, когда нам нужно получить данные сразу по списку физических лиц одним запросом. Выясним причину, почему этот регистр удобен: он содержит уже «схлопнутую» информацию на текущий момент, избавляя нас от необходимости соединяться с интервальными регистрами и рассчитывать срезы последних.


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТекущиеКадровыеДанные.Сотрудник КАК Сотрудник,
    |	ТекущиеКадровыеДанные.Организация КАК Организация,
    |	ТекущиеКадровыеДанные.Подразделение КАК Подразделение,
    |	ТекущиеКадровыеДанные.Должность КАК Должность,
    |	ТекущиеКадровыеДанные.ТекущийВидЗанятости КАК ВидЗанятости
    |ИЗ
    |	РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанные
    |ГДЕ
    |	ТекущиеКадровыеДанные.ФизическоеЛицо В(&СписокФизЛиц)
    |	И ТекущиеКадровыеДанные.ВАрхиве = ЛОЖЬ";

Запрос.УстановитьПараметр("СписокФизЛиц", МассивФизЛиц);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();

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

Способ 3: Работа с интервальными регистрами для исторических данных

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

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	КадроваяИстория.Сотрудник,
    |	КадроваяИстория.Организация,
    |	КадроваяИстория.Должность,
    |	КадроваяИстория.Подразделение
    |ИЗ
    |	РегистрСведений.КадроваяИсторияИнтервальный КАК КадроваяИстория
    |ГДЕ
    |	КадроваяИстория.ФизическоеЛицо = &ФизическоеЛицо
    |	И &ДатаАнализа МЕЖДУ КадроваяИстория.ДатаНачала И КадроваяИстория.ДатаОкончания";

Запрос.УстановитьПараметр("ФизическоеЛицо", НужноеФизЛицо);
Запрос.УстановитьПараметр("ДатаАнализа", ТекущаяДата());

Этот метод более трудоемкий в написании, но он дает полный контроль над историческими данными.

Рекомендации по выбору метода

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

  1. Если вы пишете внешнюю обработку или небольшую доработку: используйте методы КадровыйУчет.СотрудникиФизическихЛиц и КадровыйУчет.КадровыеДанныеСотрудников. Это гарантирует корректность данных и совместимость с будущими обновлениями конфигурации.
  2. Если вам нужна максимальная скорость в отчете: используйте прямой запрос к регистру ТекущиеКадровыеДанныеСотрудников.
  3. Если нужно учитывать виды занятости (совместительство): всегда проверяйте поле ВидЗанятости (или ТекущийВидЗанятости). Это позволит отделить основных сотрудников от внутренних совместителей или договорников ГПХ.
  4. Если работаете с уволенными: не забывайте передавать соответствующие флаги в параметры функций общего модуля, так как по умолчанию они часто фильтруют только работающий персонал.

Разберем еще один полезный прием: если вам нужно получить должности сотрудников по списку физических лиц, вы можете объединить вызовы в один, передав массив в функцию СотрудникиФизическихЛиц. Это значительно ускорит выполнение кода по сравнению с вызовом функции для каждого человека в отдельности.

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


// Сначала собираем всех сотрудников для всех физлиц из списка
МассивВсехСотрудников = КадровыйУчет.СотрудникиФизическихЛиц(МассивФизЛиц);

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

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

← На главную