Почему не загружаются данные в регистр сведений ВоинскийУчет при переносе через Конвертацию данных 2.1?

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

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

В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутренние механизмы платформы «1С» и Библиотеки стандартных подсистем (БСП), а также предоставим готовые и надежные варианты решения этой проблемы.

Выясняем причину: почему данные есть в XML, но отсутствуют в базе данных?

Рассмотрим стандартную логику, которую часто применяют разработчики. Для выгрузки связанных с физическим лицом данных из регистра сведений ВоинскийУчет в ПКО ФизическиеЛица в обработчике «После выгрузки» пишется следующий код:


НаборЗаписей = РегистрыСведений.ВоинскийУчет.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ФизическоеЛицо.Установить(Источник, Истина);
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
    ВыгрузитьПоПравилу(Запись, , , , "ВоинскийУчет");
КонецЦикла;

На первый взгляд, этот код логичен: мы выбираем все записи по конкретному сотруднику и отправляем их на выгрузку по правилу конвертации. В XML-файле формируются соответствующие узлы. Однако при загрузке в приемник мы сталкиваемся с полным отсутствием записей. Выясним, почему так происходит.

1. Несовместимость метода ВыгрузитьПоПравилу() с логикой независимых регистров

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

2. Проблема циклической очистки набора на стороне приемника

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

3. Эффект «Призрачной ссылки» при синхронизации не по UID

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

4. Влияние подписок на события в ЗУП 3.1

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

Решение проблемы: правильная выгрузка через ВыгрузитьРегистр()

Для корректного переноса независимых периодических регистров сведений в Конвертации данных 2.1 необходимо использовать специализированную функцию ВыгрузитьРегистр(). Этот метод формирует в XML-файле единый узел набора записей с установленным отбором. При импорте загрузчик БСП распознает этот узел как целостный пакет данных и записывает его одной транзакцией через метод НаборЗаписей.Записать().

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

Шаг 1. Подготовка таблицы значений и выгрузка набора в ПКО Источника

В ПКО ФизическиеЛица в обработчике события «После выгрузки» заменим обход в цикле на формирование таблицы значений и вызов функции ВыгрузитьРегистр(). Посмотрим на следующий пример кода:


// 1. Создаем таблицу значений с колонками, полностью соответствующими структуре регистра ВоинскийУчет
ТаблицаРегистра = Новый ТаблицаЗначений;
ТаблицаРегистра.Колонки.Добавить("Период");
ТаблицаРегистра.Колонки.Добавить("ФизическоеЛицо");
ТаблицаРегистра.Колонки.Добавить("ОтношениеКВоинскойОбязанности");
ТаблицаРегистра.Колонки.Добавить("Годность");
ТаблицаРегистра.Колонки.Добавить("Звание");
ТаблицаРегистра.Колонки.Добавить("Состав");
ТаблицаРегистра.Колонки.Добавить("ВУС");
ТаблицаРегистра.Колонки.Добавить("Военкомат");
ТаблицаРегистра.Колонки.Добавить("НаличиеМобпредписания");
ТаблицаРегистра.Колонки.Добавить("НомерКоманды");
ТаблицаРегистра.Колонки.Добавить("ДатаВрученияМобпредписания");
ТаблицаРегистра.Колонки.Добавить("Забронирован");

// 2. Считываем актуальные данные из базы-источника по нашему физлицу
НаборЗаписей = РегистрыСведений.ВоинскийУчет.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ФизическоеЛицо.Установить(Источник, Истина);
НаборЗаписей.Прочитать();

// 3. Заполняем таблицу значений строками из прочитанного набора
Для Каждого Запись Из НаборЗаписей Цикл
    НоваяСтрока = ТаблицаРегистра.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Запись);
КонецЦикла;

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

// 5. Вызываем выгрузку регистра единым пакетом
ВыгрузитьРегистр(ТаблицаРегистра, СтруктураОтбора, , , "ВоинскийУчет");

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

Шаг 2. Настройка Правил Конвертации Свойств (ПКС) для регистра

Для того чтобы метод ВыгрузитьРегистр() отработал корректно, в правилах конвертации объектов (ПКО) для регистра ВоинскийУчет должны быть четко сопоставлены все ключевые свойства. Проанализируем следующие настройки в Конвертации данных 2.1:

  1. Убедимся, что для измерения ФизическоеЛицо включен поиск по полям синхронизации (ФИО, Дата рождения, ИНН), если мы не используем поиск по УИД.
  2. Для периодических регистров обязательно должно быть сопоставлено свойство Период.
  3. В ПКО регистра сведений снимем флаг «Использовать быстрый выбор для получения данных», если он установлен, чтобы избежать конфликтов при сопоставлении сложных типов данных.

Важные рекомендации по синхронизации данных кадрового учета

Чтобы исключить влияние «призрачных ссылок» и корректно обойти жесткие транзакционные подписки на события в ЗУП 3.1, рекомендуем придерживаться следующих правил:

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

← На главную