Как автоматически получить должность при выборе физического лица в 1С:ERP?

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

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

Архитектурное разделение: Физические лица, Сотрудники и Должности

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

  1. Справочник Физические лица: Хранит исключительно персональную, фундаментальную информацию о человеке (паспортные данные, ИНН, СНИЛС, дату рождения, адреса). Здесь нет и не может быть кадровой информации.
  2. Справочник Сотрудники: Выступает связующим звеном. Он фиксирует конкретные трудовые отношения. На одно физическое лицо в базе может быть заведено несколько элементов справочника сотрудников. Например, человек может работать по основному месту работы и по внутреннему совместительству, либо быть уволенным и принятым заново.
  3. Регистр сведений КадроваяИсторияСотрудников: Именно в этом периодическом регистре хранится история того, какую должность занимает сотрудник, в каком подразделении он числится, и с какой даты действуют эти условия.

Таким образом, мы имеем связь «один ко многим». У одного физического лица может быть несколько мест работы (соответственно, несколько сотрудников), а у каждого сотрудника должность может меняться с течением времени. Следовательно, в общем случае получить одну-единственную должность "напрямую через точку" невозможно.

Проблема выбора: какой должности отдать приоритет и роль даты

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

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

Также критически важно учитывать дату документа. Кадровая история периодична. Человек, который сегодня занимает должность директора, пару месяцев назад мог числиться рядовым специалистом. Должность всегда извлекается на актуальную дату, которую мы обязательно должны передать в наш алгоритм поиска.

Способы получения данных: пишем код правильно

Проанализируем возможные варианты реализации программного получения должности.

Вариант 1: Собственный запрос к регистру сведений

Мы можем написать классический запрос к виртуальной таблице среза последних регистра КадроваяИсторияСотрудников. Мы передаем ссылку на физическое лицо, связываем ее со справочником сотрудников и получаем срез на нужную дату. Однако в современных конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), такой подход не рекомендуется. Система кадрового учета имеет множество нюансов (временные переводы, совместительство, изменения штатного расписания), и простой запрос может выдать некорректный результат.

Вариант 2: Использование типового программного интерфейса (API) конфигурации

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

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


&НаКлиенте
Процедура ФизическоеЛицоПриИзменении(Элемент)
    
    // Если поле очистили, очищаем и надпись
    Если Не ЗначениеЗаполнено(Объект.ФизическоеЛицо) Тогда
        Элементы.НадписьДолжность.Заголовок = "";
        Возврат;
    КонецЕсли;
    
    // Определяем дату для получения актуальной кадровой истории
    АктуальнаяДата = ?(ЗначениеЗаполнено(Объект.Дата), Объект.Дата, ТекущаяДата());
    
    // Обращаемся на сервер за данными
    СтрокаДолжности = ПолучитьДолжностьФизЛицаНаСервере(Объект.ФизическоеЛицо, АктуальнаяДата);
    
    // Выводим результат пользователю
    Элементы.НадписьДолжность.Заголовок = СтрокаДолжности;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьДолжностьФизЛицаНаСервере(ФизЛицо, ДатаАктуальности)
    
    РезультатДолжность = "";
    
    // Формируем массив для передачи в типовую функцию
    МассивФизЛиц = Новый Массив;
    МассивФизЛиц.Добавить(ФизЛицо);
    
    // Указываем, какие именно поля нас интересуют
    ТребуемыеДанные = "Должность, ВидЗанятости";
    
    // Вызываем типовой API кадрового учета
    ТаблицаКадровыхДанных = КадровыйУчет.КадровыеДанныеФизическихЛиц(Истина, МассивФизЛиц, ТребуемыеДанные, ДатаАктуальности);
    
    Если ТаблицаКадровыхДанных.Количество() > 0 Тогда
        // Если записей несколько, ищем "Основное место работы"
        Для Каждого СтрокаДанных Из ТаблицаКадровыхДанных Цикл
            Если СтрокаДанных.ВидЗанятости = Перечисления.ВидыЗанятости.ОсновноеМестоРаботы Тогда
                РезультатДолжность = Строка(СтрокаДанных.Должность);
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        // Если основное место не найдено (например, только совместительство), берем первую попавшуюся должность
        Если ПустаяСтрока(РезультатДолжность) Тогда
            РезультатДолжность = Строка(ТаблицаКадровыхДанных[0].Должность);
        КонецЕсли;
    КонецЕсли;
    
    Возврат РезультатДолжность;
    
КонецФункции

Где посмотреть рабочие примеры в типовой конфигурации?

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

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

← На главную