Как программно записать «битую» ссылку в регистр и почему возникает ошибка «Запись не верна»

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Что такое «битая» ссылка и допустима ли она в регистрах

С точки зрения платформы 1С, «битая» ссылка — это объект ссылочного типа, для которого в базе данных нет соответствующей записи. Программно такую ссылку можно получить, зная её УникальныйИдентификатор. Проанализируем пример создания подобной ссылки:


// Создание ссылки на несуществующий элемент справочника
Идентификатор = Новый УникальныйИдентификатор("d1c2b3a4-e5f6-7890-1234-567890abcdef");
Ссылка = Справочники.Контрагенты.ПолучитьСсылку(Идентификатор);

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

Разбор ошибки «Запись не верна!» при работе с регистрами

При попытке записать набор записей регистра бухгалтерии (или любого другого регистра) программисты часто сталкиваются с исключением: Ошибка при вызове метода контекста (Записать): Запись не верна!. Выясним основные причины этой ошибки, когда мы работаем с внешними данными:

  1. Нарушение уникальности записей: Для регистров сведений это попытка записать две строки с одинаковым набором измерений (период + измерения).
  2. Незаполненные обязательные поля: Отсутствие значения в поле Период, Регистратор или в измерениях, для которых запрещены пустые значения.
  3. Несоответствие типов: Попытка записать ссылку типа СправочникСсылка.Склады в поле, предназначенное для СправочникСсылка.Организации.
  4. Проблемы с Планом видов характеристик (ПВХ): Это специфическая проблема регистров бухгалтерии, где используются Субконто.

Режим записи «ОбменДанными.Загрузка = Истина»

Первое, что мы должны сделать при программной загрузке данных — это установить свойство ОбменДанными.Загрузка в значение Истина. Рассмотрим, как это влияет на процесс записи:

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

Пример корректного кода загрузки из XML, который мы можем использовать:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлу);
ЧтениеXML.Прочитать(); // Чтение корня

Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
    // Десериализация набора записей или объекта
    НаборЗаписей = ПрочитатьXML(ЧтениеXML);
    
    Попытка
        // Включаем режим загрузки для обхода проверок
        НаборЗаписей.ОбменДанными.Загрузка = Истина;
        НаборЗаписей.Записать();
    Исключение
        Сообщить("Ошибка записи: " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;
ЧтениеXML.Закрыть();

Проблема GUID-ов в Планах видов характеристик (ПВХ)

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

В регистре бухгалтерии значение субконто привязано к конкретному ВидуСубконто. Сам ВидСубконто является ссылкой на элемент Плана видов характеристик. Если в базе-источнике элемент «Контрагенты» имеет один GUID, а в базе-приемнике — другой, то при загрузке платформа не сможет сопоставить значение. Даже если мы записываем «битую» ссылку, система должна понимать, к какому типу данных она относится. Если ссылка на ВидСубконто не найдена в ПВХ приемника, система не может определить правила типизации для этого поля, что и вызывает ошибку Запись не верна!.

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

Как гарантированно создать «битую» ссылку для теста

Рассмотрим метод, который позволяет имитировать наличие «битой» ссылки в регистре для отладки механизмов загрузки. Нам не нужно создавать и удалять объект, достаточно использовать метод УстановитьСсылкуНового() в связке с записью в регистр:


// 1. Генерируем новый GUID, которого точно нет в базе
НовыйGUID = Новый УникальныйИдентификатор();
НужнаяСсылка = Справочники.Номенклатура.ПолучитьСсылку(НовыйGUID);

// 2. Создаем запись в регистре с этой ссылкой
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Период.Установить(ТекущаяДата());
Запись = Набор.Добавить();
Запись.Период = ТекущаяДата();
Запись.Номенклатура = НужнаяСсылка; // Вот она, битая ссылка
Запись.Цена = 100;

Попытка
    Набор.Записать();
    Сообщить("Запись успешно создана с битой ссылкой");
Исключение
    Сообщить("Ошибка: " + ОписаниеОшибки());
КонецПопытки;

Пошаговый чек-лист для исправления ошибки «Запись не верна»

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

  1. Проверьте заполнение системных полей: Убедитесь, что у каждой записи набора заполнен Период и Регистратор. Если регистратор сам является «битой» ссылкой, проверьте, разрешен ли этот тип документа в качестве регистратора для данного регистра в метаданных.
  2. Синхронизируйте ПВХ: Проверьте, совпадают ли ссылки на Виды Субконто. Используйте метод ВидСубконто.УникальныйИдентификатор() в обеих базах для сравнения.
  3. Анализируйте составные типы: Если ресурс или измерение имеет составной тип данных, убедитесь, что тип записываемой «битой» ссылки входит в этот составной тип.
  4. Используйте отладку: Посмотрите содержимое объекта перед вызовом метода Записать(). Особое внимание уделите полям, где отображается "<Объект не найден>...". Если вместо этого вы видите Неопределено там, где должна быть ссылка — это и есть причина ошибки.
  5. Проверьте режим обмена: Удостоверьтесь, что ОбменДанными.Загрузка = Истина устанавливается именно для того объекта, который вы записываете (набора записей).

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

← На главную