C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 複数のEXCELファイルのシートを1EXCELのシートに統合


(過去ログ 29 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■13773 / inTopicNo.1)  複数のEXCELファイルのシートを1EXCELのシートに統合
  
□投稿者/ イナフ (1回)-(2008/02/04(Mon) 19:31:24)

分類:[VB.NET/VB2005] 

OS:XP
開発環境:VS2003

いつも拝見させて頂き非常に参考になり助かっております。

現在、フォルダ配下に存在する各EXCELファイルのシートを一つのEXCELファイルにまとめようとしております。
フォルダ配下に存在するEXCELを開きながらシートを読みこみ、新規に作成した統合用のEXCELファイルに
シートをコピーしていっておりますが、コピーするファイルが多い場合に非常に時間が掛かってしまいます。
シートをコピーするする度に前回のコピー時間より倍程の時間が掛かるようになり、30ファイルともなりますと
数十分も掛かってしまいます。
なんとかシートのコピー処理を高速化する方法はないものでしょうか?

下記が処理コードになります。
※Try〜FinallyでのCOM開放は見て頂きやすいように省いております。

  Public Sub CreateXlsUnityFile(ByVal unityFolder As String, ByVal unityFile As String)

    Dim xlApplication As Excel.Application

    'COM生成
    xlApplication = New Excel.Application

    ' 警告メッセージなどを表示しないようにする
    xlApplication.DisplayAlerts = False

    '新規Booksの生成
    Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks

    '新規Bookの生成
    Dim xlNewBook As Excel.Workbook = xlBooks.Add()

    '新規Sheetsの生成
    Dim xlNewSheets As Excel.Sheets = xlNewBook.Worksheets

    '新規Sheetの生成
    Dim xlNewSheet As Excel.Worksheet = DirectCast(xlNewSheets(1), Excel.Worksheet)

    'ディレクトリにあるEXCELのシートを新規EXCELにコピーする
    Dim files As String() = System.IO.Directory.GetFiles(unityFolder)
    Dim file As String
    For Each file In files

      'コピー元Bookの取得
      Dim xlBook As Excel.Workbook = xlBooks.Open(file)

      'コピー元Sheetsの取得
      Dim xlSheets As Excel.Sheets = xlBook.Worksheets

      'コピー元Sheetの取得
      Dim xlSheet As Excel.Worksheet = xlSheets(1)

      'シート名を変更
      Dim sheetName As String = System.IO.Path.GetFileNameWithoutExtension(file)

      'シート名に設定可能な31バイトを超える場合は名称を編集する
      If LenB(sheetName) <= 31 Then
        xlSheet.Name = sheetName
      Else
        xlSheet.Name = Left(sheetName, 3) & sheetName.Substring(sheetName.IndexOf("("))
      End If

      '※シートをコピー
      Dim t1 As Integer = System.Environment.TickCount
      xlSheet.Copy(xlNewSheet)
      Debug.WriteLine("" & System.Environment.TickCount - t1)

      '開放処理
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)

      'コピー元ブックを閉じる
      xlBook.Close()
      System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)

    Next

    '不要シートの削除
    Call DeleteSheet(xlNewSheets, "Sheet1")
    Call DeleteSheet(xlNewSheets, "Sheet2")
    Call DeleteSheet(xlNewSheets, "Sheet3")

    'ブックの保存
    xlNewBook.SaveAs(unityFile)

    'シートの開放
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlNewSheet)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlNewSheets)

    'ブックを閉じる
    xlNewBook.Close()
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlNewBook)

    'ブックス開放
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)

    '終了処理
    xlApplication.Quit()
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)

  End Sub

引用返信 編集キー/
■13779 / inTopicNo.2)  Re[1]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ やじゅ (95回)-(2008/02/04(Mon) 20:52:36)
やじゅ さんの Web サイト
No13773 (イナフ さん) に返信
> シートをコピーしていっておりますが、コピーするファイルが多い場合に非常に時間が掛かってしまいます。
> シートをコピーするする度に前回のコピー時間より倍程の時間が掛かるようになり、30ファイルともなりますと
> 数十分も掛かってしまいます。
> なんとかシートのコピー処理を高速化する方法はないものでしょうか?
>

高速化するとしたら、マルチスレッド化ですかね。
例えば、ファイル数の半分を別ブックにコピー、もう半分は本ブックに、最後に本ブックに結合するとか

引用返信 編集キー/
■13785 / inTopicNo.3)  Re[2]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ 特攻隊長まるるう (120回)-(2008/02/04(Mon) 22:43:03)
No13779 (やじゅ さん) に返信
> 高速化するとしたら、マルチスレッド化ですかね。
経験上、悪化する可能性も高いと思います。
VB 側の処理を早くしても、Excel 側は変わらず。。。
もしくは、更に遅くなることもあります。

Excel 側の処理がどんどん重くなる場合は、コピーする
範囲を小さくするとか、値のみなら Value プロパティに
直接設定するとか、Excel 側の処理を軽く(少なく)する
方法を探る方が解決しやすいかも?
引用返信 編集キー/
■13788 / inTopicNo.4)  Re[3]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ やじゅ (98回)-(2008/02/04(Mon) 23:22:38)
やじゅ さんの Web サイト
No13785 (特攻隊長まるるう さん) に返信
> ■No13779 (やじゅ さん) に返信
>>高速化するとしたら、マルチスレッド化ですかね。
> 経験上、悪化する可能性も高いと思います。
>

そうかもね。
じゃー別案
もしかしたら、10ファイルごとに一度保存して終了とか
したら速くなったりして… 
根拠としては、メモリが一度解放されて、メモリが空くかなーと思っただけだぴょん。
引用返信 編集キー/
■13792 / inTopicNo.5)  Re[4]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ イナフ (2回)-(2008/02/05(Tue) 00:07:06)
みなさんご返信ありがとう御座いました。
後日、やじゅさんの方法で試してみて、結果をご報告しようと思います。

別の方法で、1シートコピー毎に(※)処理を簡潔する方法でやってみましたが、こちらも
同様の結果になってしまいました…。

※1シート分コピーする毎に下記の様な処理
for XXXX to XXXX
 New Excel.Application
 〜
 コピー処理
 〜
 lApplication.Quit()
Next

引用返信 編集キー/
■13799 / inTopicNo.6)  Re[5]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ 特攻隊長まるるう (121回)-(2008/02/05(Tue) 07:53:14)
No13792 (イナフ さん) に返信
> 別の方法で、1シートコピー毎に(※)処理を簡潔する方法でやってみましたが、こちらも
> 同様の結果になってしまいました…。
いやいや^^;Excel.Application を作り直したらそりゃ遅いでしょう。
Excel は突然のシャットダウンにも対応して一時ファイルを作成してます
から、Quit するたびに終了処理が一通り走ります。

変更点を少なくするっていう観点だけだと、見当がつかないですか。。。
シートのコピーじゃなく、移動にするとかどうでしょう?
# 移動元は保存せずに閉じてください。
引用返信 編集キー/
■13801 / inTopicNo.7)  Re[6]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ セイン (71回)-(2008/02/05(Tue) 09:27:02)
あまり知識がなくてごめんなさい。
一度CSVファイルに変換するという手はないのでしょうか?

引用返信 編集キー/
■13831 / inTopicNo.8)  Re[7]: 複数のEXCELファイルのシートを1EXCELのシートに統合
□投稿者/ イナフ (3回)-(2008/02/05(Tue) 15:11:57)
ご返信、誠にありがとう御座います。

>10ファイルごとに一度保存して終了とかしたら速くなったり
無念ながら結果を得られませんでした。

>シートのコピーじゃなく、移動にするとかどうでしょう?
移動にて処理を行いました。若干早くなりましたが、
移動を重ねるごとに処理が重くなるのは変わりませんでした。

> 一度CSVファイルに変換するという手はないのでしょうか?
CSV形式では表せないデータでしたので、断念致しました。

統合先のEXCELでシート数が多い場合、コピー、移動処理において時間が掛かかるような感じがします。
数件毎に統合EXCELを保存して閉じ、再度開いて処理した場合におきましても同様でした。(再度New Excel.Applicationはせず)
Excel側の処理を軽くしようと考えましたが、値のみならず細かい書式や名前定義なども
存在し大変ですので、こちらも断念致しました。
当初便利機能としまして、別アプリで個々に出力されるEXCELを一括して閲覧&ブック単位で一括印刷できるように
と思い製作しておりました。現在は統合する機能を保留にしまして、フォルダ配下に存在する
EXCELファイルを一括して印刷するように変更致しました。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
New Excel.Application
for XXXX to XXXX
  〜
  '印刷を行う
  xlSheet.PrintOut(From:=1, Copies:=1, Preview:=False)
  〜
Next
lApplication.Quit()
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

しかし、このままでは悔しいので時間があるときになんとかしたいと思います。
皆様本当にありがとう御座いました。一応「解決」にしておきます。

※今回参考にしましたURLを貼っておきます。
http://www.microsoft.com/japan/msdn/office/vsto2003/ExcelObj.aspx#excelobj_link13

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -