Как исправить ошибку «Поле объекта недоступно для записи» при программном создании сотрудника и физического лица?

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

При разработке механизмов импорта данных или автоматического создания объектов в 1С программисты часто сталкиваются с ошибкой «Поле объекта недоступно для записи». Особенно часто это происходит при попытке заполнить данные справочника Сотрудники, который неразрывно связан со справочником ФизическиеЛица. Разберем подробно, почему возникает эта ситуация и как правильно выстроить архитектуру кода для создания связанных объектов.

Анализ причины ошибки: Ссылка против Объекта

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

НовыйСотрудник.ФизическоеЛицо.ФИО = ИнформацияФЛ.Наименование;

В этой строке кроется фундаментальная ошибка понимания работы платформы 1С. Рассмотрим ситуацию по шагам:

  1. Переменная НовыйСотрудник является объектом (результат функции СоздатьЭлемент()). Мы можем записывать в её непосредственные реквизиты любые значения.
  2. Реквизит ФизическоеЛицо у нового сотрудника — это поле ссылочного типа. Поскольку объект только что создан, это поле содержит пустую ссылку на справочник ФизическиеЛица.
  3. Когда мы обращаемся через точку (ФизическоеЛицо.ФИО), система пытается «разыменовать» ссылку. Но обращение через точку от ссылки всегда возвращает данные только для чтения.
  4. Записать данные в объект, находясь в контексте ссылки другого объекта, невозможно. Именно поэтому платформа сообщает: «Поле объекта недоступно для записи».

Правильный алгоритм создания связанных объектов

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

Рассмотрим пошаговый алгоритм:

  1. Поиск существующего физического лица: Прежде чем создавать нового человека, проверим по уникальным идентификаторам (ИНН или СНИЛС), нет ли его уже в базе.
  2. Создание/Модификация физического лица: Если физлицо не найдено, создаем новый объект, заполняем его и обязательно записываем. Если найдено — получаем объект для редактирования.
  3. Связывание объектов: Полученную ссылку на записанное физическое лицо присваиваем реквизиту сотрудника.
  4. Запись сотрудника: Только теперь записываем сам объект сотрудника.

Проанализируем пример исправленного кода:


// 1. Сначала работаем с Физическим Лицом
ФизЛицоСсылка = Справочники.ФизическиеЛица.НайтиПоРеквизиту("ИНН", строка.ИНН);

Если ФизЛицоСсылка.Пустая() Тогда
    ФизЛицоОбъект = Справочники.ФизическиеЛица.СоздатьЭлемент();
Иначе
    ФизЛицоОбъект = ФизЛицоСсылка.ПолучитьОбъект();
КонецЕсли;

// Заполняем реквизиты ФизЛица напрямую в его объект
ФизЛицоОбъект.Наименование = строка.ФИО;
ФизЛицоОбъект.ДатаРождения = Дата(строка.ФЛДатаРождения);
ФизЛицоОбъект.ИНН = строка.ИНН;
// ... заполнение остальных полей ...

ФизЛицоОбъект.Записать(); // Теперь у нас есть валидная ссылка в ФизЛицоОбъект.Ссылка

// 2. Теперь создаем Сотрудника
НовыйСотрудник = Справочники.Сотрудники.СоздатьЭлемент();
НовыйСотрудник.ФизическоеЛицо = ФизЛицоОбъект.Ссылка; // Присваиваем ссылку
НовыйСотрудник.Наименование = ФизЛицоОбъект.Наименование;
НовыйСотрудник.Код = строка.КодСотрудника;

НовыйСотрудник.Записать();

Особенности работы с ФИО в современных конфигурациях (ЗУП 3.1, ERP)

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

Если вы работаете в конфигурации «Зарплата и управление персоналом 3.1», прямая запись в ФизическоеЛицо.ФИО может не сработать или не обновить данные в кадровом учете. В таких случаях мы рекомендуем использовать следующий подход:

Проанализируем ситуацию: для корректного отображения ФИО в истории, нужно заполнять отдельные реквизиты Фамилия, Имя, Отчество (если они есть в справочнике как реквизиты) или использовать программный интерфейс (API) конфигурации для записи фамилии. Однако, в простейшем случае, запись в Наименование объекта физлица инициирует обновление представления.

Использование устаревших реквизитов

В исходном коде автора встречается строка:

НовыйСотрудник.УдалитьТекущееПодразделение = ...

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

Рекомендации по качеству кода

Рассмотрим несколько советов, которые помогут избежать подобных ошибок в будущем:

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

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

← На главную