Формат MOXCEL – Введение/комментарии
Файл MXL представляет собой продукт СЕРИАЛИЗАЦИИ объекта C++-объекта CSheetDoc. Сериализация осуществляется стандартными для MFC средствами: посредством класса CArchive. Поэтому для понимания формата файла очень полезен доступ к исходникам MFC. В частности могут представлять интерес исходника класса CArchive и функций сериализации многих встроенных MFC-классов (например, CString). 1С:Предприятие 7.7 создавалось при помощи Visual Studio 6, поэтому исходные тексты MFC нужно брать оттуда.
Справка по сериализации в MSDN:
http://msdn.microsoft.com/en-us/library/6bz744w8(VS.80).aspx
Т.к. для загрузки документа 1С использует сериализацию, то НИКАКОЙ валидации загружаемых данных не производится. Поэтому некорректный генератор MXL-документов в теории может создавать документы, вызывающие повреждение памяти 1С. Следовательно, тестирование генераторов MXL-документов следует производить очень тщательно.
Далее приводится описание сериализации некоторых типичных объектов.
Счетчик
Объект типа «счетчик» указывает количество последующих далее объектов. Данный объект записывается функцией CArchive::WriteCount. Вот так эта функция выглядит в VC6:
Следовательно, если количество объектов меньше 0xFFFF, то это количество записывается в виде слова. Если количество объектов больше или равно 0xFFFF, то сначала записывается 0xFFFF, а потом реальное количество объектов в виде двойного слова.
Строки
Объект «Строка» представляет собой продукт сериализации объекта CString. Сериализация происходит при помощи оператора << для класса CArchive.
Исходный текст оператора:
Отсюда видно, что алгоритм следующий:
- Если длина строки меньше 255 байт, то длина строки записывается в виде одного байта.
- Если длина строки больше или равна 255, то записывается значение 0xFF.
- Далее, если длина строки меньше 0xFFFE, то записывается длина строки в виде слова.
- Иначе записывается 0xFFFF и далее длина строки в виде двойного слова.
Следует учитывать, что все строки в 1С неюникодные.
Примеры:
- Если длина строки 45, то будет записан один байт: 0x2D.
- Если длина строки 378 байт, то будет записана следующая последовательность: 0xFF 0x7A 0x01.
- Если длина строки 156345 байт, то будет записана последовательнось: 0xFF 0xFF 0xFF 0x00 0xB9 0x62 0x02.
После количества символов следуют собственно сами символы строки – обычные однобайтовые символы в кодировке CP1251.
Единица измерения – юнит
Юнит – условное название внутренней единицы измерения в 1С. Эта единица используется, например, в свойствах внедренных объектов. Свойства юнита:
- При разрешении экрана в 96dpi 1 пиксел = 3 юнита.
- 1 пункт = 4 юнита.
Вероятно, юнит был выбран в 1С таким образом, чтобы размер в пунктах и размер в пикселах всегда выражался в юнитах целым числом. В одном дюйме 288 юнитов. 288 это наименьшее общее кратное чисел 96 и 72: стандартное dpi для экрана и количество пунктов в дюйме.
Устаревшее содержимое
- Файлы типа *.mxl или «moxсel» представляют собой набор последовательных блоков. Т.е. при разборе файла всегда известна структура текущего блока и какой следующий блок, после текущего. Размер блока может увеличиваться в зависимости от содержимого блока, т.к. может содержать вложенные блоки.
- Что такое блок? В принципе их два типа – «логический» и «физический». Логический блок – это собрание физических блоков в логически целый объект, а физический – это данные, длина которых всегда известна и не меняется. :)
- Как правило физический блок устроен так:
- «количество данных» – число которое указывает, сколько порций данных будет далее;
- «данные» – данные заданной длины или блоки известной структуры, которые идут друг за другом.
Т. е. длина блока не постоянна, а зависит от количества данных которые в нее входят, и если в нее входят другие блоки, то и от их длины.
- Логический блок чаще всего устроен так:
- блок номеров
- блок свойств
Например:
блок номеров – [кол-во номеров] [номер 1] [номер 2] ... [номер n]
блок свойств – [кол-во св-в] [св-во 1] [св-во 2] ... [св-во m]
(!) Важно, как правило n = m, т.к. если сначала идут номера свойств, то их и должно быть столько же, сколько и свойств, справедливо и обратное. :-)
И пример их физической реализации:
данные | длина | комментарий |
0x0003 | 2 | кол-во номеров = 3 |
0x00000001 | 4 | первое св-во имеет номер = 1 |
0x00000005 | 4 | второе св-во имеет номер = 5 |
0x00000006 | 4 | и т.д. |
0x0003 | 2 | кол-во св-в = 3 |
0x000000000066 | 6 | св-во № 1 |
0x000000005500 | 6 | св-во № 5 |
0x007700005500 | 6 | и т.п. |
- Наиболее распространенным блоком являются св-ва ячейки. Его формат с небольшими изменениями используется для следующих св-в:
- общие св-ва таблицы;
- св-ва колонтитулов;
- св-ва колонок;
- св-ва строк;
- св-ва ячейки; :)
- св-ва рисунка (OLE, диаграммы);
- св-ва ячеки диалоговой таблицы.
- Что такое диалоговая таблица?
«Диалоговая таблица» – это таблица которая работает в режиме ввода данных. Т.е. это естественно или в отчете, или в обработке в «св-вах формы» выбрана таблица «для ввода данных». После чего в св-вах ячейки появляется дополнительная вкладка «Данные».
- Свойства ячейки всегда состоят и пары значений флажок и значение. Если значение флажка не ноль, то сопутствующее ему значение установленно и имеет смысл, Если флажок не установлен, то сопутствующее ему значение либо ноль, либо сохраняет прошлое значение. Флажки являются битовыми. т. е. в одном байте – 8 бит – 8 флажков.
В таблице
«свойств ячеек по группам»? отображены вышеупомянутые пары.
- Некоторые выводы:
- Весь файл можно прочитать только зная всю структуру файла, т.е. расшифровку всех блоков.
- В файл записываются только изменненые значения.
- То что не сохраняется в таблице:
- «Область печати»
- «Повторять на каждом листе»
- «Параметры страницы»
- Что необходимо еще сделать:
- Много непонятных значений в рисунках и OLE.
- Рисунки к св-вам рисунков
- ...
Страницы, ссылающиеся на данную:
ФорматMOXCEL