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

Программист 1С v7.7 Налоговый учет IT и автоматизация бизнеса
← На главную

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

В чем сложность прямого редактирования файлов MXL?

Формат MXL, использовавшийся в версии 1С 7.7, представляет собой сложный бинарный файл. В его основе лежит технология Microsoft Compound Document File (OLE2 Storage). Это тот же контейнер, который корпорация Microsoft применяла в старых версиях MS Office (например, для форматов XLS или DOC). Данные внутри этого контейнера организованы в виде структурированных потоков (streams).

Давайте проанализируем ключевые технические особенности бинарного формата MXL 7.7:

  1. Бинарная структура: Основной поток данных, в котором хранятся таблицы, обычно носит имя "Book" или "Workbook". Запись информации внутри него происходит последовательными блоками (записями), каждая из которых снабжается собственным идентификатором (ID) и длиной. Такая логика очень близка к формату Excel BIFF.
  2. Типы записей и стили: Оформление ячеек, границы, цвета и шрифты хранятся обособленно от самих ячеек. Информация о шрифтах записывается в виде системных структур LOGFONT (Windows API). Сама ячейка не содержит параметров цвета или рамки — она хранит лишь индекс стиля из общей таблицы форматов (Format Records). Чтобы программно записать ячейку с уникальным оформлением, нужно сначала зарегистрировать новый стиль в таблице форматов и только потом сослаться на него.
  3. Секции и именованные области: В структуре MXL 7.7 горизонтальные и вертикальные секции технически представляют собой разновидность именованных областей. Для создания секции "вручную" на низком уровне требуется сформировать запись, описывающую строковое имя секции, тип области (горизонтальная, вертикальная, прямоугольная), координаты (номера начальной и конечной строк/колонок) и уровень вложенности.
  4. Кодировка строк: Текстовые данные внутри бинарного файла MXL кодируются в однобайтовой системной кодировке (для русскоязычных систем — Windows-1251). Любая ошибка при работе со спецсимволами или длинами строк может привести к порче файла.

Прямая программная запись такого бинарного файла через низкоуровневые потоки — задача крайне трудоемкая, требующая создания полноценного парсера и генератора OLE2-контейнеров. К счастью, существуют проверенные и гораздо более простые способы решения этой задачи.

---

Решение 1. Использование внешней библиотеки Yoksel (Йоксель)

Если перед вами стоит задача автоматического разбора структуры готовых файлов MXL или их генерации на лету без визуального отображения, наиболее стабильным решением является использование бесплатной библиотеки Yoksel. Она предоставляет полноценный COM-объект (ActiveX DLL), который можно легко подключить к среде 1С 7.7.

Библиотека Yoksel позволяет работать со структурой MXL на высоком уровне. Вам больше не нужно заботиться о бинарных смещениях и структурах LOGFONT. Выясним, как с помощью Yoksel можно программно манипулировать областями и секциями:


// Пример инициализации объекта Yoksel в 1С 7.7
Попытка
    ТабличныйДокумент = СоздатьОбъект("Йоксель.ТабличныйДокумент");
Исключение
    Предупреждение("Компонента Yoksel не зарегистрирована в системе!");
    Возврат;
КонецПопытки;

// Загрузка существующего файла MXL
ТабличныйДокумент.Открыть("C:\Templates\TaxForm.mxl");

// Получение списка именованных областей и секций
КоличествоОбластей = ТабличныйДокумент.Области.Количество();
Для Номер = 1 По КоличествоОбластей Цикл
    ТекущаяОбласть = ТабличныйДокумент.Области.Получить(Номер);
    Сообщить("Найдена область: " + ТекущаяОбласть.Имя + " (Строки: " + ТекущаяОбласть.Верх + " - " + ТекущаяОбласть.Низ + ")");
КонецЦикла;

С помощью Yoksel можно не только читать, но и динамически добавлять новые области, изменять их размеры, управлять параметрами шрифтов и объединением ячеек, после чего сохранять результат обратно в оригинальный формат MXL или экспортировать его в XLS / PDF.

---

Решение 2. Практичный метод "пустого шаблона"

Если задача заключается в формировании печатной формы, дизайн которой периодически корректируется пользователями или законодательством (как в случае с налоговыми декларациями), опытные разработчики рекомендуют отказаться от идеи генерации структуры таблиц "с нуля" из кода. Вместо этого применяется метод пустого шаблона.

Рассмотрим этот метод по шагам:

  1. В конфигураторе или стандартном редакторе таблиц 1С создается файл-шаблон (например, Template.mxl).
  2. В этом шаблоне визуально рисуются все возможные варианты строк, шапок и подвалов. Каждому логическому блоку назначается имя секции (например, Шапка, СтрокаТаблицы, Подвал).
  3. Программа при формировании отчета открывает этот файл как шаблон, считывает нужные секции по их именам и последовательно выводит их в результирующий документ с заполнением параметров.

Посмотрим на пример кода, реализующий этот подход:


// Создаем объект результирующей таблицы
Таб = СоздатьОбъект("Таблица");

// Загружаем заранее подготовленный шаблон с секциями
Таб.ИсходнаяТаблица("C:\Templates\MyReportTemplate.mxl");

// Выводим шапку по имени секции
Таб.ВывестиСекцию("Шапка");

// В цикле выводим строки таблицы
ВыборкаДанных.ВыбратьСтроки();
Пока ВыборкаДанных.ПолучитьСтроку() = 1 Цикл
    // Заполняем переменные шаблона, которые будут выведены в ячейках
    НомерСтроки = ВыборкаДанных.НомерСтроки;
    Наименование = ВыборкаДанных.Наименование;
    Сумма = ВыборкаДанных.Сумма;
    
    // Выводим секцию строки
    Таб.ВывестиСекцию("Строка");
КонецЦикла;

// Выводим подвал
Таб.ВывестиСекцию("Подвал");

// Показываем готовую форму пользователю
Таб.Показать("Налоговая форма");

Почему этот метод наиболее эффективен? Если в следующем квартале государственные органы изменят внешний вид декларации (например, добавят новую колонку, изменят шрифт или цвет фона), вам не придется переписывать программный код генератора. Достаточно будет открыть файл MyReportTemplate.mxl в визуальном редакторе 1С, внести изменения в оформление ячеек и сохранить файл. Программный код продолжит корректно обращаться к именованным секциям и выводить обновленные данные.

---

Решение 3. Программная адресация по координатам ячеек

Если по каким-то причинам вы не хотите использовать секции и шаблоны, а генерация формы должна выполняться полностью динамически, можно использовать прямую адресацию к ячейкам и областям через стандартные свойства Область, ШиринаСтолбца и ВысотаСтроки объекта Таблица.

Проанализируем пример динамического построения сетки и управления размерами ячеек:


Таб = СоздатьОбъект("Таблица");

// Задаем ширину колонок программно
Таб.Область(1, 1, 1, 1).ШиринаСтолбца(15);
Таб.Область(1, 2, 1, 2).ШиринаСтолбца(30);
Таб.Область(1, 3, 1, 3).ШиринаСтолбца(20);

// Заполняем ячейки данными по координатам (Строка, Колонка)
Для Стр = 1 По 10 Цикл
    Таб.Область(Стр, 1).Текст = "Строка № " + Стр;
    Таб.Область(Стр, 2).Текст = "Динамические данные";
    Таб.Область(Стр, 3).Текст = Стр * 100;
    
    // Устанавливаем высоту текущей строки
    Таб.Область(Стр, 1, Стр, 3).ВысотаСтроки(20);
КонецЦикла;

Таб.Показать("Динамическая таблица");

Этот способ позволяет отказаться от использования внешних библиотек и жестких шаблонов, однако его поддержка при частых изменениях макета отчета сопряжена с высокой трудоемкостью, так как координаты всех ячеек приходится рассчитывать в коде вручную.

Резюме

Для быстрого и стабильного решения задач по управлению структурой файлов MXL в 1С 7.7 лучше всего использовать комбинацию метода пустого шаблона и стандартных механизмов платформы. Если же вам требуется производить глубокий анализ структуры бинарных файлов без визуального отображения или конвертировать их в сторонние форматы, оптимальным выбором станет интеграция внешней библиотеки Yoksel.

← На главную