Зачем?! На C и вправду ничего в экосистеме 1С нет. Или мне не попадалось. И, кроме пополнения списка в статье VKislitsin, хотелось сравнить скорость с платформой 1С. Здесь, правда, возникает проблема: если получить скорость разбора контейнера в компоненте просто, как получить эту скорость в 1С? Приходится прибегать к замеру «по часам», что даёт очень не точный результат.
В Windows в режиме тонкого клиента среднее значение времени получения метаданных из ERP 2.5.12.48 компонентой составляет 640 мс. Открытие того же файла в 1С Конфигураторе 8.3.23.1739 (х64) – около 5 000 мс. Таким образом, прирост скорости в ≈ 8 раз. Но из внешней компоненты возвращается текст в JSON, его разбор и отображение в 1С занимает, вместе с запросом в ВК, ≈ 3000 мс. При таком расчете прирост скорости падает с 8 до ≈ 1,7 раза.
Для тестирования скорости желательно временно отключить Защиту в реальном времени Microsoft Defender (если он у вас включен). Служба Antimalware service executable очень сильно тормозить выполнение ВК.
В Linux, запущенной в Oracle VM VirtualBox, в режиме тонкого клиента среднее значение времени получения метаданных из ERP 2.5.12.48 компонентой составляет 1030 мс. Открытие того же файла в 1С Конфигураторе 8.3.23.1739 (х64) – около 20 000 мс. Таким образом, прирост скорости в ≈ 20 раз. Как неожиданно и... странно!
Для реализации работы в веб-клиенте использовалась обработка из статьи Решение для работы внешней компоненты в веб-браузере под Windows и Linux: 1С + Installer.
Эта статья, в некотором смысле, опирается на работу Андрея Овсянкина Описание формата файлов конфигурации (CF, EPF, ERF) и использует её терминологию.
Работу с контейнером можно разделить на два уровня: уровень файлов и уровень метаданных. В этой статье речь пойдёт больше про уровень файлов и, совсем немного, про уровень метаданных.
Контейнер – файл с конфигурацией (cf), внешняя обработка (epf), внешний отчет (erf) или расширение (cfe). Если проводить аналогию с файловой системой, то контейнер - это логический диск. Файл внутри контейнера – это поименованная совокупность данных. Файл всегда состоит из двух документов: документа заголовка и документа с содержимым файла. Документ, в свою очередь, состоит из блоков. Блок – это структура из заголовка и следующего строго за ним тела блока. Начиная с версии платформы 8.3.16, появилась новая версия контейнера. Эта версия есть только для конфигурации (cf), и представляет собой адаптацию для работы с 64-х разрядными (UINT64) адресами (старая версия работает с 32-х разрядными (INT32) адресами).
Метаданное – это связанная совокупность файлов. Метаданные – вся структура метаданных в контейнере. В контейнере для работы с метаданными находятся несколько вспомогательных файлов: root, version, versions, copyinfo, configinfo. Root/configinfo – это файл, с которого начинается работа с метаданными контейнера.
Root используется для конфигурации (cf), внешней обработке (epf), внешнего отчета (erf), для расширения (cfe) – configinfo. Внутри root файла находится id файла с описанием структуры метаданных.
В файле version находится информация о версии контейнера, например: {{216,0,{80323,0}}}, где 80323 – номер версии. Если номер версии меньше 80316 – версия с 32-х разрядной адресацией, иначе – с 64-х разрядной. Имеет смысл только для конфигурации, в обработке, отчете, расширении всегда 32-х разрядная версия, вне зависимости от того, что написано в файле version.
В файле versions находятся пары «id метаданного», id версии метаданного. Используется для кэширования метаданных.
В файле copyinfo в формате внутренних данных 1С хранится информация об изменениях. Есть, судя по всему, только во внешних отчётах и обработках.
Configinfo используется в расширении вместо root, version, versions.
В файле с описанием структуры метаданных, в разделах видов метаданных находится список id самих метаданных. Id метаданного совпадает с именем файла атрибутов, содержащим описание метаданного. В этом файле находится список частей метаданного произвольного количества: формы, макеты, команды, перерасчеты. Помимо этого у метаданного, в зависимости от его вида метаданного, могут быть постфиксы единичных частей: модуль объекта, модуль менеджера, справочная информация и так далее.
Например, в ERP 2.5.12.48.cf, у справочника Файлы с id e7b0ae70-0192-456c-9dc5-e66049fa9df2, постфикса модуля объекта (см. ниже таблицу) - 0, то есть, id файла с модулем объекта - id.0, e7b0ae70-0192-456c-9dc5-e66049fa9df2.0. Аналогично, модуль менеджера - e7b0ae70-0192-456c-9dc5-e66049fa9df2.3, справочная информация, e7b0ae70-0192-456c-9dc5-e66049fa9df2.1, предопределенные данные, внезапно!, e7b0ae70-0192-456c-9dc5-e66049fa9df2.1c. Не все постфиксы однозначные и цифровые.
С частями произвольного количества несколько сложнее: нужно в файле атрибутов найти id части, для справочников id форм - fdf816d2-1ead-11d5-b975-0050bae0a95d. Получаем имена файлов формы, например, ФормаВыбора: Атрибуты формы - 5a398637-a06c-4442-9093-a864fa7f049f, Форма и модуль - 5a398637-a06c-4442-9093-a864fa7f049f.0, Справочная информация - 5a398637-a06c-4442-9093-a864fa7f049f.1. Аналогично с макетами, командами, перерасчетами.
Таблица групп метаданных
Группа метаданных |
id |
Общие |
9cd510cd-abfc-11d4-9434-004095e12fc7 |
Основные |
9fcd25a0-4822-11d4-9414-008048da11f9 |
Бухгалтерский учет |
e3687481-0a87-462c-a166-9f34594f9bba |
Расчет |
9de14907-ec23-4a07-96f0-85521cb6b53b |
Бизнес-процессы |
51f2d5d8-ea4d-4064-8892-82951750031e |
Внешние источники данных |
e68182ea-4237-4383-967f-90c1e3370bc7 |
Сервисы интеграции |
fb282519-d103-4dd3-bc12-cb271d631dfc |
Внешняя обработка |
c3831ec8-d8d5-4f93-8a22-f9bfae07327f |
Внешний отчет |
e41aff26-25cf-4bb6-b6c1-3f478a75f374 |
Таблица видов метаданных с постфиксами единичных частей
Виды метаданных |
ID вида метаданного |
Модуль |
Справочная информация |
Предопре-деленные значения |
объекта/набора записей |
менед-жера |
Интерфейсы |
39bddf6a-0c3c-452b-921c-d99cfa1c2f1b |
|
|
|
|
Подсистемы |
37f2fa9a-b276-11d4-9435-004095e12fc7 |
|
|
|
|
Общие модули |
0fe48980-252d-11d6-a3c7-0050bae0a776 |
|
|
|
|
Параметры сеанса |
24c43748-c938-45d0-8d14-01424a72b11e |
|
|
|
|
Роли |
09736b02-9cac-4e3f-b4f7-d3e9576ab948 |
|
|
|
|
Общие реквизиты |
15794563-ccec-41f6-a83c-ec5f7b9a5bc1 |
|
|
|
|
Планы обмена |
857c4a91-e5f4-4fac-86ec-787626f1c108 |
2 |
3 |
0 |
|
Критерии отбора |
3e7bfcc0-067d-11d6-a3c7-0050bae0a776 |
|
0 |
|
|
Подписки на события |
4e828da6-0f44-4b5b-b1c0-a2b3cfe7bdcc |
|
|
|
|
Регламентные задания |
11bdaf85-d5ad-4d91-bb24-aa0eee139052 |
|
|
|
|
Боты |
6e6dc072-b7ac-41e7-8f88-278d25b6da2a |
1 |
|
|
|
Функциональные опции |
af547940-3268-434f-a3e7-e47d6d2638c3 |
|
|
|
|
Параметры функциональных опций |
30d554db-541e-4f62-8970-a1c6dcfeb2bc |
|
|
|
|
Определяемые типы |
c045099e-13b9-4fb6-9d50-fca00202971e |
|
|
|
|
Хранилища настроек |
46b4cd97-fd13-4eaa-aba2-3bddd7699218 |
|
8 |
|
|
Общие команды |
2f1a5187-fb0e-4b05-9489-dc5dd6412348 |
2 |
|
1 |
|
Группы команд |
1c57eabe-7349-44b3-b1de-ebfeab67b47d |
|
|
|
|
Общие формы |
07ee8426-87f1-11d5-b99c-0050bae0a95d |
|
|
1 |
|
Общие макеты |
0c89c792-16c3-11d5-b96b-0050bae0a95d |
|
|
|
|
Общие картинки |
7dcd43d9-aca5-4926-b549-1842e6a4e8cf |
|
|
|
|
XDTO-пакеты |
cc9df798-7c94-4616-97d2-7aa0b7bc515e |
|
|
|
|
Web-сервисы |
8657032e-7740-4e1d-a3ba-5dd6e8afb78f |
0 |
|
|
|
HTTP-сервисы |
0fffc09c-8f4c-47cc-b41c-8d5c5a221d79 |
0 |
|
|
|
WS-ссылки |
d26096fb-7a5d-4df9-af63-47d04771fa9b |
|
|
|
|
Сервисы интеграции |
bf3420b0-f6f9-41a0-b83a-fe9d4ab0b65d |
0 |
|
|
|
Элементы стиля |
58848766-36ea-4076-8800-e91eb49590d7 |
|
|
|
|
Стили |
3e5404af-6ef8-4c73-ad11-91bd2dfac4c8 |
|
|
|
|
Языки |
9cd510ce-abfc-11d4-9434-004095e12fc7 |
|
|
|
|
Константы |
0195e80c-b157-11d4-9435-004095e12fc7 |
0 |
1 |
|
|
Справочники |
cf4abea6-37b2-11d4-940f-008048da11f9 |
0 |
3 |
1 |
1c |
Документы |
061d872a-5787-460e-95ac-ed74ea3a3e84 |
0 |
2 |
1 |
|
Нумераторы |
36a8e346-9aaa-4af9-bdbd-83be3c177977 |
|
|
|
|
Последовательности |
bc587f20-35d9-11d6-a3c7-0050bae0a776 |
|
|
|
|
Журналы документов |
4612bd75-71b7-4a5c-8cc5-2b0b65f9fa0d |
|
1 |
0 |
|
Перечисления |
f6a80749-5ad7-400b-8519-39dc5dff2542 |
|
0 |
|
|
Отчеты |
631b75a0-29e2-11d6-a3c7-0050bae0a776 |
0 |
2 |
1 |
|
Обработки |
bf845118-327b-4682-b5c6-285d2a0eb296 |
0 |
2 |
1 |
|
Планы видов характеристик |
82a1b659-b220-4d94-a9bd-14d757b95a48 |
15 |
16 |
5 |
7 |
Планы счетов |
238e7e88-3c5f-48b2-8a3b-81ebbecb20ed |
14 |
15 |
5 |
9 |
Планы видов расчета |
30b100d6-b29f-47ac-aec7-cb8ca8a54767 |
1 |
3 |
0 |
2 |
Регистры сведений |
13134201-f60b-11d5-a3c7-0050bae0a776 |
1 |
2 |
0 |
|
Регистры накопления |
b64d9a40-1642-11d6-a3c7-0050bae0a776 |
1 |
2 |
0 |
|
Регистры бухгалтерии |
2deed9b8-0056-4ffe-a473-c20a6c32a0bc |
6 |
7 |
5 |
|
Регистры расчета |
f2de87a8-64e5-45eb-a22d-b3aedab050e7 |
1 |
2 |
0 |
|
Перерасчеты |
274bf899-db0e-4df6-8ab5-67bf6371ec0b |
0 |
|
|
|
Бизнес-процессы |
fcd3404e-1523-48ce-9bc0-ecdb822684a1 |
6 |
8 |
5 |
|
Задачи |
3e63355c-1378-4953-be9b-1deb5fb6bec5 |
6 |
7 |
5 |
|
Внешние источники данных |
5274d9fc-9c3a-4a71-8f5e-a0db8ab23de5 |
|
|
|
|
Внешние обработки |
c3831ec8-d8d5-4f93-8a22-f9bfae07327f |
0 |
|
1 |
|
Внешние отчеты |
e41aff26-25cf-4bb6-b6c1-3f478a75f374 |
0 |
|
1 |
|
Таблица видов метаданных с частями переменного количества
Виды метаданных |
Формы |
Команды |
Макеты |
Планы обмена |
87c509ab-3d38-4d67-b379-aca796298578 |
d5207c64-11d5-4d46-bba2-55b7b07ff4e |
+ |
Критерии отбора |
00867c40-06b1-11d6-a3c7-0050bae0a776 |
23fa3b84-220a-40e9-8331-e588bed87f7d |
- |
Хранилища настроек |
b8533c0c-2342-4db3-91a2-c2b08cbf6b23 |
|
+ |
Справочники |
fdf816d2-1ead-11d5-b975-0050bae0a95d |
4fe87c89-9ad4-43f6-9fdb-9dc83b3879c6 |
+ |
Документы |
fb880e93-47d7-4127-9357-a20e69c17545 |
b544fc6a-2ba3-4885-8fb2-cb289fb6d65e |
+ |
Журналы документов |
ec81ad10-ca07-11d5-b9a5-0050bae0a95d |
a49a35ce-120a-4c80-8eea-b0618479cd70 |
+ |
Перечисления |
33f2e54b-37ce-4a7a-a569-b648d7aa4634 |
6d8d73a7-ba29-401d-9032-3872ec2d6433 |
+ |
Отчеты |
a3b368c0-29e2-11d6-a3c7-0050bae0a776 |
e7ff38c0-ec3c-47a0-ae90-20c73ca72246 |
+ |
Обработки |
d5b0e5ed-256d-401c-9c36-f630cafd8a62 |
45556acb-826a-4f73-898a-6025fc9536e1 |
+ |
Планы видов характеристик |
eb2b78a8-40a6-4b7e-b1b3-6ca9966cbc94 |
95b5e1d4-abfa-4a16-818d-a5b07b7d3f73 |
+ |
Планы счетов |
5372e285-03db-4f8c-8565-fe56f1aea40e |
0df30176-6865-4787-9fc8-609eb144174f |
+ |
Планы видов расчета |
a7f8f92a-7a4b-484b-937e-42d242e64144 |
2e90c75b-2f0c-4899-a7d4-5426eaefc96e |
+ |
Регистры сведений |
13134204-f60b-11d5-a3c7-0050bae0a776 |
b44ba719-945c-445c-8aab-1088fa4df16e |
+ |
Регистры накопления |
b64d9a44-1642-11d6-a3c7-0050bae0a776 |
99f328af-a77f-4572-a2d8-80ed20c81890 |
+ |
Регистры бухгалтерии |
d3b5d6eb-4ea2-4610-a3e2-624d4e815934 |
7162da60-f7fe-4d78-ad5d-e31700f9af18 |
+ |
Регистры расчета |
a2cb086c-db98-43e4-a1a9-0760ab048f8d |
acdf0f11-2d59-4e37-9945-c6721871a8fe |
+ |
Бизнес-процессы |
3f7a8120-b71a-4265-98bf-4d9bc09b7719 |
7a3e533c-f232-40d5-a932-6a311d2480bf |
+ |
Задачи |
3f58cbfb-4172-4e54-be49-561a579bb38b |
f27c2152-a2c9-4c30-adb1-130f5eb2590f |
+ |
Внешние обработки |
d5b0e5ed-256d-401c-9c36-f630cafd8a62 |
|
+ |
Внешние отчеты |
a3b368c0-29e2-11d6-a3c7-0050bae0a776 |
|
+ |
Для всех видов метаданных id макетов: 3daea016-69b7-4ed4-9453-127911372fe6.
Виды метаданных ID вида метаданного Модуль объекта/ набора записей Модуль менеджера Справочная информация Предопределенные значения Формы Команды Макеты
Неизвестный вид метаданных 39bddf6a-0c3c-452b-921c-d99cfa1c2f1b
Подсистемы 37f2fa9a-b276-11d4-9435-004095e12fc7
Общие модули 0fe48980-252d-11d6-a3c7-0050bae0a776
Параметры сеанса 24c43748-c938-45d0-8d14-01424a72b11e
Роли 09736b02-9cac-4e3f-b4f7-d3e9576ab948
Общие реквизиты 15794563-ccec-41f6-a83c-ec5f7b9a5bc1
Планы обмена 857c4a91-e5f4-4fac-86ec-787626f1c108 2 3 0 87c509ab-3d38-4d67-b379-aca796298578 d5207c64-11d5-4d46-bba2-55b7b07ff4e 3daea016-69b7-4ed4-9453-127911372fe6
Критерии отбора 3e7bfcc0-067d-11d6-a3c7-0050bae0a776 0 00867c40-06b1-11d6-a3c7-0050bae0a776 23fa3b84-220a-40e9-8331-e588bed87f7d
Подписки на события 4e828da6-0f44-4b5b-b1c0-a2b3cfe7bdcc
Регламентные задания 11bdaf85-d5ad-4d91-bb24-aa0eee139052
Боты 6e6dc072-b7ac-41e7-8f88-278d25b6da2a 1
Функциональные опции af547940-3268-434f-a3e7-e47d6d2638c3
Параметры функциональных опций 30d554db-541e-4f62-8970-a1c6dcfeb2bc
Определяемые типы c045099e-13b9-4fb6-9d50-fca00202971e
Хранилища настроек 46b4cd97-fd13-4eaa-aba2-3bddd7699218 8 b8533c0c-2342-4db3-91a2-c2b08cbf6b23 3daea016-69b7-4ed4-9453-127911372fe6
Общие команды 2f1a5187-fb0e-4b05-9489-dc5dd6412348 2 1
Группы команд 1c57eabe-7349-44b3-b1de-ebfeab67b47d
Общие формы 07ee8426-87f1-11d5-b99c-0050bae0a95d 1
Общие макеты 0c89c792-16c3-11d5-b96b-0050bae0a95d
Общие картинки 7dcd43d9-aca5-4926-b549-1842e6a4e8cf
XDTO-пакеты cc9df798-7c94-4616-97d2-7aa0b7bc515e
Web-сервисы 8657032e-7740-4e1d-a3ba-5dd6e8afb78f 0
HTTP-сервисы 0fffc09c-8f4c-47cc-b41c-8d5c5a221d79 0
WS-ссылки d26096fb-7a5d-4df9-af63-47d04771fa9b
Сервисы интеграции bf3420b0-f6f9-41a0-b83a-fe9d4ab0b65d 0
Элементы стиля 58848766-36ea-4076-8800-e91eb49590d7
Стили 3e5404af-6ef8-4c73-ad11-91bd2dfac4c8
Языки 9cd510ce-abfc-11d4-9434-004095e12fc7
Константы 0195e80c-b157-11d4-9435-004095e12fc7 0 1
Справочники cf4abea6-37b2-11d4-940f-008048da11f9 0 3 1 1c fdf816d2-1ead-11d5-b975-0050bae0a95d 4fe87c89-9ad4-43f6-9fdb-9dc83b3879c6 3daea016-69b7-4ed4-9453-127911372fe6
Документы 061d872a-5787-460e-95ac-ed74ea3a3e84 0 2 1 fb880e93-47d7-4127-9357-a20e69c17545 b544fc6a-2ba3-4885-8fb2-cb289fb6d65e 3daea016-69b7-4ed4-9453-127911372fe6
Нумераторы 36a8e346-9aaa-4af9-bdbd-83be3c177977
Последовательности bc587f20-35d9-11d6-a3c7-0050bae0a776
Журналы документов 4612bd75-71b7-4a5c-8cc5-2b0b65f9fa0d 1 0 ec81ad10-ca07-11d5-b9a5-0050bae0a95d a49a35ce-120a-4c80-8eea-b0618479cd70 3daea016-69b7-4ed4-9453-127911372fe6
Перечисления f6a80749-5ad7-400b-8519-39dc5dff2542 0 33f2e54b-37ce-4a7a-a569-b648d7aa4634 6d8d73a7-ba29-401d-9032-3872ec2d6433 3daea016-69b7-4ed4-9453-127911372fe6
Отчеты 631b75a0-29e2-11d6-a3c7-0050bae0a776 0 2 1 a3b368c0-29e2-11d6-a3c7-0050bae0a776 e7ff38c0-ec3c-47a0-ae90-20c73ca72246 3daea016-69b7-4ed4-9453-127911372fe6
Обработки bf845118-327b-4682-b5c6-285d2a0eb296 0 2 1 d5b0e5ed-256d-401c-9c36-f630cafd8a62 45556acb-826a-4f73-898a-6025fc9536e1 3daea016-69b7-4ed4-9453-127911372fe6
Планы видов характеристик 82a1b659-b220-4d94-a9bd-14d757b95a48 15 16 5 7 eb2b78a8-40a6-4b7e-b1b3-6ca9966cbc94 95b5e1d4-abfa-4a16-818d-a5b07b7d3f73 3daea016-69b7-4ed4-9453-127911372fe6
Планы счетов 238e7e88-3c5f-48b2-8a3b-81ebbecb20ed 14 15 5 9 5372e285-03db-4f8c-8565-fe56f1aea40e 0df30176-6865-4787-9fc8-609eb144174f 3daea016-69b7-4ed4-9453-127911372fe6
Планы видов расчета 30b100d6-b29f-47ac-aec7-cb8ca8a54767 1 3 0 2 a7f8f92a-7a4b-484b-937e-42d242e64144 2e90c75b-2f0c-4899-a7d4-5426eaefc96e 3daea016-69b7-4ed4-9453-127911372fe6
Регистры сведений 13134201-f60b-11d5-a3c7-0050bae0a776 1 2 0 13134204-f60b-11d5-a3c7-0050bae0a776 b44ba719-945c-445c-8aab-1088fa4df16e 3daea016-69b7-4ed4-9453-127911372fe6
Регистры накопления b64d9a40-1642-11d6-a3c7-0050bae0a776 1 2 0 b64d9a44-1642-11d6-a3c7-0050bae0a776 99f328af-a77f-4572-a2d8-80ed20c81890 3daea016-69b7-4ed4-9453-127911372fe6
Регистры бухгалтерии 2deed9b8-0056-4ffe-a473-c20a6c32a0bc 6 7 5 d3b5d6eb-4ea2-4610-a3e2-624d4e815934 7162da60-f7fe-4d78-ad5d-e31700f9af18 3daea016-69b7-4ed4-9453-127911372fe6
Регистры расчета f2de87a8-64e5-45eb-a22d-b3aedab050e7 1 2 0 a2cb086c-db98-43e4-a1a9-0760ab048f8d acdf0f11-2d59-4e37-9945-c6721871a8fe 3daea016-69b7-4ed4-9453-127911372fe6
Перерасчеты 274bf899-db0e-4df6-8ab5-67bf6371ec0b 0
Бизнес-процессы fcd3404e-1523-48ce-9bc0-ecdb822684a1 6 8 5 3f7a8120-b71a-4265-98bf-4d9bc09b7719 7a3e533c-f232-40d5-a932-6a311d2480bf 3daea016-69b7-4ed4-9453-127911372fe6
Задачи 3e63355c-1378-4953-be9b-1deb5fb6bec5 6 7 5 3f58cbfb-4172-4e54-be49-561a579bb38b f27c2152-a2c9-4c30-adb1-130f5eb2590f 3daea016-69b7-4ed4-9453-127911372fe6
Внешние источники данных 5274d9fc-9c3a-4a71-8f5e-a0db8ab23de5
Внешние обработки c3831ec8-d8d5-4f93-8a22-f9bfae07327f 0 1 d5b0e5ed-256d-401c-9c36-f630cafd8a62 3daea016-69b7-4ed4-9453-127911372fe6
Внешние отчеты e41aff26-25cf-4bb6-b6c1-3f478a75f374 0 1 a3b368c0-29e2-11d6-a3c7-0050bae0a776 3daea016-69b7-4ed4-9453-127911372fe6
Постфиксы частей метаданных переменного количества
Формы: 0 - Форма и модуль, 1 - Справочная информация.
Команды: 2 - Модуль команды.
Макеты: 0 - Макет.
Перерасчеты: 0 - Модуль набора записей.
Описание формата схемы компоновки данных
Данные этого формата состоят из вычисляемого двоичного заголовка и текстового тела в UTF-8 с BOM.
Двоичный заголовок имеет вид: 4 байта с ‘0’, 4-х байтовое представление количества разделов Settings текстовой части, список 8-ми байтовых смещений адреса раздела относительно предыдущего. Например, заголовок схемы из 6 разделов выглядит так:
Кол-во разделов Settings, 4 370298 – смещение 1 раздела Settings
00 00 00 00 04 00 00 00 7A A6 05 00 00 00 00 00
30088 – смещение 2-го 31352 – смещение 3-го
88 75 00 00 00 00 00 00 78 7A 00 00 00 00 00 00
12639 – смещение 4-го 14797 – длина 4-го раздела
5F 31 00 00 00 00 00 00 CD 39 00 00 00 00 00 00
Текстовая часть состоит из раздела SchemaFile, за которым следуют один или несколько разделов Settings. Заканчиваются данные пустым разделом SchemaFile. Перед каждым разделом идёт объявление xml <?xml version="1.0" encoding="UTF-8"?> с BOM.
Описание формата табличного документа
Данные этого формата состоят из двоичного заголовка 4D 4F 58 43 45 4C 00 08 00 01 00 0B 00 и текстового тела в UTF-8 с BOM.
БНФ - форма Бэкуса - Наура.
<Контейнер 1С> ::= < Контейнер 1С , 32-х адресация>|<Заполнитель, 32-х адресация><Контейнер 1С, 64-х адресация>
БНФ версии с 32-х разрядной адресацией
<Контейнер 1С, 32-х адресация> ::= <Заголовок, 32-х адресация><Документ адресов файлов, 32-х адресация>[<Список файлов, 32-х адресация>]
<Заголовок, 32-х адресация> ::= <Адрес первого пустого блока, 32-х адресация><Размер блока по умолчанию, 32-х адресация><Количество файлов в контейнере, 32-х адресация><Пустое значение, 32-х адресация> //Длина 16 байт
<Адрес первого пустого блока, 32-х адресация> ::= 7F FF FF FF | <Число int32 LE> //Число int32 LE, если пустых блоков нет, равен INT32_MAX (2 147 483 647, 0x7fffffff).
<Размер блока по умолчанию, 32-х адресация> ::= <Число int32 LE> //обычно 512 байтов
<Количество файлов в контейнере, 32-х адресация> ::= <Число int32 LE>
<Пустое значение, 32-х адресация> ::= 00 00 00 00
<Документ адресов файлов, 32-х адресация> ::= <Запись адреса, 32-х адресация>[<Документ адресов файлов, 32-х адресация>]
<Запись адреса, 32-х адресация> ::= <Адрес документа атрибутов, 32-х адресация><Адрес документа содержимого, 32-х адресация><Зарезервированное поле, 32-х адресация> //Длина 12 байтов
<Адрес документа атрибутов, 32-х адресация> ::= <Число int32 LE>
<Адрес документа содержимого, 32-х адресация> ::= <Число int32 LE>
<Зарезервированное поле, 32-х адресация> ::= 7F FF FF FF //Число int32 LE, всегда равно INT32_MAX (2 147 483 647, 0x7fffffff).
<Список файлов, 32-х адресация> ::= <Файл, 32-х адресация>[<Список файлов, 32-х адресация>]
<Файл, 32-х адресация> ::= <Документ атрибутов, 32-х адресация><Документ содержимого файла, 32-х адресация>
<Документ атрибутов, 32-х адресация> ::= <Список блоков, 32-х адресация>
<Документ содержимого файла, 32-х адресация> ::= <Cписок блоков, 32-х адресация> //Документ содержимого всегда идёт сразу за документом атрибутов. Обязательное ли это условие, неизвестно.
<Список блоков, 32-х адресация> ::= <Первый блок списка, 32-х адресация>[<Байты>][<Блок, 32-х адресация>[<Байты>][<Список блоков, 32-х адресация>]]
<Первый блок списка, 32-х адресация> ::= <Заголовок первого блока, 32-х адресация><Тело блока, 32-х адресация> // 31 байт
<Заголовок первого блока, 32-х адресация> ::= <CRLF><Размер всего документа, 32-х адресация><Пробел><Размер текущего блока, 32-х адресация><Пробел><Адрес следующего блока, 32-х адресация><Пробел><CRLF>
<Блок, 32-х адресация> ::= <Заголовок блока, 32-х адресация><Тело блока, 32-х адресация>
<Заголовок блока, 32-х адресация> ::= <CRLF><Пустое значение, 32-х адресация><Пробел><Размер текущего блока, 32-х адресация><Пробел><Адрес следующего блока, 32-х адресация><Пробел><CRLF> //31 байт
<Размер всего документа, 32-х адресация> ::= <hex - число, длина 8 байт>
<Размер текущего блока, 32-х адресация> ::= <hex - число, длина 8 байт>
<Адрес следующего блока, 32-х адресация> ::= <hex - число, длина 8 байт> //если следующего блока нет, тогда INT32_MAX.
<Тело блока, 32-х адресация> ::= <Сжатое по алгоритму deflate содержимое> // Набор байтов, указанного в <Заголовок блока, 32-х адресация> в <Размер текущего блока, 32-х адресация> размера.
<Сжатое по алгоритму deflate содержимое> :: = <Содержимое> | <Контейнер 1С, 32-х адресация>
<Содержимое> :: = <Байты>
<Число int32 LE> ::= <Байт><Байт><Байт><Байт> // Не больше 2 147 483 647, 0x7fffffff. LE - Порядок байтов
<hex - число, длина 8 байт> :: = <цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра>
<CRLF> ::= 0D 0A // \r\n(0x0D, 0x0A)
<Пробел> ::= " " // 0x20
<Байты> ::= <Байт>[<Байты>]
<Байт> ::= <цифра>[<цифра>] //Не более 255
<цифра> ::= 0|1|2|3|4|5|6|7|8|9
БНФ версии с 64-х разрядной адресацией
<Заполнитель, 32-х адресация> :: = <Контейнер 1С, 32-х адресация> //Заполнитель длиной 4953, всегда стандартный, содержит 5 файлов.
<Контейнер 1С, 64-х адресация> ::= <Заголовок, 64-х адресация><Документ адресов файлов, 64-х адресация>[<Список файлов, 64-х адресация>]
<Заголовок, 64-х адресация> ::= <Адрес первого пустого блока, 64-х адресация><Размер блока по умолчанию, 32-х адресация><Количество файлов в контейнере, 32-х адресация><Пустое значение, 32-х адресация> //Длина 20 байт
<Адрес первого пустого блока, 64-х адресация> ::= FF FF FF FF FF FF FF FF | <Число uint64 LE> //Число uint64 LE, если пустых блоков нет, равен UINT64_MAX (0xfffffffffffffff).
<Размер блока по умолчанию, 32-х адресация> ::= <Число int32 LE> //обычно 512 байтов
<Количество файлов в контейнере, 32-х адресация> ::= <Число int32 LE>
<Пустое значение, 32-х адресация> ::= 00 00 00 00
<Документ адресов файлов, 64-х адресация> ::= <Запись адреса, 64-х адресация>[<Документ адресов файлов, 64-х адресация>]
<Запись адреса, 64-х адресация> ::= <Адрес документа атрибутов, 64-х адресация><Адрес документа содержимого, 64-х адресация><Зарезервированное поле, 64-х адресация> //Длина 24 байта
<Адрес документа атрибутов, 64-х адресация> ::= <Число uint64 LE>
<Адрес документа содержимого, 64-х адресация> ::= <Число uint64 LE>
<Зарезервированное поле, 64-х адресация> ::= FF FF FF FF FF FF FF FF //Число uint64 LE, всегда равно UINT64_MAX (0xfffffffffffffff).
<Список файлов, 64-х адресация> ::= <Файл, 64-х адресация>[<Список файлов, 64-х адресация>]
<Файл, 64-х адресация> ::= <Документ атрибутов, 64-х адресация><Документ содержимого файла, 64-х адресация>
<Документ атрибутов, 64-х адресация> ::= <Список блоков, 64-х адресация>
<Документ содержимого файла, 64-х адресация> ::= <Cписок блоков, 64-х адресация> //Документ содержимого всегда идёт сразу за документом атрибутов. Обязательное ли это условие, неизвестно.
<Список блоков, 64-х адресация> ::= <Первый блок списка, 64-х адресация>[<Байты>][<Блок, 64-х адресация>[<Байты>][<Список блоков, 64-х адресация>]]
<Первый блок списка, 64-х адресация> ::= <Заголовок первого блока, 64-х адресация><Тело блока, 64-х адресация>
<Заголовок первого блока, 64-х адресация> ::= <CRLF><Размер всего документа, 64-х адресация><Пробел><Размер текущего блока, 64-х адресация><Пробел><Адрес следующего блока, 64-х адресация><Пробел><CRLF> //55 байтов
<Блок, 64-х адресация> ::= <Заголовок блока, 64-х адресация><Тело блока, 64-х адресация>
<Заголовок блока, 64-х адресация> ::= <CRLF><Пустое значение, 32-х адресация><Пробел><Размер текущего блока, 64-х адресация><Пробел><Адрес следующего блока, 64-х адресация><Пробел><CRLF> //55 байтов
<Размер всего документа, 64-х адресация> ::= <hex - число, длина 16 байт>
<Размер текущего блока, 64-х адресация> ::= <hex - число, длина 16 байт>
<Адрес следующего блока, 64-х адресация> ::= <hex - число, длина 16 байт> //если следующего блока нет, тогда UINT64_MAX.
<Тело блока, 64-х адресация> ::= <Сжатое по алгоритму deflate содержимое> // Набор байтов, указанного в <Заголовок блока, 64-х адресация> в <Размер текущего блока, 64-х адресация> размера.
<Сжатое по алгоритму deflate содержимое> :: = <Содержимое> | <Контейнер 1С, 32-х адресация>
<Содержимое> :: = <Байты>
<Число int32 LE> ::= <Байт><Байт><Байт><Байт> //Не больше 2 147 483 647, 0x7fffffff. LE - Порядок байтов
<Число uint64 LE> ::= <Байт><Байт><Байт><Байт><Байт><Байт><Байт><Байт>
<hex - число, длина 16 байт> :: = <цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра><цифра>
<CRLF> ::= 0D 0A // \r\n(0x0D, 0x0A)
<Пробел> ::= " " // 0x20
<Байты> ::= <Байт>[<Байты>]
<Байт> ::= <цифра>[<цифра>] //Не более 255
<цифра> ::= 0|1|2|3|4|5|6|7|8|9
Описание обработки
Обработка предназначена как для работы с метаданными, так и для работы с контейнером. Для метаданных поддерживается только чтение. Для работы с контейнером: CRUD файлов, выгрузка файлов в директорию и загрузка файлов из директории в контейнер. Для выгрузки и загрузки файлов используется форма с индикатором уровня выполнения процесса. Выполнение этих операций может быть прервано кнопкой Отмена.
В обработке 5 закладок: Метаданные, Закрытые модули, Файлы, Выгрузить в директорию, Загрузить из директории.
На закладке Метаданные отображается дерево метаданных контейнера, аналогично конфигуратору 1С:
При выводе содержимого файла можно задать объём данных: 100Кб, 1Мб, не ограничено. Это сделано из-за того, что отображение больших файлов (versions, например) занимает очень много времени (минут 20).
На закладке Закрытые модули выводятся только те модули, которые закрыты паролями:
На закладке Файлы можно просмотреть файловую структуру контейнера. Кроме этого, для каждого файла есть возможность узнать его принадлежность к метаданным.
На этой же закладке реализована работа с CRUD: создание, обновление, удаление файла. Для создания и обновления файлов служит форма:
В форме создания/обновления файла находятся команды сохранения и загрузки содержимого. Работа этих команд зависит от выбранного типа содержимого файла. По умолчанию это ТекстовыеДанные. В этом режиме содержимым может быть только текст. В текстовом формате в контейнере хранится практически всё: картинки, внешние компоненты, атрибуты и т.д. Двоичные данные (картинки, ВК и т.д.) помещаются в base64.
Но есть 3 исключения: файл Текст (text) закрытого паролем модуля (ДвоичныеДанные), табличный документ (ТабличныйДокумент), схема компоновки данных (СхемаКомпоновкиДанных). Для работы с этими исключениями в типе данных нужно выбрать соответствующее значение. В этом случае обработка преобразует из текстового формата в формат для записи в контейнер. Например, для создания файла с типом макета "Табличным документ", нужно выбрать тип содержимого ТабличныйДокумент и набрать текст самого документа в текстовом формате. При сохранении в контейнер содержимому файла будет добавлен двоичный заголовок. Аналогично с макетом типа "Схема компоновки данных". Что интересно, все остальные типы макетов сохраняются в текстовом формате.
Тот же алгоритм действий при необходимости загрузки/выгрузке содержимого файла на диск. Открываем файл для обновления, сохраняем содержимое на диск. Необходимые двоичные заголовки будут добавлены обработкой. Двоичные данные архива закрытого модуля (файл text) будут извлечены/помещены в base64.
Для создания файла внутри папки следует использовать знак "\" после id. Например, 0004654c-f91f-463d-a529-e23bb363ed21.1\text.
Чтобы удалить папку, необходимо удалить все её файлы.
Описание внешней компоненты
Внешняя компонента написана по технологии Native и работает в режимах сервера, тонкого клиента и веб-клиента для браузеров Chrome и Firefox. Поддерживаются OC Windows и Linux, платформа 1С с версии 8.3.18 32/64. На сервере компонента поддерживает типы подключения Изолированно и НеИзолированно.
Внешняя компонента тестировалась на платформах 1С версий 8.3.23.1739 (х64) и 8.3.21.1302 (х32), в клиентском и серверном режимах. Для тестирования использовались контейнеры:
32-х разрядная адресация: БП 1.6.25.6_.cf, SSL 2.4.2.47.cf, ДекомпиляторAWA Полный.epf (обычные формы), Расширение.cfe (произвольное расширение), КонсольЗапросов.epf (из комплекта SSL 3.1.8.334), СтатистикаВыполненияОбработчиковОбновления.erf (из комплекта SSL 3.1.8.334).
64-х разрядная адресация: ERP 2.5.12.48.cf, SSL 3.1.8.334.cf.
Функции:
Метаданные/Metadata (Имя файла контейнера) – возвращает JSON со структурой метаданных контейнера.
ЗапароленныеМодули /PasswordProtectedModules (Имя файла контейнера) - возвращает JSON со структурой метаданных контейнера, содержащий защищенные паролем модули в виде дерева.
ЗапароленныеМодулиСписок /PasswordProtectedModulesList (Имя файла контейнера) - возвращает JSON со структурой метаданных контейнера, содержащий защищенные паролем модули в виде списка (версия 1.1.0.1).
СтруктураМетаданного/MetadataStructure (Имя файла контейнера, ИД метаданного) - возвращает JSON со структурой указанного метаданного. Если метаданное не найдено, вызывается исключение.
МетаданныеФайла/MetadataForFile(Имя файла контейнера, ИД файла) – для указанного файла возвращается JSON со структурой указанного метаданного, в состав которого этот файл входит. Если файл не входит в состав метаданного, возвращается пустая строка.
Файлы/Files (Имя файла контейнера, Сортировка) - возвращает JSON со списком отсортированных файлов. Сортировка может принимать значения: 0 – сортировать по имени, 1 – сортировать как «список файлов в Windows», 2 – учитывать длину ИД.
ФайлыПагинация/FilesPagination(Имя файла контейнера, Сортировка, Начало, Окончание) - возвращает JSON со списком отсортированных файлов с Начало по Окончание. Сортировка может принимать значения: 0 – сортировать по имени, 1 – сортировать как «список файлов в Windows», 2 – учитывать длину ИД. Начало - номер первой записи, Окончание - номер последней записи.
ПолучитьФайл/ReadFile (Имя файла контейнера, ИД файла, Максимальный размер файла) – возвращает JSON с содержимым файла и типом содержимого.
ОформитьСхемуКомпоновкиДанных /putTitleToScheme (Текстовая часть схемы компоновки данных) – добавляет к переданному тексту заголовок схемы компоновки данных. Возвращает двоичные данные.
ТекстПоследнейОшибки /GetLastError () – возвращает текст ошибки, если она была. Иначе возвращает пустую строку. Вызов функции стирает прежнее значение ошибки. Список сообщений об ошибке: Ошибка формата контейнера, Ошибка открытия контейнера, Ошибка чтения контейнера, Ошибка позиционирования в контейнере, Ошибка записи в контейнер, Контейнер пуст, Id не найден, Файл root/configinfo не найден, Ошибка в структуре метаданного, Ошибка создания файла, Ошибка записи файла, Ошибка создания директории, Недостаточно памяти, Файл является директорией, Файл не является директорие, Файл уже существует, Файл не существует, Ошибка разархивирования, Ошибка архивирования, Ошибка потока, В директории нет файлов, Ошибка чтения файла, Найдена циклическая ссылка, Слишком большой размер архива, Слишком большой размер файла, Ошибка формата схемы компоновки данных, Ошибка преобразования в UTF-8, Ошибка создания GUID, Прочитана не вся цепочка блоков, Имя файла контейнера не задано, Id не задан, Метод предназначен только для клиентского режима.
Процедуры:
ВыгрузитьФайлы /ExtractFiles(Имя файла контейнера, Директория, Количество потоков) – выгружает из контейнера файлы в казанную директорию. Директории в момент вызова процедуры не должно быть, иначе вызывается исключение. Количество потоков может быть от 0 (без потоков) до 2048. Оптимальная величина зависит от компьютера и, вероятно, не может превышать 64.
ЗагрузитьФайлы/DownloadFiles(Имя файла контейнера, Директория) – загружает файлы из директории в контейнер. Содержимое контейнера полностью очищается. Содержимое грузится «как есть».
СоздатьФайл/CreateFile(Имя файла контейнера, ИД файла, Содержимое файла, Тип содержимого файла) – создаёт файл с указанным ИД и содержимым. Тип содержимого файла может принимать значения: ТекстовыеДанные, ДвоичныеДанные, ТабличныйДокумент, СхемаКомпоновкиДанных. Если параметр содержит другое значение, он считается равным ТекстовыеДанные. Тип ДвоичныеДанные подразумевает, что в Содержимое файла переданы двоичные данные в формате Base64. ТабличныйДокумент – смотрите описание формата табличного документа. СхемаКомпоновкиДанных – смотрите описание формата схемы компоновки данных. При создании папки – файла, содержащего другие файлы, необходимо использовать знак «\»: <Имя папки>\<имя файла>. Например: 00035364-b591-4e6a-9219-e27dac18f687.1\info.
ОбновитьФайл/UpdateFile(Имя файла контейнера, ИД файла, Содержимое файла, Тип содержимого файла) – обновляет файл с указанным ИД. При этом тип содержимого может меняться. Если файл с ИД не найден, вызывается исключение. Если необходимо обновить файл в папке, используется знак «\», например: 00035364-b591-4e6a-9219-e27dac18f687.1\info.
УдалитьФайл/DeleteFile(Имя файла контейнера, ИД файла) – удаляет из контейнера файл с указанным ИД. Если файл с ИД не найден, вызывается исключение. Если для папки удаляемый файл является последним, то удаляется вся папка целиком.
Процедуры для запуска только на клиенте:
НачатьВыгрузкуФайлов/BeginExtractFilesToDirectory(Имя файла контейнера, Директория, Количество потоков) – запускает отдельный поток, в остальном работает аналогично ВыгрузитьФайлы. В ходе выполнения, при достижении каждого процента посылает сообщение в 1С. Сообщение может обрабатываться в процедуре ВнешнееСобытие(Источник, Событие, Данные). При этом Источник = "Container1C", Событие может принимать значения "ХодВыполнения", "Завершение", "Ошибка". Если Событие = "ХодВыполнения", Данные содержит проценты выполненной выгрузки. Метод может применяться только на клиенте, при вызове на сервере генерируется исключение и метод ТекстПоследнейОшибки возвращает сообщение: "Метод предназначен только для клиентского режима".
НачатьЗагрузкуФайлов/BeginDownloadFiles(Имя файла контейнера, Директория, Актуализировать версии кэшей) - запускает отдельный поток, в остальном работает аналогично ЗагрузитьФайлы. Ход выполнения аналогичен НачатьВыгрузкуФайлов. Метод может применяться только на клиенте, при вызове на сервере генерируется исключение и метод ТекстПоследнейОшибки возвращает сообщение: "Метод предназначен только для клиентского режима". Параметр Актуализировать версии кэшей вызывает срабатывание метода АктуализироватьVersions после успешной загрузки.
ПрерватьОперацию/AbortLongTimeOperation() – вызов процедуры прерывает работу запущенной процедуры НачатьВыгрузкуФайлов или НачатьЗагрузкуФайлов. Данные при этом остаются в том состоянии, в котором была прервана их обработка. При выгрузке файлы будут недогружены в директорию, при загрузке – в контейнер. При прерванной загрузке контейнер будет испорчен.
АктуализироватьVersions/actualizeVersions(Имя файла контейнера) - актуализирует версии кэшей 1С. Для версии 6 (8.0) в файлах versions и metadata\root, для расширений в configinfo, для всех остальных - в versions. Если файл был добавлен в контейнер, он добавляется в список кэшей, если удалён - удаляется из списка.
Для не расширений: если файл был обновлен в текущем сеансе работы с контейнером, его версия кэша (GUID) обновляется в списке. Таким образом, предполагается вызов метода после завершения работы над изменением файлов. Если метод вызвать в другом сеансе работы с ВК, то данные об обновлениях будут утеряны. Новые/удаленные файлы будут добавлены/исключены из списка кэшей вне зависимости от сеанса.
Для расширений (cfe): поскольку кэш представляет собой sha1 от заархивированного содержимого файла, то список кэшей обновляется при обновлении содержимого файла вне зависимости от сеанса ВК.
ОбновитьФайлВVersions/updateFileInVersions(ИД файла) - устанавливает отметку об необходимости обновления для указанного файла. Чтобы версия кэша файла обновилась в списке кэшей необходимо вызвать метод АктуализироватьVersions в текущем сеансе работы с ВК. Поскольку метод ОбновитьФайл ставит отметку об необходимости обновления, метод ОбновитьФайлВVersions предназначен для разрешения коллизий. При работе с расширениями коллизий не возникает.
Заключение
Данная статья - ещё один маленький шаг к пониманию инфраструктуры 1С. Естественно, в ней возможны ошибки и недоработки. За конструктивную критику буду благодарен.
Update 2023.07.13. Добавлен новый тип метаданных - Интерфейсы. В обработке добавлена новая закладка для отображения закрытых модулей - Список. В ВК добавлен новый метод ЗапароленныеМодулиСписок. В запароленных модулях добавлен вид метаданных Константы. Изменена версия ВК на 1.1.0.1.
Update 2023.07.17. Добавлена поддержка формата метаданных 6 (8.0). Улучшено кэширование данных. Изменена версия ВК на 1.2.0.0. На C всё таки пишут, и это здорово: Статический анализатор кода 1С на Си.
Update 2023.08.11. Добавлена поддержка работы с кэшем 1С (versions), в том числе и для расширений (cfe). В ВК добавлены методы АктуализироватьVersions и ОбновитьФайлВVersions. В метод НачатьЗагрузкуФайлов добавлен параметр Актуализировать версии кэшей. Добавлена новая форма для работы с файлом versions. Изменена версия ВК на 1.3.0.0. Оптимизирована скорость получения метаданных из ERP 2.5.12.48 с ≈ 3000 мс до ≈ 1350 мс.
Update 2024.04.15. Добавлена возможность работы в Linux 32/64 и в веб-браузерах Chrome и Firefox. На закладке Файлы используется режим пагинации, поскольку в режиме веб-клиента больше 10 000 элементов вызывают зависание на 20-30 минут. Поскольку ПрочитатьJSON в веб-клиенте не поддерживается, используется функция ПрочитатьЗначениеJSON, к тому же, она работает значительно быстрее. Из-за использования этой функции минимальная версия платформы ограничена версией 8.3.23, вместо 8.3.18. Чтобы запустить обработку на версиях платформы младше 8.3.23, нужно раскомментировать код в конце модуля формы Основная.
Update 2024.11.27. Добавлена поддержка символов с кодами 1-31, кроме 9 (табуляция), 10 (перенос), 13 (возврат коретки). Для отображения символов используется шаблон '#0<код символа с ведущим нулем>;', например, #001; или #031;. Использование кода #000; запрещено и вызывает ошибку.
Исправлены выявленные ошибки.