Экспорт нескольких MXL в один XLS на несколько листов



В ходе одного из проектов всплыло задание: отчёты должны быть скомпонованы в пачки и сохраняться в эксель вместе, каждый отчёт — на отдельный лист в файле. После некоторых происков с экселем и поисков с гуглом появилась обработка.

Алгоритм прост:

  • * открываем эксель,
  • * создаём новый файл,
  • * перебираем в цикле табличные документы:
    • — каждый документ сохраняем в эксель штатными средствами 1С,
    • — открываем файл экселем и
    • — копи-пастим оттуда первый (единственный) лист в наш сводный файл.
  • * сохраняемся, закрываем эксель

Разрабатывалось и тестировалось в условиях MS Office 2007 Standart. Под старые офисы можно и самим допилить. 

В приложенном файле нижеприведённый код и пример его использования.

Исходный код:

// СохранитьМногостраничныйФайл() Создаёт XLSX-файл с несколькими листами
//
// Параметры
//      ИмяФайла            — Имя выходного файла
//      СоответствиеЛистов  —
//                          (1) Соответствие:
//          Ключ            — Строка — Имя листа
//          Значение        — Табличный документ — Содержимое листа
//                          (2) Таблица значений с колонками Ключ и Значение.
//                              Может понадобиться, если требуется строгий порядок листов.
Процедура СохранитьМногостраничныйФайл(ИмяФайла, СоответствиеЛистов) Экспорт

    Х = ПолучитьCOMОбъект(«», «Excel.Application»);
   
Х.SheetsInNewWorkbook = 1; // в новой книге создавать только 1 лист
   
Книга = Х.Workbooks.Add();

    Первый = Истина; // у нас уже есть один лист, надо использовать его
   
ПрошлыйЛист = Неопределено;

    Для Каждого мЛист Из СоответствиеЛистов Цикл

        // Сохраняем табличный документ во временный файл
       
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(«xlsx»);
       
ТабДок = мЛист.Значение;
       
ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.XLSX);

        Х.CutCopyMode = False; // Сбрасываем старое копирование

        // Копируем первый (единственный) лист временного файла
        мКнига = Х.Workbooks.Open(ИмяВременногоФайла);
       
мКнига.Worksheets(1).Cells.Select();
       
Х.Selection.Copy();

        Если Первый Тогда // Используем созданный автоматически
           
НовыйЛист = Книга.Worksheets(1);
           
Первый = Ложь;
        Иначе
// добавляем новый
           
НовыйЛист = Книга.Worksheets.Add(, ПрошлыйЛист); // Добавляем новый лист после прошлого
       
КонецЕсли;

        НовыйЛист.Name = мЛист.Ключ; // Задаём имя
       
НовыйЛист.Paste(); // Вставляем содержимое

        // Сбрасываем выделение с добавленного листа
        НовыйЛист.Activate();
       
Х.Range(«A1»).Select();

        ПрошлыйЛист = НовыйЛист;

    КонецЦикла; // Для Каждого мЛист Из СоответствиеЛистов Цикл

    Х.DisplayAlerts = False; // Отключаем вывод предупреждений типа «Заменить файл?»
   
Книга.Worksheets(1).Activate(); // Активируем 1 лист из списка
   
Книга.SaveAs(ИмяФайла);

    Х.Quit();

    Х = Неопределено;

КонецПроцедуры // СохранитьМногостраничныйФайл()

12 Comments

  1. AlX0id

    А копипаст зачем? Чтобы не дышали при этом? )

    У меня вот так вполне работает..

    Колво = ЭлементыФормы.ПанельРезультат.Страницы.Количество()-1;
    Попытка
    
    Excel = Новый COMОбъект(«Excel.Application»);
    Excel.Application.WorkBooks.Add(-4167);
    
    КнигаРез = Excel.ActiveWorkBook;
    Лист = Excel.ActiveSheet;
    
    Исключение
    
    Сообщить(«Не удалось создать файл Microsoft Excel!!!»,СтатусСообщения.ОченьВажное);
    Возврат;
    
    КонецПопытки;
    
    Для Сч = 1 По Колво Цикл
    
    ЭлементыФормы[«ПолеТД» + (Колво — Сч + 1)].Записать(ПутьКФайлам + «Лист.xls», ТипФайлаТабличногоДокумента.XLS);
    Excel.Application.WorkBooks.Add(ПутьКФайлам + «Лист.xls»);
    КнигаТмп = Excel.ActiveWorkBook;
    ЛистBefore = КнигаРез.Sheets(1);
    КнигаТмп.Sheets(1).Name = ЭлементыФормы.ПанельРезультат.Страницы[Колво — Сч + 1].Заголовок;
    КнигаТмп.Sheets(1).Copy(ЛистBefore);
    КнигаТмп.Close(Ложь);
    
    КонецЦикла;
    
    КнигаРез.SaveAs(ПутьКФайлам + ИмяФайла);
    Excel.Application.Quit();
    

    Показать

    Reply
  2. baton_pk

    (1) AlX0id, согласен. Тоже дошёл до копирования листов, но уже позже. А копипаст вполне себе быстро работает, так что над «не дышать» никто даже и не задумался за все 2 дня эксплуатации. Хотя это не срок, конечно.

    Reply
  3. NoRazum

    Отличная разработка.

    Сэкономило мне кучу времени.

    Плюс однозначна!!!

    Reply
  4. Kesr

    Мне тоже пригодилась. Спасибо. Вот еще бы формулы из Excel файлов перекидывать. Буду копать в этом направлении.

    Reply
  5. nnurik

    Пригодилось, спасибо. Только цвета преобразились в Excel у меня… Буду искать, как исправить.

    Reply
  6. baton_pk

    (5) nnurik!

    да, есть в 1С такая проблема 🙂

    Reply
  7. marksheder

    Спасибо, очень пригодилась обработка!!!

    Reply
  8. Mialex

    Спасибо!

    Хорошая обработка! Облегчила мне сегодня жизнь.

    Reply
  9. ilya005

    excel выдает сообщение если много данных,

    что бы отключить перед закрытием книги использовать это:

    КнигаТмп.Sheets(1).Range(«A1»).Copy();

    Reply
  10. тшл

    Спасибо.

    Было по другому сделано(непонятно что и откуда), переделал на этот текст.

    Reply
  11. lhfrjy

    Хорошая, только временные файлы нужно удалять обязательно!!

    Reply
  12. AllexSoft

    (1) эх еще бы пример нормальный, сохранение какой нибудь коллекции (список значения, соответствие) с табличными документами, как у ТС. У вас какой то больно специфичный пример, сколько не вглядывался так и не понял как оно работает.

    Например ЛистBefore = КнигаРез.Sheets(1); — почему здесь строго единица? всегда вставляете в первую страницу? остальные сдвинутся автоматом назад ?

    Excel.Application.WorkBooks.Add(-4167); — добавить книгу без листов ?

    КнигаТмп.Sheets(1).Copy(ЛистBefore); а точно так, а не на оборот? типа ЛистBefore.Copy(КнигаТмп.Sheets(1)); ?

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *