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

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

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

Анализ структуры данных регистра ФИО

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

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

Способ 1: Использование запроса с виртуальной таблицей СрезПоследних

Рассмотрим наиболее производительный и правильный с точки зрения архитектуры 1С способ — использование виртуальной таблицы СрезПоследних. Этот метод позволяет получить актуальную запись на определенный момент времени.

Разберем пример кода, который возвращает дату изменения фамилии для конкретного физического лица:


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

В данном примере мы используем параметр ПериодСреза. Если его не указать, система вернет самую последнюю запись в регистре. Однако использование параметров в виртуальной таблице (в части отбора по ФизическоеЛицо) значительно ускоряет работу запроса, так как система фильтрует данные еще на уровне СУБД.

Способ 2: Прямой запрос к таблице регистра (Получение последней записи)

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


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

Обратите внимание на конструкцию ВЫБРАТЬ ПЕРВЫЕ 1 и УПОРЯДОЧИТЬ ПО Период УБЫВ. Это классический прием для получения самой "свежей" записи в любой периодической структуре. Также крайне рекомендуется использовать ключевое слово РАЗРЕШЕННЫЕ после ВЫБРАТЬ, если в базе настроены права доступа на уровне записей (RLS), чтобы избежать ошибок доступа у пользователей с ограниченными правами.

Способ 3: Использование типовых функций ЗУП 3.1

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

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

Рассмотрим работу с общим модулем ФизическиеЛица:


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

Для массового получения данных лучше использовать метод ФизическиеЛица.ДанныеФизическихЛиц, передав в него массив ссылок. Это позволит избежать проблемы "запроса в цикле", которая часто приводит к деградации производительности системы.

Типичные ошибки и их разбор

Проанализируем ситуацию, возникшую в обсуждении на форуме. Один из пользователей пытался использовать несуществующее слово РАЗГРАНИЧИТЬ. Важно запомнить, что в языке запросов 1С существуют только следующие ключевые слова для управления выборкой:

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

Резюме для реализации

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

  1. Проверить, передана ли ссылка на ФизическоеЛицо (если передан Сотрудник — получить его ФизическоеЛицо).
  2. Использовать запрос к виртуальной таблице СрезПоследних с обязательным отбором по измерению в параметрах таблицы.
  3. Всегда добавлять РАЗРЕШЕННЫЕ для корректной работы под пользователями.
  4. Если в вашей конфигурации доступен модуль ФизическиеЛица, отдавать предпочтение его методам.

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

← На главную