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