Что представляет собой внутренний формат сериализации 1С и как его правильно прочитать?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Каждый разработчик 1С рано или поздно сталкивается с загадочными строками, которые начинаются с фигурных скобок и символа решетки: {"#", ...}. Этот формат используется платформой «1С:Предприятие» повсеместно — в конфигурационных файлах, файлах настроек, схемах СКД, журналах регистрации старого формата (.elf), а также при сохранении данных с помощью встроенных функций. В этой статье мы подробно разберем структуру этого формата, выясним назначение системных идентификаторов, научимся расшифровывать ссылки на объекты и разберем способы чтения этих данных.

Что это за формат и откуда он берется?

Представленный фрагмент — это внутренний формат представления данных платформы 1С (часто называемый v8-сериализацией). Встроенный язык 1С взаимодействует с ним напрямую через функции ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр(). Когда мы сохраняем объект в строку для передачи или записи в файл, платформа преобразует его в древовидную текстовую структуру.

Проанализируем пример из сообщения автора:


{"#",51e7a0d2-530b-11d4-b98a-008048da3034,
{1144,
{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,
{4,
{
{"S","Номенклатура"},
{"#",4b1b49cb-5430-4f80-9818-a1cef1b3d410,116:80e1b083fee00c3a11e80a59363dac8d}
},
...

Давайте разберем по шагам, что означают эти символы:

  1. Символ "#" указывает платформе на то, что далее объявляется сложный тип данных (объект или коллекция).
  2. Следом идет уникальный идентификатор (UUID) типа данных. Например, 51e7a0d2-530b-11d4-b98a-008048da3034 — это системный UUID типа Массив.
  3. Далее в фигурных скобках указывается количество элементов коллекции (в нашем примере — 1144 элемента) и сами элементы.

Как кодируются примитивные типы данных

Прежде чем переходить к сложным объектам, рассмотрим, как во внутреннем формате записываются базовые типы. Каждый примитивный тип данных представляется парой из литерала типа и значения:

Системные UUID коллекций

Платформа 1С использует фиксированные UUID для своих встроенных типов коллекций. Они неизменны в любой конфигурации и в любой информационной базе. Выясним основные из них:

Рассмотрим пример кода, демонстрирующий сериализацию Структуры и Соответствия с одинаковыми данными:


Карта = Новый Соответствие;
Карта.Вставить("Номенклатура", СсылкаНоменклатура);
КартаТекст = ЗначениеВСтрокуВнутр(Карта);

Словарь = Новый Структура;
Словарь.Вставить("Номенклатура", СсылкаНоменклатура);
СловарьТекст = ЗначениеВСтрокуВнутр(Словарь);

После сериализации мы получим практически идентичные структуры, за исключением главного UUID типа:

Для Соответствия:


{"#",3d48feae-a9c6-4c5a-a099-9eb6477630c6,
{1,
{
{"S","Номенклатура"},
{"#",190a7469-3325-4d33-b5ec-28a63ac83b06,215:af150015e9b8c48d11e050911643ef2e}
}
}
}

Для Структуры:


{"#",4238019d-7e49-4fc9-91db-b6b951d5cf8e,
{1,
{
{"S","Номенклатура"},
{"#",190a7469-3325-4d33-b5ec-28a63ac83b06,215:af150015e9b8c48d11e050911643ef2e}
}
}
}

Декодирование ссылок и «перевернутый GUID»

В приведенном автором примере встречается сериализованная ссылка на элемент справочника:

{"#", 4b1b49cb-5430-4f80-9818-a1cef1b3d410, 116:80e1b083fee00c3a11e80a59363dac8d}

Проанализируем эту строку детально:

  1. 4b1b49cb-5430-4f80-9818-a1cef1b3d410 — уникальный UUID типа метаданных справочника (например, справочника «Номенклатура»).
  2. 116 — внутренний идентификатор таблицы СУБД (например, таблица _Reference116 в базе данных SQL).
  3. 80e1b083fee00c3a11e80a59363dac8d — уникальный идентификатор конкретной записи базы данных. Обратите внимание, что этот GUID находится в «переставленном» (shuffled) представлении 1С.

Восстановим стандартный GUID ссылки по следующему алгоритму. Стандартный GUID состоит из 5 групп: [Группа 1]-[Группа 2]-[Группа 3]-[Группа 4]-[Группа 5].

Во внутреннем формате 1С эти группы переставлены местами: [Группа 4][Группа 5][Группа 3][Группа 2][Группа 1].

Возьмем строку 80e1b083fee00c3a11e80a59363dac8d и разобьем ее по длинам групп:

Собираем их в стандартный порядок 1-2-3-4-5 и разделяем дефисами:

363dac8d-0a59-11e8-80e1-b083fee00c3a

Теперь, используя этот GUID, мы можем легко найти элемент в базе данных с помощью встроенного метода:

Ссылка = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор("363dac8d-0a59-11e8-80e1-b083fee00c3a"));

Почему возникает ошибка формата потока?

Попытка прочитать некоторые строки (например, старый журнал регистрации .elf или байт-код закрытых модулей) стандартным методом ЗначениеИзСтрокиВнутр() часто приводит к ошибке «Ошибка формата потока». Выясним причины этого поведения:

Как прочитать данные без стандартных функций

Если вам необходимо прочитать подобные структуры, не прибегая к платформенным методам 1С (например, при обработке файлов внешними скриптами), самым простым решением будет конвертация данных в формат JSON.

Для этого воспользуемся следующим подходом:

  1. Заменим фигурные скобки { на квадратные [, а закрывающие } на ].
  2. Преобразуем структуры вида {"#", <UUID>, ...} в стандартные объекты "ключ-значение" JSON.
  3. Используем стандартный парсер JSON любого языка программирования (например, в Python это библиотека json, а в JavaScript — метод JSON.parse()).

Такой подход позволяет автоматизировать чтение сложных файлов конфигурации и логов 1С на любой программной платформе быстро и эффективно.

← На главную