При настройке обмена данными, особенно в конфигурациях «Конвертация данных 2.0» или 3.0, разработчики часто сталкиваются с ситуацией, когда один документ-источник должен породить два или более различных документа в базе-приемнике. Возникает закономерный вопрос: можно ли присвоить этим новым документам один и тот же УникальныйИдентификатор (GUID), заимствованный у источника? Не приведет ли это к фатальным ошибкам в работе платформы?
В этой статье мы подробно разберем архитектурные особенности платформы «1С:Предприятие 8», проанализируем опыт типовых решений и выясним, как правильно работать с идентификаторами объектов.
Для начала проанализируем, как платформа 1С идентифицирует объект в базе данных. В отличие от многих других систем, где первичным ключом является только GUID, в 1С ссылка на объект (тип ЛюбаяСсылка) состоит из двух ключевых компонентов:
Рассмотрим ситуацию на уровне таблиц базы данных. Каждый вид документа (например, РеализацияТоваровУслуг и ПоступлениеТоваровУслуг) хранится в своей физической таблице. Поскольку таблицы разные, наличие одинакового GUID в поле _IDRRef (в терминах SQL-хранения) в разных таблицах не создает конфликта уникальности первичного ключа. С точки зрения СУБД это две независимые записи в разных местах.
Таким образом, платформа 1С всегда понимает, о каком объекте идет речь, так как при обращении к ссылке она знает её метаданные (тип). Как справедливо замечено в обсуждении, 1С гарантирует уникальность GUID в пределах одной таблицы, но не всей базы данных в целом.
Существует распространенное заблуждение, что при генерации УникальногоИдентификатора в него «зашивается» информация о типе документа. Это не так. Платформа 1С использует стандартные алгоритмы генерации UUID (обычно версии 4 — случайные числа или версии 1 — на основе времени и MAC-адреса). В самом наборе байтов GUID нет никакой информации о том, является ли объект справочником или документом конкретного вида.
Следовательно, копирование идентификатора из одного типа метаданных в другой технически безопасно. Платформа не будет пытаться «угадать» тип по GUID, она всегда будет использовать явное указание типа из контекста или метаданных ссылки.
Рассмотрим ситуацию, которую часто реализует сама компания 1С. Возьмем обмен между «Управление торговлей» (УТ) и «Бухгалтерией предприятия» (БП). Документ ПередачаТоваровМеждуОрганизациями в УТ при выгрузке в БП может трансформироваться сразу в два документа: РеализацияТоваровУслуг (для одной организации) и ПоступлениеТоваровУслуг (для другой).
В этом случае разработчики 1С часто назначают обоим документам в БП тот же GUID, который был у исходного документа в УТ. Это делается для:
GUID).Если мы разрабатываем собственный механизм или используем «Конвертацию данных», мы можем программно установить идентификатор. Посмотрим на пример кода, как можно создать документ с заранее известным GUID, полученным из строки или другого объекта:
// Предположим, НовыйGUIDСтрокой - это идентификатор документа-источника
НовыйGUID = Новый УникальныйИдентификатор(НовыйGUIDСтрокой);
// Пытаемся найти существующий документ конкретного типа
ДокументСсылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(НовыйGUID);
// Проверяем, существует ли объект в базе
Если ДокументСсылка.ПолучитьОбъект() = Неопределено Тогда
// Если объекта нет, создаем новый с этим GUID
НовыйОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйОбъект.УстановитьСсылкуНового(ДокументСсылка);
// ... заполнение реквизитов ...
НовыйОбъект.Записать();
КонецЕсли;
Этот подход гарантирует, что даже если в системе уже есть документ другого типа (например, ПоступлениеТоваровУслуг) с таким же идентификатором, метод ПолучитьСсылку вернет пустую ссылку именно нужного нам типа, не вызывая коллизий.
Несмотря на техническую допустимость, разберем по шагам ситуации, где одинаковые GUID могут потребовать повышенного внимания:
e1cib/data/Документ.Название?ref=... содержит тип метаданных. Если вы передадите такую ссылку другому пользователю, она откроется корректно. Проблемы возникнут только если внешняя система хранит «голый» GUID без указания типа и пытается найти его во всей базе 1С поиском по всем таблицам — в таком случае она может найти несколько объектов.GUID в одну таблицу СУБД не позволит.Document_Реализация и Document_Поступление — это разные эндпоинты. Одинаковый GUID в разных эндпоинтах абсолютно легитимен.Проанализировав ситуацию, можно сделать следующие выводы:
МенеджерПоиска или запросом по всем таблицам через UNION ALL) следует всегда учитывать тип метаданных, чтобы не получить неожиданную выборку из нескольких документов.УникальномуИдентификатору, система корректно найдет объект именно того типа, который указан в правиле конвертации (ПКО).Подводя итог: страх перед «одинаковыми гуидами» в разных типах документов — это скорее психологический барьер, чем техническое ограничение. Платформа спроектирована так, чтобы эффективно справляться с подобными сценариями.