При интеграции 1С с внешними системами (будь то сторонние базы данных MS SQL, журналы регистрации в формате SQLite 1Cv8.lgd или внешние API) разработчики часто сталкиваются со специфическим форматом хранения уникальных идентификаторов. Вместо привычного нам 36-символьного представления GUID в СУБД или логах могут записываться строки вида 150:811e005056b8ab6011e9a7953bc1c13f.
В этой статье мы подробно разберем, как расшифровать подобные строки, автоматически определить тип объекта 1С и получить полноценную ссылку без использования медленных и потенциально опасных "грязных хаков" вроде встроенной функции ЗначениеИзСтрокиВнутр().
Давайте проанализируем структуру исходной строки. Запись типа 150:811e005056b8ab6011e9a7953bc1c13f состоит из двух ключевых частей, разделенных двоеточием:
Справочники.Номенклатура на уровне СУБД может соответствовать таблица _Reference150.Для того чтобы создать объект типа УникальныйИдентификатор, нам необходимо привести 32-символьную последовательность к стандартному виду с дефисами. Разберем по шагам алгоритм восстановления байтового порядка. Нам нужно переставить части строки по определенной схеме.
Ниже представлена готовая функция, которая решает эту задачу с максимальной производительностью с помощью строковых операций платформы:
Функция ВосстановитьGUIDИзСтрокиЖурнала(ЗначениеGUID) Экспорт
// Пример входа: "811e005056b8ab6011e9a7953bc1c13f"
// Пример выхода: "3bc1c13f-a795-11e9-811e-005056b8ab60"
Если СтрДлина(ЗначениеGUID) <> 32 Тогда
Возврат Неопределено;
КонецЕсли;
СтрокаGUID = Сред(ЗначениеGUID, 25, 8) + "-" +
Сред(ЗначениеGUID, 21, 4) + "-" +
Сред(ЗначениеGUID, 17, 4) + "-" +
Сред(ЗначениеGUID, 1, 4) + "-" +
Сред(ЗначениеGUID, 5, 12);
Попытка
Возврат Новый УникальныйИдентификатор(СтрокаGUID);
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Чтобы не прописывать соответствие кодов (например, 150) конкретным справочникам или документам вручную (что крайне опасно, так как при обновлении или переносе конфигурации в другую базу эти коды могут измениться), мы воспользуемся платформенным методом ПолучитьСтруктуруХраненияБазыДанных().
Рассмотрим, как один раз при запуске системы сформировать соответствие кодов таблиц СУБД и объектов метаданных 1С, сохранив его в кэш (например, в параметры сеанса или повторно используемый модуль):
Функция ПолучитьТаблицуСоответствияКодовМетаданных() Экспорт
СоответствиеКодов = Новый Соответствие;
// Получаем структуру хранения для всей конфигурации
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных(, Истина);
Для Каждого СтрокаТаблицы Из СтруктураБД Цикл
ИмяТаблицыХранения = СтрокаТаблицы.ИмяТаблицыХранения;
ИмяМетаданных = СтрокаТаблицы.ИмяТаблицы;
// Анализируем справочники
Если Найти(ИмяТаблицыХранения, "_Reference") = 1 Тогда
КодТипа = Число(Сред(ИмяТаблицыХранения, 11)); // Извлекаем числовую часть
СоответствиеКодов.Вставить(КодТипа, "Справочник." + СтрЗаменить(ИмяМетаданных, "Справочник.", ""));
// Анализируем документы
ИначеЕсли Найти(ИмяТаблицыХранения, "_Document") = 1 Тогда
КодТипа = Число(Сред(ИмяТаблицыХранения, 10)); // Извлекаем числовую часть
СоответствиеКодов.Вставить(КодТипа, "Документ." + СтрЗаменить(ИмяМетаданных, "Документ.", ""));
КонецЕсли;
КонецЦикла;
Возврат СоответствиеКодов;
КонецФункции
Теперь мы можем объединить полученные инструменты. Вместо использования тяжелого и нестабильного метода ЗначениеИзСтрокиВнутр(), мы будем работать через менеджеры метаданных. Это гарантирует стабильность кода при любых обновлениях платформы.
Функция ПолучитьСсылкуИзВнешнегоИдентификатора(ВходнаяСтрока, КэшМетаданных) Экспорт
// ВходнаяСтрока = "150:811e005056b8ab6011e9a7953bc1c13f"
ПозицияДвоеточия = Найти(ВходнаяСтрока, ":");
Если ПозицияДвоеточия = 0 Тогда
Возврат Неопределено;
КонецЕсли;
КодТипаСтрокой = Лев(ВходнаяСтрока, ПозицияДвоеточия - 1);
СтрокаGUID = Сред(ВходнаяСтрока, ПозицияДвоеточия + 1);
// Пробуем получить имя метаданных по коду
КодТипа = Число(КодТипаСтрокой);
ПолноеИмяМетаданных = КэшМетаданных.Получить(КодТипа);
Если ПолноеИмяМетаданных = Неопределено Тогда
Возврат Неопределено; // Тип не найден в текущей конфигурации
КонецЕсли;
// Восстанавливаем UUID
УИД = ВосстановитьGUIDИзСтрокиЖурнала(СтрокаGUID);
Если УИД = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
// Получаем менеджер объекта динамически
МассивПути = СтрРазделить(ПолноеИмяМетаданных, ".");
ТипОбъекта = МассивПути[0]; // "Справочник" или "Документ"
ИмяОбъекта = МассивПути[1]; // Например, "Номенклатура"
Если ТипОбъекта = "Справочник" Тогда
Возврат Справочники[ИмяОбъекта].ПолучитьСсылку(УИД);
ИначеЕсли ТипОбъекта = "Документ" Тогда
Возврат Документы[ИмяОбъекта].ПолучитьСсылку(УИД);
КонецЕсли;
Возврат Неопределено;
КонецФункции
Важно понимать: если вы попытаетесь выполнять вышеописанную процедуру построчно в цикле при выводе динамического списка или в событии формы ПриПолученииДанныхНаСервере, интерфейс системы начнет сильно зависать при прокрутке. Рассмотрим два профессиональных подхода к оптимизации этой задачи.
Наиболее производительный архитектурный паттерн — перенос сопоставления на уровень СУБД. Для этого в конфигурации создается вспомогательный регистр сведений (например, СопоставлениеВнешнихИдентификаторов) со следующей структурой:
ВнешнийКод (Строка, длина 50, индексировать).СсылкаНаОбъект (ЛюбаяСсылка).Начиная с версии платформы 8.3.22, в языке запросов 1С появилась штатная функция УникальныйИдентификатор(). Мы можем раз в сутки или по регламентному заданию быстро заполнять этот регистр простым запросом:
ВЫБРАТЬ
УникальныйИдентификатор(Номенклатура.Ссылка) КАК GUIDСтрока,
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
После заполнения регистра вы можете связать таблицу внешнего источника данных с этим регистром сведений обычным левым соединением (LEFT JOIN) прямо в запросе динамического списка. На выходе вы мгновенно получите готовые ссылки без малейших задержек интерфейса.
Если данные запрашиваются порциями для программной обработки, преобразовывать их нужно пакетами. Давайте разберем алгоритм пакетного сопоставления:
УникальныйИдентификатор. Это позволяет мгновенно проверить физическое существование объектов в базе 1С и исключить появление "битых" ссылок.Используя данные методы, мы полностью отказываемся от ненадежных механизмов сериализации внутренних строк 1С, повышаем отказоустойчивость нашей интеграции и сохраняем высокую отзывчивость интерфейса для конечных пользователей.