Платформа 1С:Предприятие 7.7, несмотря на свой почтенный возраст, до сих пор успешно решает учетные задачи во многих организациях. Однако одной из ее главных проблем является отсутствие штатной поддержки современных форматов экспорта отчетов. Базовый функционал позволяет сохранять таблицы (файлы .mxl) интерактивно только в устаревший формат XLS (Excel 95/97), который накладывает жесткие ограничения на количество строк, искажает цвета и некорректно обрабатывает сложные объединенные ячейки.
Для решения этой проблемы разработчиками долгое время использовалась легендарная библиотека Йоксель. Но ее сборка из исходников под современные стандарты крайне затруднена, а развитие проекта давно остановилось. В качестве современной, быстрой и функциональной альтернативы была разработана внешняя компонента v7Moxel (автор — Dmitry Dreytser, известный под ником MadDAD). Компонента написана на C# с использованием .NET Framework и библиотеки OpenXML, что позволяет ей сохранять отчеты в формате XLSX (Excel 2007 и выше), а также в PDF и HTML абсолютно автономно — наличие установленного Microsoft Office или LibreOffice на сервере или локальной машине пользователя не требуется.
В этой статье мы подробно разберем возможности компоненты v7Moxel, процесс ее установки, настройки, интеграции в код 1С 7.7, а также рассмотрим примеры решения сопутствующих технических проблем.
Компонента предоставляет разработчику 1С 7.7 богатый инструментарий для работы с печатными формами:
taskrunner.exe. Это защищает адресное пространство 32-битного процесса 1cv7.exe от критической ошибки нехватки памяти (Out of Memory).Для успешной работы компоненты на рабочих станциях и серверах должны быть выполнены следующие требования:
Разберем процесс установки по шагам:
C:\v7Moxel\).Register.cmd от имени Администратора (правой кнопкой мыши -> «Запуск от имени администратора»). Данный скрипт вызывает утилиту RegAsm.exe из состава .NET Framework и регистрирует COM-сервер под программным идентификатором AddIn.Moxel.Converter.Компонента поддерживает стандартный интерфейс интеграции 1С ILanguageExtender и предоставляет разработчику несколько ключевых методов (доступны как англоязычные, так и русскоязычные синонимы):
ЗагрузитьИзПамяти(Таблица) / LoadFromMemory(Table) — загружает табличный документ 1С напрямую из памяти запущенного процесса, избавляя от необходимости сохранять промежуточный .mxl файл на диск.Записать(ИмяФайла, КодФормата) / Write(FileName, FormatCode) — производит конвертацию загруженной таблицы и записывает результат на диск.
0 — Оригинальный MXL1 — XLSX (Excel 2007+)2 — HTML3 — PDFПерехватитьЗапись(Режим) / InterceptSave(Mode) — управляет глобальным перехватом интерактивного диалога сохранения файлов в 1С. При значении 1 перехват включен, при 0 — выключен.Присоединить() / Attach() — инициализирует связь компоненты со средой 1С.Рассмотрим подробнее, как реализовать различные сценарии экспорта отчетов программным путем.
Проанализируем ситуацию, когда нам необходимо выгрузить сформированный отчет в файл Excel 2007 программно, без вывода диалоговых окон пользователю. Напишем универсальную процедуру для глобального модуля или модуля формы отчета:
Процедура ЭкспортироватьТаблицуВXLSX(Таб, ПутьКФайлу)
// Шаг 1. Пытаемся загрузить внешнюю компоненту
Если ЗагрузитьВнешнююКомпоненту("v7Moxel.dll") = 0 Тогда
Сообщить("Не удалось загрузить внешнюю компоненту v7Moxel.dll!", "!");
Возврат;
КонецЕсли;
// Шаг 2. Создаем объект конвертера
Попытка
Конвертер = СоздатьОбъект("AddIn.Moxel.Converter");
Исключение
Сообщить("Не удалось создать COM-объект AddIn.Moxel.Converter. Проверьте регистрацию в реестре!", "!");
Возврат;
КонецПопытки;
// Шаг 3. Передаем таблицу в память компоненты
Попытка
Конвертер.ЗагрузитьИзПамяти(Таб);
Исключение
Сообщить("Ошибка при передаче табличного документа в компоненту: " + ОписаниеОшибки(), "!");
Возврат;
КонецПопытки;
// Шаг 4. Записываем таблицу в формате XLSX (код формата = 1)
Попытка
Конвертер.Записать(ПутьКФайлу, 1);
Сообщить("Документ успешно экспортирован в формат XLSX: " + ПутьКФайлу, "i");
Исключение
Сообщить("Ошибка записи файла: " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецПроцедуры
Выясним, как ведет себя компонента при сохранении в PDF. Начиная с версии 0.2, v7Moxel автоматически считывает настройки ориентации страницы (портрет или ландшафт) и масштаб. Нам достаточно предварительно настроить параметры печати у самой таблицы 1С:
Процедура ЭкспортироватьТаблицуВPDF(Таб, ПутьКФайлу)
// Загружаем компоненту
Если ЗагрузитьВнешнююКомпоненту("v7Moxel.dll") = 0 Тогда
Предупреждение("Компонента v7Moxel.dll не найдена!");
Возврат;
КонецЕсли;
Конвертер = СоздатьОбъект("AddIn.Moxel.Converter");
// Задаем параметры страницы на уровне 1С
// 1 - Портрет, 2 - Ландшафт. Зададим ландшафтную ориентацию
Таб.ПараметрыСтраницы(2, 100, 1, 5, 5, 5, 5, 0, 0, 1, 1, );
// Загружаем документ в конвертер
Конвертер.ЗагрузитьИзПамяти(Таб);
// Записываем в формате PDF (код формата = 3)
Попытка
Конвертер.Записать(ПутьКФайлу, 3);
Предупреждение("Файл PDF успешно сформирован!");
Исключение
Сообщить("Не удалось сохранить PDF: " + ОписаниеОшибки(), "!");
КонецПопытки;
КонецПроцедуры
Рассмотрим очень удобный механизм, который предлагает разработчик компоненты. Вместо написания кода под каждую кнопку выгрузки, мы можем один раз при запуске системы включить глобальный перехват штатного механизма записи таблиц 1С. В этом случае, когда пользователь выбирает меню «Файл - Сохранить как», он автоматически получает возможность сохранять в XLSX и PDF прямо из стандартного диалогового окна 1С.
Для реализации этого механизма откройте модуль Причало Настройки (процедура ПриНачалеРаботыСистемы) в Конфигураторе и добавьте следующий код:
Процедура ПриНачалеРаботыСистемы()
// Загружаем компоненту конвертации mxl документов
Если ЗагрузитьВнешнююКомпоненту("v7Moxel.dll") = 1 Тогда
Попытка
ГлобальныйКонвертер = СоздатьОбъект("AddIn.Moxel.Converter");
// Включаем глобальный перехват стандартных диалогов записи
ГлобальныйКонвертер.ПерехватитьЗапись(1);
Сообщить("Компонента v7Moxel успешно инициализирована. Стандартный экспорт в XLS заменен на XLSX.", "I");
Исключение
Сообщить("Ошибка инициализации AddIn.Moxel.Converter: " + ОписаниеОшибки(), "!");
КонецПопытки;
Иначе
Сообщить("Внимание! Компонента v7Moxel.dll не загружена. Экспорт в XLSX и PDF будет недоступен.", "!");
КонецЕсли;
КонецПроцедуры
Проанализируем техническую проблему, с которой часто сталкиваются пользователи старых конфигураций 1С 7.7. При формировании крупных годовых отчетов, оборотно-сальдовых ведомостей или реестров документов, таблица в памяти 1С может занимать десятки и сотни мегабайт. Архитектура 1С 7.7 является 32-битной, что ограничивает максимальный объем используемой процессом оперативной памяти в 2 ГБ. Внутренние механизмы парсинга библиотек .NET (в частности, ClosedXML) при построении DOM-модели XML-документа Excel могут кратно увеличивать потребление памяти во время конвертации.
Разработчик компоненты элегантно решил эту проблему. Начиная с версии 0.3, библиотека автоматически оценивает размер передаваемого табличного документа. Если размер таблицы превышает внутренний порог (2 МБ), компонента выполняет следующие действия:
taskrunner.exe (который поставляется вместе с dll-файлом компоненты).1cv7.exe.Важное примечание для системных администраторов: Чтобы данный функционал работал стабильно, убедитесь, что исполняемый файл taskrunner.exe находится в той же папке, что и зарегистрированная библиотека v7Moxel.dll, а у пользователя 1С есть права на запуск сторонних исполняемых файлов в операционной системе и запись во временный каталог Windows (%TEMP%).
В процессе эволюции компоненты v7Moxel были устранены критические ошибки визуализации, которые ранее мешали качественному переходу на безбумажный документооборот:
Используя компоненту v7Moxel, вы получаете мощный инструмент для модернизации 1С 7.7, позволяющий пользователям формировать современные, красивые и удобные документы для обмена с контрагентами и клиентами.