В отличие от справочников или документов, записи регистра сведений в платформе «1С:Предприятие» не являются ссылочными типами данных. Это означает, что у записи регистра по умолчанию отсутствует стандартный УникальныйИдентификатор (GUID), к которому привыкли разработчики. Уникальность записи в регистре обеспечивается совокупностью значений его измерений (и периода для периодических регистров). Однако в прикладных задачах часто возникает необходимость получить некую строковую метку или уникальный ключ для конкретной строки. Рассмотрим подробно все существующие способы решения этой задачи, их преимущества и недостатки.
Поскольку уникальность записи гарантируется набором измерений, мы можем составить строковый идентификатор, последовательно объединив значения всех измерений. Разберем, как это сделать правильно, используя штатную функцию XMLСтрока. Эта функция хороша тем, что она преобразует простые типы и ссылки в канонический строковый вид, который удобно хранить и сравнивать.
Проанализируем ситуацию: если мы просто сложим строки, мы можем получить коллизию (пересечение), если значения разных измерений в сумме дадут одинаковую строку. Поэтому рекомендуется использовать разделители.
// Функция для формирования ключа записи
Функция ПолучитьИдентификаторЗаписи(МенеджерЗаписи)
Ключ = "";
// Перечисляем измерения явно или обходим программно
Ключ = Ключ + XMLСтрока(МенеджерЗаписи.Измерение1) + "|";
Ключ = Ключ + XMLСтрока(МенеджерЗаписи.Измерение2) + "|";
// Если регистр периодический, добавляем период
// Ключ = Ключ + XMLСтрока(МенеджерЗаписи.Период);
Возврат Ключ;
КонецФункции
Если в вашем регистре много измерений или их состав может меняться со временем, писать каждое имя вручную нерационально. Выясним, как автоматизировать этот процесс через обращение к метаданным. Мы можем перебрать все измерения регистра в цикле и сформировать строку динамически.
ИмяРегистра = "ВашРегистрСведений";
МетаданныеРегистра = Метаданные.РегистрыСведений[ИмяРегистра];
СтрокаКлюча = "";
Для Каждого Измерение Из МетаданныеРегистра.Измерение Цикл
Значение = ТекущаяЗапись[Измерение.Имя]; // ТекущаяЗапись - это структура или МенеджерЗаписи
СтрокаКлюча = СтрокаКлюча + XMLСтрока(Значение) + "_";
КонецЦикла;
Сообщить("Уникальный ключ записи: " + СтрокаКлюча);
Рассмотрим более продвинутый технический подход. В платформе 1С существует специальный объект РегистрСведенийКлючЗаписи. Он содержит только значения измерений и период. Если применить к нему функцию ЗначениеВСтрокуВнутр, мы получим уникальную системную строку. Важно понимать разницу: МенеджерЗаписи содержит еще и ресурсы с реквизитами, поэтому ЗначениеВСтрокуВнутр для него может возвращать одинаковый результат, если измерения совпадают, а ресурсы разные. А вот КлючЗаписи всегда уникален для уникальной строки регистра.
// Предположим, у нас есть СтруктураКлюча с именами и значениями измерений
КлючОбъект = РегистрыСведений.МойРегистр.СоздатьКлючЗаписи(СтруктураКлюча);
УникальныйСистемныйИдентификатор = ЗначениеВСтрокуВнутр(КлючОбъект);
Иногда требования заказчика или архитектура внешней системы обмена данными диктуют необходимость наличия классического UUID. В этом случае мы можем добавить в регистр новое измерение, например, с именем ИдентификаторЗаписи и типом УникальныйИдентификатор.
Важные моменты при использовании этого метода:
Новый УникальныйИдентификатор().
МенеджерЗаписи = РегистрыСведений.НашРегистр.СоздатьМенеджерЗаписи();
// Заполняем основные измерения
МенеджерЗаписи.Номенклатура = СсылкаНоменклатура;
// Генерируем уникальный ключ
МенеджерЗаписи.ИдентификаторЗаписи = Новый УникальныйИдентификатор();
МенеджерЗаписи.Записать();
Если в результате объединения значений измерений (Способ 1) получается слишком длинная строка (например, более 1000 символов), работать с ней становится неудобно. Проанализируем ситуацию: для таких случаев идеально подходит механизм хеширования. В современной платформе 1С (8.3.11+) доступен объект ХешированиеДанных.
Мы можем собрать все значения в одну строку, а затем получить её MD5-хеш. Это даст нам строку фиксированной длины (32 символа), которая будет уникальной для каждого набора исходных данных.
ДанныеДляХеша = "";
Для Каждого Измерение Из Метаданные.РегистрыСведений.МойРегистр.Измерения Цикл
ДанныеДляХеша = ДанныеДляХеша + XMLСтрока(ТекущиеДанные[Измерение.Имя]);
КонецЦикла;
ХешОбъект = Новый ХешированиеДанных(АлгоритмХеширования.MD5);
ХешОбъект.Добавить(ДанныеДляХеша);
УникальныйХеш = НРег(СтрЗаменить(Строка(ХешОбъект.ХешРезультат), " ", ""));
Посмотрим на задачу с точки зрения интеграции. Если вам нужно передать идентификатор записи во внешнюю систему (например, веб-сайт или мобильное приложение), современным стандартом считается формат JSON. Вы можете сериализовать структуру измерений в JSON-строку. Это компактно и легко восстанавливается обратно в объект 1С для поиска записи.
Также стоит отметить, что при использовании REST API (интерфейс OData), 1С сама формирует уникальный ключ записи в формате: Регистр_Имя(Измерение1='Значение',Измерение2=123). Эту логику можно перенять для собственных нужд, так как она является наиболее «родной» для платформы.
Подводя итог нашему анализу, выделим основные правила выбора метода:
КлючЗаписи и ЗначениеВСтрокуВнутр.XMLСтрока.УникальныйИдентификатор, но следите за индексами.Метаданные.Измерения, чтобы код не сломался при изменении структуры регистра.Разбор этих методов показывает, что отсутствие встроенного GUID у записей регистра — это не ограничение, а особенность архитектуры, которая дает гибкость в определении уникальности данных в зависимости от бизнес-задачи.