Как исправить разбиение таблицы на несколько листов при сохранении в Excel из 1С v7.7 через Йоксель?

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

При работе в системе 1С:Предприятие 7.7 разработчики часто сталкиваются с задачей экспорта печатных форм (выходных таблиц) в формат Excel. Для качественного сохранения структуры таблиц, шрифтов и цветов традиционно используется внешняя компонента Йоксель (библиотека SpreadSheet.dll). Однако на практике возникает неприятная ситуация: в самой 1С печатная форма идеально умещается на один лист, но после конвертации и открытия файла в Microsoft Excel при подготовке к печати таблица разбивается на несколько страниц (например, на 4 листа по ширине). При попытке программно задать параметры страницы в коде Йокселя система может выдавать ошибку.

В этой статье мы подробно разберем, почему возникает данная проблема, как исправить ошибку инициализации параметров печати в Йокселе и какими способами можно принудительно заставить Excel выводить сконвертированный документ на один лист.

Выясняем причину ошибки при обращении к Параметрам Печати

Проанализируем исходную ситуацию. Разработчик пытается установить параметры страницы (поля, ориентацию) через свойства объекта Йоксель, используя следующий код:


Параметры = Документ.ПараметрыПечати;
Параметры.ПолеСверху = 50;
Параметры.ПолеСнизу = 50;    
Параметры.ПолеСлева = 50;
Параметры.ПолеСправа = 50;
Параметры.Ориентация = 2;

При выполнении этого фрагмента 1С аварийно завершает работу или выдает ошибку обращения к методам объекта. Первопричина кроется в устаревшей версии библиотеки SpreadSheet.dll. В ранних релизах Йокселя (например, в версиях ветки 0.3.0.0 или ранних сборках 1.x) работа с объектом ПараметрыПечати содержала критические ошибки, приводившие к нестабильности компоненты.

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

Настройка автомасштабирования документа в коде Йокселя

После того как мы обновили компоненту, нам становится доступен весь функционал управления печатью. Почему же документ все-таки бьется на 4 листа? В 1С печатная форма масштабируется под физический лист бумаги благодаря включенной опции "Автомасштаб" (по ширине листа). При обычном экспорте табличного документа эти настройки сбрасываются, и Excel пытается вывести документ в масштабе 100%, перенося не поместившиеся по ширине колонки на новые страницы.

Давайте настроим автоматическое масштабирование непосредственно в коде конвертации с помощью свойств обновленного Йокселя. Рассмотрим пример процедуры сохранения:


Процедура ВыполнитьСохранение(ИмяВременногоФайла)
    // Записываем исходную таблицу во временный файл MXL
    гТаблица.Записать(ИмяВременногоФайла);
    
    // Создаем объект Йокселя для работы с табличным документом
    Документ = СоздатьОбъект("ТабличныйДокумент");
    Документ.Открыть(ИмяВременногоФайла);
    
    // Инициализируем конвертер в формат Excel
    Конвертер = СоздатьОбъект("КонвертерExcel");
    Книга = Конвертер.Создать();
    
    // Настраиваем параметры печати
    Параметры = Документ.ПараметрыПечати;
    Параметры.АвтоМасштаб = 1; // Включаем режим "По ширине листа"
    Параметры.Ориентация = 2;  // Устанавливаем ландшафтную (альбомную) ориентацию (1 - портрет, 2 - ландшафт)
    
    // Настраиваем поля страницы (значения указываются в миллиметрах)
    Параметры.ПолеСверху = 10;
    Параметры.ПолеСнизу = 10;    
    Параметры.ПолеСлева = 10;
    Параметры.ПолеСправа = 10;
    
    // Добавляем лист в книгу Excel и производим запись
    Книга.Листы.Добавить(ВыбНазваниеЛиста, Документ);
    Книга.ПараметрыКонвертера.РаспознаватьЧисловыеЗначения = 0;
    Книга.Записать(ВыбИмяФайла);
КонецПроцедуры

В этом коде ключевым является свойство Параметры.АвтоМасштаб = 1. Оно передает в результирующий XLS-файл директиву для Excel, указывающую, что при выводе на печать необходимо применить сжатие до размеров печатной области страницы.

Автоматический перенос параметров печати из 1С в Йоксель при помощи компоненты 1С++

Жесткое прописывание полей и ориентации в коде — не всегда лучшее решение, так как пользователи могут настраивать параметры страницы интерактивно перед печатью. Чтобы динамически перенести настройки из текущей печатной формы 1С в объект Йокселя, мы можем использовать популярную внешнюю компоненту 1С++ и ее объект МенеджерТабличногоДокумента.

Разберем по шагам, как связать параметры страницы оригинального табличного документа 1С и конвертируемого документа Йокселя:


// Создаем менеджер табличного документа из 1С++ для извлечения настроек печати
ТабМенеджер = СоздатьОбъект("МенеджерТабличногоДокумента");
ТабМенеджер.УстановитьТаблицу(гТаблица);
ПараметрыСтраницы = ТабМенеджер.ПараметрыСтраницы;

// Переносим настройки масштабирования и полей в Йоксель
Параметры = Документ.ПараметрыПечати;
Параметры.Масштаб = ПараметрыСтраницы.Scale;
Параметры.Ориентация = ПараметрыСтраницы.Orient;

// Обратите внимание: в 1С++ поля могут возвращаться в сантиметрах, 
// тогда как Йоксель принимает параметры в миллиметрах (умножаем на 10)
Параметры.ПолеСлева = ПараметрыСтраницы.Left * 10;
Параметры.ПолеСправа = ПараметрыСтраницы.Right * 10;
Параметры.ПолеСверху = ПараметрыСтраницы.Top * 10;
Параметры.ПолеСнизу = ПараметрыСтраницы.Bottom * 10;

Этот изящный способ позволяет полностью сохранить пользовательские настройки печати, заданные в 1С, и автоматически применить их к созданному Excel-файлу.

Альтернативное решение: Докрутка параметров страницы через COM-объект Excel

Если по каким-то причинам использование встроенных механизмов Йокселя для масштабирования не привело к желаемому результату (например, из-за специфических версий Microsoft Excel в вашей организации), мы можем применить альтернативный подход. Мы запишем файл с помощью Йокселя стандартным образом, а затем "на лету" откроем его через COM-соединение и установим жесткие параметры вывода на одну страницу.

Рассмотрим пример реализации такого алгоритма:


// Шаг 1. Стандартное сохранение файла через Йоксель
Книга.Записать(ВыбИмяФайла);

// Шаг 2. Корректировка параметров печати напрямую в Excel через COM
Попытка
    Эксель = СоздатьОбъект("Excel.Application");
    // Открываем файл в фоновом режиме без отображения окна программы
    Эксель.Visible = 0;
    Эксель.DisplayAlerts = 0; 
    
    РабочаяКнига = Эксель.Workbooks.Open(ВыбИмяФайла);
    АктивныйЛист = РабочаяКнига.ActiveSheet;
    
    // Переходим к настройкам параметров страницы (PageSetup)
    НастройкаСтраницы = АктивныйЛист.PageSetup;
    
    // Отключаем фиксированный процентный масштаб, чтобы активировать масштабирование по страницам
    НастройкаСтраницы.Zoom = 0; 
    
    // Указываем Excel уместить весь документ ровно на 1 страницу по ширине
    НастройкаСтраницы.FitToPagesWide = 1; 
    
    // Значение "0" или "Ложь" для высоты означает, что количество страниц по вертикали не ограничено
    НастройкаСтраницы.FitToPagesTall = 0; 
    
    // Сохраняем изменения и закрываем Excel
    РабочаяКнига.Save();
    РабочаяКнига.Close();
    Эксель.Quit();
Исключение
    // В случае ошибки (например, если Excel не установлен на сервере/клиенте)
    Предупреждение("Не удалось настроить параметры печати в Excel: " + ОписаниеОшибки());
    Если ПустоеЗначение(Эксель) = 0 Тогда
        Эксель.Quit();
    КонецЕсли;
КонецПопытки;

Применение COM-соединения гарантирует стопроцентное срабатывание логики автоподгонки масштаба, поскольку настройки прописываются непосредственно внутренними механизмами самого Microsoft Excel.

Известные ограничения при конвертации

При оптимизации печатных форм важно учитывать системные ограничения компоненты Йоксель. На текущий момент компонента не поддерживает конвертацию настройки "Повторять строки на каждом листе" (так называемые сквозные строки или шапка таблицы). Если ваша печатная форма занимает много страниц в высоту и на каждом листе требуется повторять шапку, то при переносе в Excel средствами Йокселя эта опция работать не будет. В подобных случаях сквозные строки также придется настраивать после конвертации программно через COM-соединение с Excel, обращаясь к свойству PageSetup.PrintTitleRows.

Подводя итог, мы видим, что проблема разделения листов успешно решается комплексным подходом: своевременным обновлением SpreadSheet.dll, использованием свойства АвтоМасштаб в Йокселе или, в качестве надежной альтернативы, постобработкой файла через COM-объект Excel.

← На главную