При разработке и поддержке решений на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью генерации сложных печатных форм, например, регулярно меняющихся налоговых деклараций, отчетов или внешних документов. Традиционный подход с жестким рисованием шаблонов в конфигураторе не всегда удобен, особенно если структура документа должна формироваться динамически на лету. В этой статье мы подробно разберем, как устроена структура файлов формата MXL, и рассмотрим практические способы программного создания секций и именованных областей.
Формат MXL, использовавшийся в версии 1С 7.7, представляет собой сложный бинарный файл. В его основе лежит технология Microsoft Compound Document File (OLE2 Storage). Это тот же контейнер, который корпорация Microsoft применяла в старых версиях MS Office (например, для форматов XLS или DOC). Данные внутри этого контейнера организованы в виде структурированных потоков (streams).
Давайте проанализируем ключевые технические особенности бинарного формата MXL 7.7:
LOGFONT (Windows API). Сама ячейка не содержит параметров цвета или рамки — она хранит лишь индекс стиля из общей таблицы форматов (Format Records). Чтобы программно записать ячейку с уникальным оформлением, нужно сначала зарегистрировать новый стиль в таблице форматов и только потом сослаться на него.Прямая программная запись такого бинарного файла через низкоуровневые потоки — задача крайне трудоемкая, требующая создания полноценного парсера и генератора OLE2-контейнеров. К счастью, существуют проверенные и гораздо более простые способы решения этой задачи.
---
Если перед вами стоит задача автоматического разбора структуры готовых файлов 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.
---
Если задача заключается в формировании печатной формы, дизайн которой периодически корректируется пользователями или законодательством (как в случае с налоговыми декларациями), опытные разработчики рекомендуют отказаться от идеи генерации структуры таблиц "с нуля" из кода. Вместо этого применяется метод пустого шаблона.
Рассмотрим этот метод по шагам:
Template.mxl).Шапка, СтрокаТаблицы, Подвал).Посмотрим на пример кода, реализующий этот подход:
// Создаем объект результирующей таблицы
Таб = СоздатьОбъект("Таблица");
// Загружаем заранее подготовленный шаблон с секциями
Таб.ИсходнаяТаблица("C:\Templates\MyReportTemplate.mxl");
// Выводим шапку по имени секции
Таб.ВывестиСекцию("Шапка");
// В цикле выводим строки таблицы
ВыборкаДанных.ВыбратьСтроки();
Пока ВыборкаДанных.ПолучитьСтроку() = 1 Цикл
// Заполняем переменные шаблона, которые будут выведены в ячейках
НомерСтроки = ВыборкаДанных.НомерСтроки;
Наименование = ВыборкаДанных.Наименование;
Сумма = ВыборкаДанных.Сумма;
// Выводим секцию строки
Таб.ВывестиСекцию("Строка");
КонецЦикла;
// Выводим подвал
Таб.ВывестиСекцию("Подвал");
// Показываем готовую форму пользователю
Таб.Показать("Налоговая форма");
Почему этот метод наиболее эффективен? Если в следующем квартале государственные органы изменят внешний вид декларации (например, добавят новую колонку, изменят шрифт или цвет фона), вам не придется переписывать программный код генератора. Достаточно будет открыть файл MyReportTemplate.mxl в визуальном редакторе 1С, внести изменения в оформление ячеек и сохранить файл. Программный код продолжит корректно обращаться к именованным секциям и выводить обновленные данные.
---
Если по каким-то причинам вы не хотите использовать секции и шаблоны, а генерация формы должна выполняться полностью динамически, можно использовать прямую адресацию к ячейкам и областям через стандартные свойства Область, ШиринаСтолбца и ВысотаСтроки объекта Таблица.
Проанализируем пример динамического построения сетки и управления размерами ячеек:
Таб = СоздатьОбъект("Таблица");
// Задаем ширину колонок программно
Таб.Область(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.