Как правильно загрузить данные из табличной части в независимый регистр сведений 1С?

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

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

Понимание причины ошибки

Основная проблема заключается в механизме работы с объектами РегистрСведенийНаборЗаписей. Если вы пытаетесь добавить данные в регистр, не установив предварительно отбор или не считав текущее состояние регистра, платформа воспринимает операцию как попытку создания записи, которая уже существует в базе данных. В независимых регистрах сведений ключевыми полями являются измерения и период. Если вы пытаетесь добавить запись с теми же измерениями, что уже есть в базе, система закономерно выдает ошибку нарушения уникальности.

Способ 1: Массовая загрузка через НаборЗаписей

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

  1. Создаем объект НаборЗаписей для нужного регистра.
  2. Считываем текущие данные из базы методом Прочитать().
  3. Выгружаем данные в ТаблицаЗначений методом Выгрузить().
  4. Циклом обходим исходную табличную часть и проверяем наличие аналогичных записей в выгруженной таблице.
  5. Если записи нет, добавляем её в таблицу.
  6. Загружаем обновленную таблицу обратно в НаборЗаписей и записываем изменения.

Посмотрим, как это выглядит в коде:


НаборЗаписей = РегистрыСведений.ОтветственныеЛица.СоздатьНаборЗаписей();
НаборЗаписей.Прочитать();
ТТаблицаДанных = НаборЗаписей.Выгрузить();

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

НаборЗаписей.Загрузить(ТТаблицаДанных);
НаборЗаписей.Записать(Ложь);

Способ 2: Использование Менеджера записи для одиночных операций

Если объем данных небольшой (например, до 100 записей), можно использовать МенеджерЗаписи. Этот объект работает с одной записью регистра напрямую. Он удобен тем, что сам следит за уникальностью ключей, однако при большом количестве записей этот метод может работать медленнее из-за множественных обращений к БД.


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

Важные рекомендации

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

Таким образом, сочетая грамотную проверку данных на этапе подготовки (в памяти) и корректное использование методов записи, вы сможете легко и безопасно обновлять данные в любых регистрах сведений 1С.

← На главную