Как решить проблему с высотой строк при сохранении отчетов из 1С 7.7 в Excel?

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

Разберем классическую проблему платформы 1С:Предприятие 7.7, с которой сталкивался практически каждый разработчик при выгрузке печатных форм (особенно счетов-фактур, накладных Торг-12) в формат Microsoft Excel. При использовании стандартного метода Таб.Записать(ИмяФайла, "xls") высота строк в полученном файле сбрасывается на фиксированное значение (обычно около 8 мм). Если наименование товара длинное и переносится на несколько строк, в Excel отобразится только первая строка, а остальной текст окажется скрыт.

Проанализируем причины этой проблемы и подробно рассмотрим несколько эффективных способов ее решения: от использования внешних компонент до программного управления Excel через COM-соединение.

Почему возникает проблема с высотой строк?

Встроенный табличный движок 1С 7.7 (так называемый Moxel) при экспорте таблиц во внешние файлы Excel использует упрощенные алгоритмы конвертации. Он не передает свойство автовысоты строк в файл .xls. В результате Excel открывает документ со стандартной высотой ячеек.

Более того, если попытаться включить флаг автовысоты для строк непосредственно в макете 1С 7.7 перед выгрузкой, система начнет катастрофически тормозить при сохранении больших документов. Это связано с неоптимальным алгоритмом пересчета высоты ячеек во встроенном конвертере 1С, где время обработки возрастает экспоненциально в зависимости от количества строк. Отчет на 500–1000 строк может просто «повесить» сессию пользователя.

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

Использование бесплатной внешней компоненты Йоксель (библиотека SpreadSheet.dll) — это самый стабильный, быстрый и профессиональный способ решения проблемы. Йоксель полностью заменяет штатный конвертер 1С, корректно переносит все свойства форматирования, включая автовысоту строк и масштабирование «По ширине листа».

Разберем по шагам, как программно сохранить печатную форму в Excel с помощью Йокселя:


// 1. Проверяем и загружаем внешнюю компоненту
Если ЗагрузитьВнешнююКомпоненту("SpreadSheet.dll") = 0 Тогда
    Предупреждение("Не удалось загрузить компоненту SpreadSheet.dll! Убедитесь, что библиотека зарегистрирована или находится в каталоге базы данных.");
    Возврат;
КонецЕсли;

// Предположим, у нас уже сформирован и заполнен стандартный ТабличныйДокумент 1С - Таб
Таб.ТолькоПросмотр(1);
Таб.Опции(0,0,0,0);  

// Определяем путь для сохранения файла
ВыбИмяФайла = КаталогПользователя() + "Выгрузка_СчетФактура_" + СокрП(Док.НомерДок);

// 2. Создаем объект табличного документа Йокселя
ДокументЙок = СоздатьОбъект("ТабличныйДокумент");

// 3. Загружаем данные из нашей стандартной таблицы 1С в Йоксель
ДокументЙок.ЗагрузитьИзТаблицы(Таб);

// 4. Инициализируем конвертер Excel и создаем рабочую книгу
Конвертер = СоздатьОбъект("КонвертерExcel");
Книга = Конвертер.Создать();

// 5. Добавляем лист в книгу и привязываем к нему наш документ
ИмяЛиста = "Счет-Фактура";
Книга.Листы.Добавить(ИмяЛиста, ДокументЙок);

// Настраиваем дополнительные параметры конвертации для корректного отображения чисел
Книга.ПараметрыКонвертера.РаспознаватьЧисловыеЗначения = 1;

// 6. Записываем готовую книгу в формате Excel
Книга.Записать(ВыбИмяФайла + ".xls");

// Открываем файл пользователю для проверки
ЗапуститьПриложение(ВыбИмяФайла + ".xls");

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

Как прочитать конкретный лист Excel с помощью Йокселя?

В процессе обсуждения часто возникает обратный вопрос: как быстро прочитать данные из файла Excel в 1С 7.7, выбрав конкретный лист (а не только первый по умолчанию)? С помощью Йокселя это делается за доли секунды. Рассмотрим готовый пример кода:


// Создаем объекты для открытия файла
Конвертер = СоздатьОбъект("КонвертерExcel");
Книга = Конвертер.Открыть(ПутьКФайлу);

// Выбираем лист по его названию
ИмяНужногоЛиста = "Лист 2"; 

// Загружаем данные выбранного листа в документ Йокселя
ДокументЛиста = Книга.ЗагрузитьЛист(ИмяНужногоЛиста);

// Переносим данные в стандартную Таблицу Значений (ТЗ)
КонвертерТЗ = СоздатьОбъект("Йоксель.КонвертерВТаблицуЗначений");
КонвертерТЗ.УстановитьДокумент(ДокументЛиста);

// Отключаем лишние проверки для достижения максимальной скорости
КонвертерТЗ.ОпределятьСтруктуру = 0;
КонвертерТЗ.ПроверятьСтруктуру = 0;

// Выгружаем данные в ТЗ
ТЗ = КонвертерТЗ.Загрузить();
// Теперь переменная ТЗ содержит все строки со второго листа Excel

Этот алгоритм работает феноменально быстро: обработка файла объемом более 6000 строк занимает всего около 0.18 секунд, тогда как чтение через ADO Connection на таком же объеме данных потребует более 30 секунд.

Решение 2. Использование патча MoxelDoctor для исправления штатного конвертера

Если в вашей конфигурации слишком много отчетов и печатных форм, переписывать код выгрузки для каждой из них под компоненту Йоксель может быть слишком трудозатратно. В этом случае на помощь приходит патч MoxelDoctor (автор — Romix).

Это небольшая библиотека, которая перехватывает функции оригинальной библиотеки Moxel.dll непосредственно в оперативной памяти запущенного процесса 1cv7.exe. Пачт оптимизирует внутренний алгоритм пересчета высоты строк 1С 7.7. После его интеграции вы можете продолжать использовать стандартный метод Таб.Записать() с включенной автовысотой в макетах. Скорость сохранения увеличится в сотни раз, и зависания системы полностью прекратятся.

Решение 3. Программная корректировка высоты строк через OLE (Excel.Application)

Если на компьютерах пользователей гарантированно установлен пакет Microsoft Office, мы можем применить метод OLE-автоматизации. Идея заключается в том, что мы сначала сохраняем файл стандартным методом 1С, а затем в фоновом режиме запускаем Excel, открываем этот файл и принудительно выполняем команду автоматического подбора высоты строк.

Посмотрим на пример реализации данного метода:


// Сохраняем файл штатным методом 1С
ИмяФайла = "C:\Temp\Invoice_1C.xls";
Таб.Записать(ИмяФайла, "xls");

// Выполняем автоподбор высоты через COM-объект
Попытка
    // Создаем экземпляр приложения Excel
    ExcelПриложение = СоздатьОбъект("Excel.Application");
    
    // Скрываем окно Excel и отключаем обновление экрана для скорости
    ExcelПриложение.Visible = 0;
    ExcelПриложение.ScreenUpdating = 0;
    
    // Открываем созданную книгу
    Книга = ExcelПриложение.Workbooks.Open(ИмяФайла);
    Лист = Книга.Worksheets(1); // Выбираем первый лист
    
    // Применяем метод AutoFit ко всем строкам листа
    Лист.Rows.AutoFit();
    
    // Сохраняем изменения и закрываем процессы
    Книга.Save();
    Книга.Close();
    ExcelПриложение.Quit();
    
    Сообщить("Файл успешно сохранен, высота строк скорректирована!");
Исключение
    Сообщить("Не удалось оптимизировать высоту строк. Ошибка: " + ОписаниеОшибки(), "!");
    // Гарантируем закрытие процесса Excel в случае возникновения сбоя
    Попытка
        ExcelПриложение.Quit();
    Исключение
    КонецПопытки;
КонецПопытки;

Преимущества метода: не требует установки и регистрации сторонних DLL-библиотек на компьютерах пользователей.

Недостатки метода: скорость работы ниже, чем при использовании Йокселя, так как инициализация COM-соединения с Excel требует значительных системных ресурсов.

Решение 4. Использование внешней компоненты xls21c

Для прямого взаимодействия с файлами Excel без использования установленного пакета MS Office часто используется легкая компонента xls21c. Она позволяет формировать файлы XLS напрямую на уровне байтового потока. Ее архитектура оптимизирована для быстрой записи больших массивов данных. Использование этой компоненты оправдано в тех случаях, когда требуется создавать сложные, многостраничные отчеты с жестко заданным форматированием строк на серверах, где установка Microsoft Office невозможна по соображениям лицензирования или безопасности.

Решение 5. Высокоскоростная запись больших объемов данных в формате XLSX через ADO

Выясним, как быть в ситуациях, когда отчет содержит огромное количество строк (более 65 536), что превышает технические лимиты старого формата XLS (Excel 97-2003). В таких случаях наилучшим решением будет запись в современный формат .xlsx напрямую через ADO (ActiveX Data Objects).

Алгоритм действий следующий:

  1. Создается пустой файл-шаблон в формате .xlsx. В нем заранее настраиваются шрифты, границы и свойство автовысоты строк для колонок.
  2. В 1С 7.7 инициализируется подключение к созданному файлу через OLEDB-провайдер:
    
    СтрокаПодключения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ИмяФайлаШаблона + ";Extended Properties=""Excel 12.0 Xml;HDR=YES;""";
    Соединение = СоздатьОбъект("ADODB.Connection");
    Соединение.Open(СтрокаПодключения);
    
  3. Запись данных осуществляется быстрыми SQL-запросами типа INSERT INTO [Лист1$] (Колонка1, Колонка2) VALUES (...).

Этот метод позволяет за несколько секунд экспортировать сотни тысяч строк информации, полностью сохраняя форматирование шаблона и автоматически подстраивая высоту строк под объем текста.

← На главную