В практике разработчика 1С часто возникают задачи, когда необходимо создать новый объект (документ, справочник или бизнес-процесс) не с произвольным идентификатором, который генерирует система, а с заранее известным значением. Чаще всего это требуется при интеграции с внешними системами, миграции данных из других информационных баз или при реализации сложных механизмов синхронизации в распределенных системах (РИБ).
Давайте подробно разберем, как правильно реализовать этот механизм, какие методы платформы 1С для этого предназначены и на какие технические нюансы стоит обратить внимание, чтобы не нарушить целостность базы данных.
Прежде чем перейти к коду, проанализируем ситуацию. По умолчанию 1С создает УникальныйИдентификатор автоматически в момент записи объекта. Однако, если мы загружаем данные из внешней CRM или другого приложения, нам важно сохранить связь между объектами. Использование "родного" идентификатора внешней системы в качестве УИДа в 1С позволяет избежать дублирования объектов и значительно упрощает последующее обновление данных. Если мы знаем УИД, нам не нужно искать объект по артикулу, номеру или наименованию — мы можем сразу обратиться к нему напрямую.
Ключевым инструментом для решения нашей задачи является метод УстановитьСсылкуНового(). Рассмотрим пошаговый алгоритм его применения. Процесс состоит из подготовки ссылки и последующей привязки ее к новому объекту.
Шаг 1. Формирование ссылки из строки GUID
Для начала нам нужно преобразовать строковое представление идентификатора в объект типа УникальныйИдентификатор, а затем получить саму ссылку. Рассмотрим пример кода:
// Строковое представление GUID, полученное извне
СтрокаГП = "550e8400-e29b-41d4-a716-446655440000";
НовыйУИД = Новый УникальныйИдентификатор(СтрокаГП);
// Получаем ссылку для конкретного типа документа
НужнаяСсылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(НовыйУИД);
Шаг 2. Проверка на существование объекта
Это критически важный этап. Если мы попытаемся создать объект с УИДом, который уже занят другим документом в базе, система может повести себя непредсказуемо или выдать ошибку нарушения уникальности. Выясним, свободен ли идентификатор:
// Проверяем, существует ли уже объект с такой ссылкой
Если НужнаяСсылка.ПолучитьОбъект() = Неопределено Тогда
// Идентификатор свободен, можно создавать новый документ
Иначе
// Объект уже существует, нужно либо обновить его, либо выдать ошибку
Возврат;
КонецЕсли;
Шаг 3. Создание объекта и фиксация ссылки
Теперь мы создаем новый экземпляр документа и, пока он еще не записан (в памяти), принудительно назначаем ему нашу подготовленную ссылку.
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
// Устанавливаем нашу ссылку ПЕРЕД записью
НовыйДокумент.УстановитьСсылкуНового(НужнаяСсылка);
// Заполняем необходимые реквизиты
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Наша компания");
// Записываем объект в базу данных
НовыйДокумент.Записать();
После вызова метода УстановитьСсылкуНового() свойство Ссылка у объекта НовыйДокумент сразу примет значение НужнаяСсылка, даже если фактически запись в таблицы SQL еще не произошла. Это позволяет использовать ссылку в связанных табличных частях или движениях еще до окончательного коммита транзакции.
Разберем подробнее технические ограничения, о которых часто забывают разработчики:
УстановитьСсылкуНового() работает только для новых, еще не записанных объектов (где метод ЭтоНовый() возвращает Истина). Если документ уже существует в базе, изменить его идентификатор стандартными средствами программирования невозможно. Единственный путь — удаление старого объекта и создание нового.ПолучитьСсылку(), но не записали объект (например, произошел отказ в процедуре ПередЗаписью), в системе появится так называемая "битая" ссылка. При просмотре в списках она будет отображаться как <Объект не найден>....Существует более сложный, но иногда необходимый способ — использование сериализации в XML. Этот метод полезен при массовой загрузке данных, когда объекты приходят в формате XML. Проанализируем этот подход:
Каждый объект 1С может быть представлен в виде XML-структуры, где УИД хранится в специальном узле. Мы можем программно подменить этот узел в тексте XML или использовать объект ЧтениеXML.
// Пример логики десериализации с подменой ссылки
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(ТекстОбъектаXML); // Текст XML, где прописан нужный Ref (UUID)
НовыйОбъект = ПрочитатьXML(Чтение);
НовыйОбъект.Записать();
При использовании ПрочитатьXML для типа ДокументОбъект, система автоматически пытается найти объект по УИД, указанному в XML. Если объект не найден, она создает новый экземпляр и при записи назначает ему именно тот УИД, который был в файле. Это штатный механизм работы планов обмена.
Посмотрим на ситуацию со стороны интерфейса. Если вы вызываете УстановитьСсылкуНового() на клиенте в форме документа, важно понимать, что это должно произойти до момента первой интерактивной записи пользователем. Оптимальное место для такой логики — обработчик ПриУстановкеНовогоНомера (если логика завязана на номер) или специализированная кнопка "Заполнить по шаблону". Однако наиболее надежным вариантом остается создание объекта целиком на стороне сервера в модуле менеджера или общем модуле.
Важный совет: Всегда проверяйте валидность строки GUID. Если строка не соответствует стандарту (например, содержит недопустимые символы или имеет неверную длину), конструктор Новый УникальныйИдентификатор(Строка) вызовет исключение, которое необходимо обрабатывать через блок Попытка...Исключение.
Подводя итог, можно сказать, что создание документа с заданным УИДом — это штатная процедура, требующая лишь соблюдения строгой последовательности действий: Получить ссылку -> Проверить отсутствие -> УстановитьСсылкуНового -> Записать. Это гарантирует корректность ссылочной целостности вашей информационной базы.