При организации обмена данными или переносе информации из платформы 1С:Предприятие 7.7 в 1С:Предприятие 8 часто возникает задача сопоставления ссылочных данных. В версии 8.х каждый объект имеет 128-битный УникальныйИдентификатор (GUID/UUID), тогда как в 7.7 идентификация объектов строится на внутренних числовых кодах и строковом представлении ЗначениеВСтрокуВнутр.
Рассмотрим, как устроена внутренняя ссылка в платформе 7.7, какие существуют способы конвертации ссылок в GUID и обратно «на лету» без использования промежуточных таблиц сопоставления, а также разберем подводные камни каждого подхода.
Для ссылочных типов (справочники, документы, счета) встроенная функция ЗначениеВСтрокуВнутр() возвращает строку формата JSON-подобного массива из 7 параметров:
{"<Тип>","0","0","<ИД_Вида_Метаданных>","0","0","<ИД_Объекта>"}
Разберем основные составляющие этой строки:
"B" — справочник, "O" — документ, "A" — счет).1Cv7.MD), например 84, 1611.Стандартный GUID представляет собой строку из 32 шестнадцатеричных цифр, разделенных дефисами по схеме 8-4-4-4-12. Мы можем закодировать тип, вид метаданных и внутренний ID объекта в HEX-представление и объединить их в валидный GUID.
Посмотрим на пример функции кодирования ссылки в 1С 7.7:
Функция ПолучитьУникальныйИдентификатор(пСсылка)
лВнутрСтрока = ЗначениеВСтрокуВнутр(пСсылка);
// Убираем внешние фигурные скобки
лСтрокаСРазделителями = Сред(лВнутрСтрока, 2, СтрДлина(лВнутрСтрока) - 2);
лСписок = СоздатьОбъект("СписокЗначений");
лСписок.ИзСтрокиСРазделителями(лСтрокаСРазделителями);
НеВажно = "";
лТип = лСписок.ПолучитьЗначение(1, НеВажно); // Например, "B"
лВид = лСписок.ПолучитьЗначение(4, НеВажно); // Например, "84"
лИДОбъекта = лСписок.ПолучитьЗначение(7, НеВажно); // Строка из 13 символов
// Проверяем корректность длины идентификатора
Если СтрДлина(лИДОбъекта) <> 13 Тогда
ВызватьИсключение "Длина идентификатора объекта должна составлять ровно 13 символов!";
КонецЕсли;
// Формируем HEX-строку (32 символа)
// Тип (2 hex-символа) + Вид метаданных (4 цифры) + 13 символов ID в HEX (26 hex-символов)
лРезультат = СтрокуВХекс(лТип) + Формат(Число(лВид), "Ч(0)4") + СтрокуВХекс(лИДОбъекта);
// Приводим строку к стандартному формату GUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
лGUID = Лев(лРезультат, 8) + "-" +
Сред(лРезультат, 9, 4) + "-" +
Сред(лРезультат, 13, 4) + "-" +
Сред(лРезультат, 17, 4) + "-" +
Прав(лРезультат, 12);
Возврат лGUID;
КонецФункции
Для обратного восстановления ссылки в 1С 7.7 из полученного GUID выполняем обратную операцию: убираем дефисы, раскодируем шестнадцатеричные пары символов обратно в строку через ХексВСтроку, собираем структуру с разделителями и передаем в ЗначениеИзСтрокиВнутр():
Функция ПолучитьСсылкуИзGUID(пGUID)
// Удаляем дефисы
лСтр = СтрЗаменить(пGUID, "-", "");
лТип = ХексВСтроку(Лев(лСтр, 2));
лВид = Строка(Число(Сред(лСтр, 3, 4)));
лИДОбъекта = ХексВСтроку(Сред(лСтр, 7, 26));
// Собираем внутреннюю строку формата 7.7
Сп = СоздатьОбъект("СписокЗначений");
Сп.ДобавитьЗначение(лТип);
Сп.ДобавитьЗначение("0");
Сп.ДобавитьЗначение("0");
Сп.ДобавитьЗначение(лВид);
Сп.ДобавитьЗначение("0");
Сп.ДобавитьЗначение("0");
Сп.ДобавитьЗначение(лИДОбъекта);
СсылкаНаОбъект = ЗначениеИзСтрокиВнутр("{" + Сп.ВСтрокуСРазделителями() + "}");
Возврат СсылкаНаОбъект;
КонецФункции
Важные нюансы прямого HEX-кодирования:
ЗначениеИзСтрокиВнутр() крайне чувствителен к длине поля идентификатора (ровно 13 символов). При распаковке необходимо сохранять все исходные пробелы..md файлом эти числовые идентификаторы могут измениться, что нарушит обратную совместимость сгенерированных ранее GUID.Если обратная сборка объекта вслепую не требуется, а необходима однозначная синхронизация между базами без коллизий, рекомендуется использовать вычисление детерминированного GUID на основе хэш-суммы (MD5 или SHA-1).
Разберем логику работы этого метода:
"Справочник.Номенклатура: 1611 ЦБ").При таком подходе при каждой выгрузке один и тот же объект 7.7 гарантированно получает один и тот же УникальныйИдентификатор в 1С 8, предотвращая дублирование данных.
Если модификация идентификаторов нежелательна, классическим и наиболее надежным методом является сопоставление через временное хранилище или регистр соответствий (как это реализовано в «1С:Конвертация данных»).
Посмотрим на пример использования объекта Соответствие в 1С 8 для кэширования генерируемых GUID:
Перем мСоответствиеПреобразования;
Функция ПолучитьИлиСоздатьGUID(Идентификатор77) Экспорт
Если ТипЗнч(мСоответствиеПреобразования) <> Тип("Соответствие") Тогда
мСоответствиеПреобразования = Новый Соответствие;
КонецЕсли;
Результат = мСоответствиеПреобразования.Получить(Идентификатор77);
Если Результат = Неопределено Тогда
Результат = Новый УникальныйИдентификатор;
мСоответствиеПреобразования.Вставить(Идентификатор77, Результат);
КонецЕсли;
Возврат Результат;
КонецФункции
Проанализировав все варианты, для прямого двустороннего обмена «на лету» без вспомогательных баз оптимально подходит HEX-кодирование строки ЗначениеВСтрокуВнутр с контролем кодировки ANSI (Windows-1251), а для стабильной долгосрочной интеграции — использование детерминированных хэш-GUID или механизмов «1С:Конвертации данных».