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

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

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

Re[4]: VB.netからExcelを実行中に…


(過去ログ 105 を表示中)

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

■62831 / inTopicNo.1)  VB.netからExcelを実行中に…
  
□投稿者/ さちも (3回)-(2011/11/05(Sat) 03:34:11)

分類:[VB.NET/VB2005 以降] 

先日、「DataGridView内でのEnterキー押下」の件で
こちらでお世話になったものです。
その節はありがとうございました。
この度、同じシステム内で別の不具合(?)の指摘を受けました。
回避策等ありましたら、お知恵をお授け下さい。


当該システムはVB.net(.NET Framework 4.0)で画面周りを作り
DBはOracle11gR1、帳票はxlsファイルで出力、という仕様です。

帳票出力時には処理速度向上のため、

  Dim oXlsApp As Excel.Application

  ' エクセル起動
  oXlsApp = New Excel.Application()

  ' エクセル非表示
  oXlsApp.Application.Visible = False
  oXlsApp.Application.DisplayAlerts = False

のようなコードを書いています。

ただ、普通にExcelを立ち上げている状態で別のxlsファイルをダブルクリックすると
すでに立ち上がっているExcelでダブルクリックしたxlsファイルが開かれますよね?

上記システムで帳票出力処理中に既存のxlsファイルをダブルクリックすると
すでに実行されている「Visible = False」になっているExcelで開いているようで
ユーザーからは
「Excelの枠だけ表示されてファイルの中身が見えない!勝手に終了するし!!」
(帳票出力が終了すると、Excel.Applicationも終了させている)
と不具合認定されています。

開発側としては「ショートカット等から別のExcelを新規に起動させれば
処理中でもExcelのファイルを開くことは可能。運用カバーをお願いします」と
回答しようとしていますが、かなりハードな要求をされるユーザーなので
「回避策無いの?」と言われる事は必至です。


上記のような現象を解決された方&解決のアイディアをお持ちの方がいらしたら
お知恵を貸してはいただけませんでしょうか?
わかりづらい書き方で申し訳ありませんが、よろしくお願いします。

引用返信 編集キー/
■62832 / inTopicNo.2)  Re[1]: VB.netからExcelを実行中に…
□投稿者/ さちも (4回)-(2011/11/05(Sat) 04:09:03)
上記カキコミに追記です。

帳票は月次帳票で、データ量も相当多いらしく
劇的な処理時間短縮は難しいです。

ユーザから「Excelはバージョン指定なし」との要望があり
(プログラム計画書には「Excel2003」って明記済みで、了解済の筈なのに…)
「遅延バインディング」(?)を使ってコーディングしており
これがまた処理速度を多少なりとも低下させているはずです。

帳票出力実行前に「時間がかかりますので、Excelを使用する場合は…」等の
確認ダイアログを表示することも考えております。
引用返信 編集キー/
■62835 / inTopicNo.3)  Re[2]: VB.netからExcelを実行中に…
□投稿者/ ともき (1回)-(2011/11/05(Sat) 07:49:58)
xlApp がファイルを開くと、WorkbookOpen イベントが呼ばれるので
Wbの中身がプログラムが開くべきではないワークブックの時はWbを閉じて
新しく Excel.Applicationのインスタンスを作成し開き直せば多少はましかなあ

Private WithEvents xlApp As New Excel.Application

Private Sub xlApp_WorkbookOpen(Wb As Microsoft.Office.Interop.Excel.Workbook) Handles xlApp.WorkbookOpen

If (ユーザーがダブルクリックで開いたWb) Then
xlApp.Visible = False
Dim path As String = Wb.FullName
Wb.Close()
Debug.Print(path)
Dim xlNew As New Excel.Application
xlNew.Workbooks.Open(path)
xlNew.Visible = True
End If
End Sub

てか開いてから呼ばれるので、xlApp が一瞬表示されるのは問題かも。

少し試してみたのですが、ダブルクリックでファイルを開くとき既にエクセル
が存在する場合は、一番古いインスタンスで開こうとしてるようなので、
プログラムの内部でエクセルのインスタンスを一つ予備で作っておくと、
それで表示できるのではないかなあと思います。
但し、この場合でも予備のインスタンスが常に最も古い作成時刻になるように、
予備を使うたびに、プログラムで使用しているエクセルを一旦解放するか、
予備として割当しなおさないといけないと思います。

あと、処理速度ですが、マルチスレッドで複数のエクセルを、
同時に操作するようにすると、処理内容にもよりますが改善されると思います。
過去にエクセルのファイルを数千個書き出すPGを作ったのですが、
インスタンスAがワークシートなどの内容を生成しているときに
インスタンスBは書き込みを行うとか、そういう感じになら処理速度が上がると思いますよ。

ただ、別のインスタンスでも、同じタイミングでワークブックのOpenやSaveAs、Add
ワークシートへの書き込み、Excelインスタンスの作成とかを行うと、
エクセル内部でデッドロックが発生しました。
これを解消するにはインスタンスを一度解放するしかないので
デッドロックが起きないように、各インスタンス同士の確実な同期が必要です。

あ、それと、com参照の管理も。これをミスると、解放できなくなりますし^^;






引用返信 編集キー/
■62839 / inTopicNo.4)  Re[3]: VB.netからExcelを実行中に…
□投稿者/ ともき (3回)-(2011/11/05(Sat) 10:21:13)
xlApp = New Excel.Application
xlApp.IgnoreRemoteRequests = True 'このxlApp のDDE通信を使用しないようにする

'
' エクセル出力
'

xlApp.IgnoreRemoteRequests = False 'このxlApp のDDE通信を使用出来るようにする
xlApp.Quit()


ていうか、このほうがよさそうですね
これで外部の影響は受けないと思います。
引用返信 編集キー/
■62840 / inTopicNo.5)  Re[2]: VB.netからExcelを実行中に…
□投稿者/ shu (1070回)-(2011/11/05(Sat) 10:21:55)
No62832 (さちも さん) に返信

役に立つか分かりませんが2次元配列で一度に書き込むと1セルづつ書くよりは
かなり速く処理出来ます。RangeのValue(またはValue2)から配列を取得してその配列の内容を書き換えて
再度RangeのValue(またはValue2)に貼るといいです。参考まで。

引用返信 編集キー/
■62846 / inTopicNo.6)  Re[4]: VB.netからExcelを実行中に…
□投稿者/ さちも (5回)-(2011/11/06(Sun) 00:14:14)
ともき様、shu様、ご回答ありがとうございます。

shu様のご提示いただいた二次元配列でのExcelへの貼付けは
実装済みのようです。

ともき様がご提示くださった IgnoreRemoteRequests が
解決への近道のような気がします。
週明けに早速試します。
マルチスレッドについては…お恥ずかしい事に
(私も含めて)経験者がおらず
組込むには工数を考えると厳しいものがあります。

お二方のアドバイス、本当に勉強になりました。
これにていったん解決とさせていただきます。
ありがとうございました。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -