DOBON.NET DOBON.NETプログラミング掲示板過去ログ

エクセル出力に時間が掛かってしまいます

環境/言語:[環境(windowsXP 32bit)、使用言語(VB.NET)]
分類:[.NET]

初めまして、こんにちは。

開発環境
OS:windowsXP
Office:Office2007
DB:MySQL
開発環境:VB.NET2003

私が、作成したエクセル出力機能があるのですが、
出力されるまでに時間が掛かりすぎてしまいます。
時間結果は下記のとおりになっております。

ユーザAさん PC環境(OS:windows7 64bit、Office2010)
出力されるまでの時間:3〜5秒

ユーザBさん PC環境(OS:windowsXP 32bit、Office2010)
出力されるまでの時間:50秒〜1分

ユーザCさん PC環境(OS:windowsXP 32bit、Office2007)
出力されるまでの時間:4〜5秒

どのユーザも出力されることは、出力されるのですが、
何故、ユーザBのみ、こんなにも時間が掛かってしまうのかが悩んでいる所になります。
私の書き方が悪いのか、それとも環境のせいなのか。
どなたかアドバイスを頂けないでしょうか。

よろしくお願い致します。

ソースは下記ように作成しています。
---------------------------------------------------------------------
Public Class Form画面A
Inherits System.Windows.Forms.Form
Private xlApp As Object
Private xlBook As Object
Private xlSheet As Object





'Form上にある「エクセル出力ボタン」を押すと↓ここから動きます。
'DB接続
If msobj.ms_connect = False Then Exit Sub

sqldata = "SELECT hoge1,hoge2,hoge3 " & _
"FROM db_テーブルA"
dtTbl = msobj.ms_reader(sqldata, "get").Tables("get")

'フォーマットOpen
xlApp = CreateObject("Excel.Application")
xlBook = xlApp.Workbooks.Open("C:\Format\FormatA.xls")
xlSheet = xlBook.Worksheets("print")

'書き込み
xlSheet.Range("B11").Value = CStr(dtTbl.Rows(0)(0)) 'hoge1
xlSheet.Range("P20").Value = CStr(dtTbl.Rows(0)(1)) 'hoge2
xlSheet.Range("AD41").Value = CStr(dtTbl.Rows(0)(2)) 'hoge3

xlSheet.PrintOut() '印刷処理

xlBook.Close(False)
xlApp.Quit()
xlApp = Nothing

EndProcess:
Dim Psa() As System.Diagnostics.Process = System.Diagnostics.Process.GetProcesses()
For Each p In Psa
If p.ProcessName = "EXCEL" Then
p.Kill()
End If
Next
msobj.ms_disconnect()
sqldata = Nothing
dtTbl = Nothing
Exit Sub
--------------------------------------------------------------------
■No32793に返信(じんべいさんの記事)
> 出力されるまでに時間が掛かりすぎてしまいます。
それぞれの処理で、それぞれ何ミリ秒を要しているのか、
各行の実行時間を計測するところから調査をはじめてみて下さい。


> ソースは下記ように作成しています。
コレクションクラスや Range クラスなどを変数に受けてないことから、
COM オブジェクトの解放手順などに問題があるように見えます。

そもそも何故、最後に EXCEL を強制 KILL しているのでしょうか?


> 私の書き方が悪いのか、それとも環境のせいなのか。
以下思い付きで:

・xlApp.Visible が True の時と False の時とで、処理時間に大きな差が生じますか?
 (非表示にすると、むしろ遅くなる環境もあります)
・「ハードウェア グラフィック アクセラレータを無効にする」の Excel 設定を
 切り替えた場合に、処理時間が変動するかどうか試してみてください。
・Excel オプションのアドイン一覧に、処理時間を要するものが紛れていませんか?
・XLSTART フォルダ や Templates フォルダなどに、不必要なブックが置かれていませんか?
・使用しているセキュリティ対策ソフトに差異はありますか?
・最新版の Update パッチが適用されていますか?
・Office をすべてアンインストールし、入れなおした場合はどうなるでしょうか。
 (複数バージョンのOfficeを導入してしまい、DLL Hell に陥っている可能性を考慮)

あとは、プリンタードライバーの違いとかですかね。PageSetup オブジェクトの
プロパティの読み書きに数十倍程度の時間差がつくケースを経験しています。
(改ページプレビューモードでの描画処理にも影響)
■No32796に返信(魔界の仮面弁士さんの記事)
> ■No32793に返信(じんべいさんの記事)
>>出力されるまでに時間が掛かりすぎてしまいます。
> それぞれの処理で、それぞれ何ミリ秒を要しているのか、
> 各行の実行時間を計測するところから調査をはじめてみて下さい。
>
>
>>ソースは下記ように作成しています。
> コレクションクラスや Range クラスなどを変数に受けてないことから、
> COM オブジェクトの解放手順などに問題があるように見えます。
>
> そもそも何故、最後に EXCEL を強制 KILL しているのでしょうか?
>
>
>>私の書き方が悪いのか、それとも環境のせいなのか。
> 以下思い付きで:
>
> ・xlApp.Visible が True の時と False の時とで、処理時間に大きな差が生じますか?
>  (非表示にすると、むしろ遅くなる環境もあります)
> ・「ハードウェア グラフィック アクセラレータを無効にする」の Excel 設定を
>  切り替えた場合に、処理時間が変動するかどうか試してみてください。
> ・Excel オプションのアドイン一覧に、処理時間を要するものが紛れていませんか?
> ・XLSTART フォルダ や Templates フォルダなどに、不必要なブックが置かれていませんか?
> ・使用しているセキュリティ対策ソフトに差異はありますか?
> ・最新版の Update パッチが適用されていますか?
> ・Office をすべてアンインストールし、入れなおした場合はどうなるでしょうか。
>  (複数バージョンのOfficeを導入してしまい、DLL Hell に陥っている可能性を考慮)
>
> あとは、プリンタードライバーの違いとかですかね。PageSetup オブジェクトの
> プロパティの読み書きに数十倍程度の時間差がつくケースを経験しています。
> (改ページプレビューモードでの描画処理にも影響)


魔界の仮面弁士さん

返信が大変遅くなり、申し訳ございません。
アドバイスを頂き、有難うございます。

魔界の仮面弁士さんのアドバイスを参考にし、
ネットで色々と方法を見つけ時間短縮に成功しました。

<結果>
ユーザAさん PC環境(OS:windows7 64bit、Office2010)
出力されるまでの時間:3〜5秒

ユーザBさん PC環境(OS:windowsXP 32bit、Office2010)
出力されるまでの時間:1〜2秒

ユーザCさん PC環境(OS:windowsXP 32bit、Office2007)
出力されるまでの時間:3〜4秒


ソースは下記となります。
----------------------------------------------------------------------
Public Class Form画面A
Inherits System.Windows.Forms.Form
Private xlApp As Object
Private xlBook As Object
Private xlBooks As Object
Private xlSheet As Object
Private xlSheets As Object
Private xlRange As Object
Private xlCells As Object





'Form上にある「エクセル出力ボタン」を押すと↓ここから動きます。
'DB接続
If msobj.ms_connect = False Then Exit Sub

sqldata = "SELECT hoge1,hoge2,hoge3 " & _
"FROM db_テーブルA"
dtTbl = msobj.ms_reader(sqldata, "get").Tables("get")

Try

' アプリケーション起動
xlApp = New Microsoft.Office.Interop.Excel.Application
xlApp.DisplayAlerts = False

' ワークブック作成
xlBooks = xlApp.Workbooks
Dim FilePath As String = "C:\Format\FormatA.xls"
xlBook = xlBooks.open(FilePath) '既存ファイルを開く場合

' 1シート目を指定
xlSheets = xlBook.Worksheets
xlSheet = DirectCast(xlSheets(1), Microsoft.Office.Interop.Excel.Worksheet)

' 対象セル抽出
xlCells = xlSheet.Cells

xlRange = DirectCast(xlCells(11, 2), Microsoft.Office.Interop.Excel.Range)
' セルに値を設定
xlRange.Value = CStr(dtTbl.Rows(0)(0)) 'hoge1
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange) '解放(使うたびに解放する)

xlRange = DirectCast(xlCells(11, 16), Microsoft.Office.Interop.Excel.Range)
' セルに値を設定
xlRange.Value = CStr(dtTbl.Rows(0)(1)) 'hoge2
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange) '解放(使うたびに解放する)

xlRange = DirectCast(xlCells(11, 30), Microsoft.Office.Interop.Excel.Range)
' セルに値を設定
xlRange.Value = CStr(dtTbl.Rows(0)(2)) 'hoge3
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange) '解放(使うたびに解放する)

xlSheet.PrintOut() '印刷処理

' COMオブジェクトを解放する
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
xlApp.Quit()
xlApp.DisplayAlerts = True
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)

Catch ex As Exception
Throw
End Try

MessageBox.Show("印刷しました。内容を確認して下さい。", "Information!", MessageBoxButtons.OK, MessageBoxIcon.Information)


EndProcess:
msobj.ms_disconnect()
sqldata = Nothing
dtTbl = Nothing
Exit Sub

魔界の仮面弁士さん

質問にお答えしていませんでした。
申し訳ございません。

> >>ソースは下記ように作成しています。
>>コレクションクラスや Range クラスなどを変数に受けてないことから、
>>COM オブジェクトの解放手順などに問題があるように見えます。
>>
>>そもそも何故、最後に EXCEL を強制 KILL しているのでしょうか?

会社の先輩のプログラムを引き継ぎ、今まで何も問題なくこれてましたので、
そのままにしてました。。。
色々調べた結果、KILLは削除しました。

>>・xlApp.Visible が True の時と False の時とで、処理時間に大きな差が生じますか?

処理時間は変わりませんでした。

>>・XLSTART フォルダ や Templates フォルダなどに、不必要なブックが置かれていませんか?

置いてません。

>>・使用しているセキュリティ対策ソフトに差異はありますか?

セキュリティソフトは全員一緒になります。

>>・最新版の Update パッチが適用されていますか?

はい、適用されています。

>>・Office をすべてアンインストールし、入れなおした場合はどうなるでしょうか。

アンインストールしても、結果は変わらずでした。


■32819の投稿の通り、時間短縮に成功しました。

有難うございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板