QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

Excelオブジェクトの解放について

Excelオブジェクトの生成に苦労をしています。
今は、Webサーバーで生成したExcelファイルをダウンロードするソースをコンパイル
したら、Response.WriteFile(strOutFileName)で落ちている。エラーはこのファイルは
別のプロセスで使用中です。

開発環境;VB.NET2003 Webアプリケーション
*ソース***

Private objApp As Excel.Application
Private objWBook As Excel.Workbook
Private objSheet As Excel.Worksheet

strInFileName ="C:\wwwroot\bbb.xls" ' 元ファイル名
strOutFileName = "C:\wwwroot\aaa.xls" ' 出力ファイル名

'***** エクセルアプリケーションのインスタンスを作成 *****
objApp = CreateObject("Excel.Application")
objWBook = m_appWork.Workbooks.Open(strInFileName)
objSheet = m_wbkWork.Worksheets(1)

objWBook.Cells(1,1).Value = 1
objWBook.Cells(1,2).Value = 1
objWBook.Cells(1,3).Value = 1

objWBook.SaveAs(strOutFileName)

objSheet = Nothing
objWBook = Nothing
objApp = Nothing

objApp.Quit()

Response.Clear()
Response.ContentType = "application/vnd.ms-excel"
Response.Charset = ""
Response.AddHeader("content-disposition", "attachment; filename=" + HttpUtility.UrlEncode(bbb.xls")
Response.WriteFile(strOutFileName)
Response.End()

*******************

タスクマネージャーで見ると、Excel.exeが起動されている為、ダウンロード
ができない。

どなたがご教授をお願いできますか?
よろしくお願いします。

質問者:チャチャ

回答

チャチャさんの書き込み (2006-06-04 18:12) より:

タスクマネージャーで見ると、Excel.exeが起動されている為、ダウンロードができない。

COM の参照が解放されていないために、Excel のプロセスが居残っているのでしょう。
先ほど、類似スレッドが解決したのでご案内しておきます。

  またまた EXCEL のプロセスについて

objApp = CreateObject("Excel.Application")

objWBook = m_appWork.Workbooks.Open(strInFileName)

objSheet = m_wbkWork.Worksheets(1)

これ、おかしくないでしょうか?

Workbooks などが暗黙的に参照されて、解放できないままでいることもそうですが、
objApp に対して Excel.Application のインスタンスを生成しているのに、
objApp ではなく、m_appWork からどうこうしようとしています。

objWBook.Cells(1,1).Value = 1

objWBook.Cells(1,2).Value = 1

objWBook.Cells(1,3).Value = 1

objSheet = Nothing

objWBook = Nothing

objApp = Nothing

objApp.Quit()

すべて参照に取り、ReleaseComObject メソッドで参照カウントをデクリメントしましょう。
そうしないと、プロセスが終了せず居残ります。

以下のリンク先が参考になると思います。

  COM オブジェクトを解放する

________________C# と VB.NET の入門サイト
<a href="http://blogs.wankuma.com/jeanne/" target="
blank">じゃんぬねっと日誌

投稿者:じゃんぬねっと

編集 履歴 (0)

じゃんぬねっと様
ご回答ありがとうございます。

以下のソースをコピーしたので、うっかり間違いました。
objApp = CreateObject("Excel.Application")
objWBook = m_appWork.Workbooks.Open(strInFileName)
objSheet = m_wbkWork.Worksheets(1)
正しいのはこれです。
objApp = CreateObject("Excel.Application")
objWBook = objApp .Workbooks.Open(strInFileName)
objSheet = m_objWBook .Worksheets(1)

COMオブジェクトの解放について初めて知りました、
やってみます。
大変有難うございました。

投稿者:チャチャ

編集 履歴 (0)

チャチャさんの書き込み (2006-06-04 20:59) より:

以下のソースをコピーしたので、うっかり間違いました。

正しいのはこれです。

objApp = CreateObject("Excel.Application")

objWBook = objApp.Workbooks.Open(strInFileName)

objSheet = m_objWBook.Worksheets(1)

こちらも、ただの転記ミスかもしれませんが...
Excel.Workbook も、違うインスタンスを使われているようです。

COMオブジェクトの解放について初めて知りました、やってみます。

たとえば、

objWBook = objApp.Workbooks.Open(strInFileName)

ここも、Excel.Workbook*s* が暗黙的に参照されています。




    Dim xlWorkbooks As Excel.Workbooks
    xlWorkbooks = objApp.Workbooks

と Excel.Workbooks の参照を取り、




    Dim xlWorkbook As Excel.Workbook
    xlWorkbook = xlWorkbooks.Open(strFileName)

その参照から Workbook を取り出します。
あとは ReleaseComObject メソッドへ、参照したこの変数を すべて 渡して解放します。

これは、先ほどの Cells (Excel.Range) についても同様のことが言えます。
毎回、Cells を Excel.Range の変数に格納する必要があります。

________________C# と VB.NET の入門サイト
<a href="http://blogs.wankuma.com/jeanne/" target="
blank">じゃんぬねっと日誌

投稿者:じゃんぬねっと

編集 履歴 (0)

余談ですが、リクエストを出すクライアントに Excel のライセンスが必要になりますので、その点には注意しておきましょう。イントラネットならともかく、インターネットでは実質的に、この技術は使用できません。また、技術的にも懸念項目が数多くあります。

Office のサーバーサイド オートメーションについて

投稿者:未記入

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。