Почему при обмене ЗУП и ERP в справочнике Сотрудники возникает ошибка «Объект не найден» в поле Головной сотрудник?

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

При сопровождении систем на базе 1С:Зарплата и управление персоналом 8 (редакция 3.1) специалисты часто сталкиваются с неприятной ситуацией после обновления конфигурации до версии 3.1.23.165 и выше. Суть проблемы заключается в том, что при переносе данных из одной базы в другую (например, из ЗУП в ERP или наоборот) через механизм Конвертации данных 2.0, у новых сотрудников реквизит ГоловнойСотрудник заполняется значением «Объект не найден». Это влечет за собой целый «снежный ком» ошибок: сотрудники не отображаются в общем списке, некорректно заполняются регистры кадровой истории и данные для подбора.

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

Разбор причины: Почему «Головной сотрудник» ссылается на «битую» ссылку?

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

Рассмотрим, что происходит в момент программной загрузки через обмен данными:

  1. Объект создается в оперативной памяти приемника, но еще не записан в базу данных. Следовательно, у него еще нет уникального идентификатора (GUID) в физической таблице базы.
  2. Правила обмена пытаются заполнить реквизиты. Если в правилах не указано иное, поле ГоловнойСотрудник может остаться пустым или получить ссылку, которая еще не существует в базе.
  3. При вызове метода Записать() срабатывает обработчик ПередЗаписью. Система видит, что реквизит ГоловнойСотрудник не заполнен, и пытается программно его установить. Однако, если ссылка еще не была сгенерирована методом УстановитьСсылкуНового(), возникает конфликт, и в базу записывается некорректный идентификатор.

Это приводит к тому, что в регистре сведений ДанныеДляПодбораСотрудников не устанавливается флаг ЭтоОсновнойСотрудник. Поскольку динамические списки в ЗУП 3.1 строятся именно по этому регистру (для оптимизации скорости), сотрудник физически в базе есть, но в списке его не видно.

Решение проблемы через изменение правил обмена (КД 2.0)

Чтобы решить проблему системно, нам необходимо внести изменения в Правила Конвертации Объектов (ПКО) для справочника Сотрудники. Основная задача — гарантировать, что ссылка на новый объект будет создана до того, как система попытается записать объект в базу данных.

Рассмотрим по шагам, как настроить обработчик в Конвертации Данных 2.0:

  1. Откроем ваши правила обмена в конфигурации «Конвертация данных».
  2. Найдем ПКО для справочника Сотрудники.
  3. Перейдем в обработчик события ПередЗагрузкой (или ПриЗагрузке, в зависимости от архитектуры ваших правил).
  4. Нам необходимо добавить код, который принудительно генерирует ссылку для нового сотрудника и подставляет ее в нужное поле.

Пример программного кода для вставки в ПКО:


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

Разберем, что делает этот код. Метод ПолучитьСсылку() создает GUID, который система зарезервирует за этим объектом. Метод УстановитьСсылкуНового() сообщает платформе, что при физической записи в таблицу Ref.Сотрудники нужно использовать именно этот идентификатор. Таким образом, на момент записи реквизит ГоловнойСотрудник уже содержит валидную ссылку, и проверка в модуле объекта проходит успешно.

Нюансы работы с ДополнительнымиСвойствами и планами обмена

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

В этом случае важно убедиться, что в правилах обмена (ПКО) установлены правильные настройки поиска. Если объект найден по уникальному идентификатору, он не считается новым, и логика ЭтоНовый() не сработает. Если же вы хотите гарантированно обновлять поле ГоловнойСотрудник даже для существующих объектов, где оно «битое», используйте обработчик ПослеЗагрузки:


Если Не ЗначениеЗаполнено(Объект.ГоловнойСотрудник) 
   ИЛИ Объект.ГоловнойСотрудник.Наименование ЕСТЬ NULL Тогда
    
    // Если ссылка битая или пустая, восстанавливаем ее
    Объект.ГоловнойСотрудник = Объект.Ссылка;
    
    // Принудительно инициируем запись для обновления регистров
    Объект.Записать();
КонецЕсли;

Как восстановить данные в базе-приемнике без повторного обмена

Если ошибка уже произошла и в вашей базе ERP или ЗУП уже создано множество сотрудников с «Объект не найден», не обязательно удалять их и загружать заново. Мы можем исправить их программно с помощью обработки «Групповое изменение реквизитов» или написав небольшой скрипт в консоли кода.

Рассмотрим алгоритм восстановления:

  1. Необходимо отобрать всех сотрудников, у которых реквизит ГоловнойСотрудник не заполнен или является «битой» ссылкой.
  2. Проверить, является ли сотрудник основным местом работы. Для совместителей головным должен быть основной сотрудник, для остальных — они сами.
  3. Выполнить программную установку реквизита и обязательную запись объекта.

Пример кода для восстановления данных:


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

Важный момент: При записи объекта после исправления реквизита ГоловнойСотрудник, система автоматически инициирует обновление записей в регистрах сведений Данные для подбора сотрудников и Кадровая история сотрудников. Это вернет сотрудника в списки выбора и сделает его доступным для кадровых документов.

Особенности учета совместителей

Проанализируем ситуацию с внешними и внутренними совместителями. Для них логика ГоловнойСотрудник = Ссылка будет ошибочной. В ЗУП 3.1 ГоловнойСотрудник — это поле, которое объединяет все карточки сотрудников одного физического лица в рамках одного предприятия. У одного ФизическогоЛица может быть несколько Сотрудников, но у всех них будет один и тот же ГоловнойСотрудник (как правило, это самая первая созданная карточка по основному месту работы).

При настройке обмена важно обеспечить следующий порядок:

Если вы загружаете совместителя, а его «головная» карточка еще не создана в базе-приемнике, реквизит снова станет «битым». Поэтому в правилах поиска (ПКО) для ГоловнойСотрудник рекомендуется использовать поиск по Физическому лицу и признаку ВидЗанятости (Основное место работы).

Резюме

Подведем итоги нашего анализа. Проблема «Объект не найден» в ЗУП 3.1.23+ вызвана не багом обмена как такового, а изменением порядка проверки данных внутри самой конфигурации. Для успешного переноса сотрудников теперь недостаточно просто передать набор полей — необходимо явно управлять ссылкой нового объекта в памяти.

Использование метода УстановитьСсылкуНового() в обработчиках Конвертации данных является наиболее корректным и «чистым» способом решения задачи, так как он не нарушает транзакционную логику 1С и позволяет штатным механизмам конфигурации-приемника правильно обработать данные при первой же записи.

← На главную