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

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

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

Анализ проблемы: почему данные не сохраняются?

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

Рассмотрим пример кода, который может приводить к подобной ошибке:


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

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

Решение проблемы с транзакциями

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

Рассмотрим исправленный алгоритм записи данных:


Для Каждого Данные Из ТЗ Цикл
    // Обязательно проверяем заполнение ключевых полей
    Если ПустаяСтрока(Данные.СНИЛС) Тогда
        Продолжить;
    КонецЕсли;

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

    Если СсылкаФизлицо.Пустая() Тогда
        ОбщегоНазначения.СообщитьПользователю("Физлицо со СНИЛС " + Данные.СНИЛС + " не найдено.");
        Продолжить;
    КонецЕсли;

    Попытка
        // Получаем объект для редактирования
        ОбъектФизлицо = СсылкаФизлицо.ПолучитьОбъект();
        
        // Устанавливаем режим загрузки, чтобы пропустить лишние проверки модуля объекта
        ОбъектФизлицо.ОбменДанными.Загрузка = Истина;
        
        // Установка даты рождения
        ОбъектФизлицо.ДатаРождения = Данные.ДатаРождения;
        
        // Запись объекта
        ОбъектФизлицо.Записать();
        
        // Если требуется запись связанных данных, транзакцию лучше описывать здесь
        // НачатьТранзакцию();
        // ... запись в регистры ...
        // ЗафиксироватьТранзакцию();
        
    Исключение
        // В случае ошибки выводим описание и продолжаем цикл (или прерываем)
        ТекстОшибки = СтрШаблон("Ошибка при записи %1: %2", СсылкаФизлицо, ОписаниеОшибки());
        ОбщегоНазначения.СообщитьПользователю(ТекстОшибки);
        // Если транзакция была открыта внутри Попытки, здесь должен быть ОтменитьТранзакцию();
    КонецПопытки;
КонецЦикла;

Особенности реквизита "Место рождения" в ЗУП 3.1

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

Разберем, как правильно заполнять сведения о месте рождения, чтобы они корректно отображались в карточке и попадали в отчеты:

  1. Строковый формат: Если вы записываете только текст, убедитесь, что в конфигурации не настроено обязательное использование классификатора.
  2. Использование API конфигурации: В ЗУП 3.1 рекомендуется использовать функции программного интерфейса из общих модулей. Это гарантирует, что данные попадут во все связанные регистры.

Важность регистров сведений

Проанализируем структуру хранения данных. В 1С:ЗУП ДатаРождения является реквизитом самого справочника, но многие другие личные данные (ФИО, ИНН, гражданство) хранятся в периодических регистрах сведений. Если ваша задача расширится до изменения фамилии, помните, что изменение реквизита Наименование в объекте справочника не создаст запись в истории ФИО.

Для корректного изменения истории личных данных следует обращаться к соответствующим регистрам:

Использование режима ОбменДанными.Загрузка

Установка Объект.ОбменДанными.Загрузка = Истина — это критически важный момент при программной записи. Рассмотрим подробнее, что это дает:

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

Заключение и рекомендации

Подводя итог нашему разбору, выделим основные правила программной работы со справочником физических лиц в ЗУП:

  1. Следите за транзакциями: Никогда не оставляйте НачатьТранзакцию() без парного ЗафиксироватьТранзакцию(). Старайтесь избегать Возврат внутри блоков транзакций.
  2. Поиск по СНИЛС: Это самый надежный способ идентификации, но предварительно очищайте строку СНИЛС от лишних символов (дефисов и пробелов) или, наоборот, приводите к формату XXX-XXX-XXX XX, принятому в 1С.
  3. Используйте типовые модули: Обратите внимание на модуль ФизическиеЛица.ЗаписатьДанныеФизическогоЛица. Использование встроенного API конфигурации — это лучший способ гарантировать целостность данных.
  4. Проверяйте журнал регистрации: Если данные не сохраняются, первым делом ищите события со статусом "Транзакция отменена" — это всегда признак программной ошибки в управлении транзакциями или отказа в подписках на события.

Соблюдение этих правил позволит вам создавать надежные механизмы интеграции и обработки данных в системе 1С:Зарплата и Управление Персоналом.

← На главную