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

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

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

Re[10]: EXCEL2000でプロセスが開放されない


(過去ログ 47 を表示中)

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

■25338 / inTopicNo.1)  EXCEL2000でプロセスが開放されない
  
□投稿者/ しんくん (1回)-(2008/09/17(Wed) 21:01:19)

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

お世話になります。
VB2005でEXCEL2000にデータを出力しています。
winXPSP2で実行するとプロセスが開放されません。しかし、Windws2003サーバーで実行するとプロセスが開放されます。
色々なサイトで皆さんが飽き飽きしたネタだと思いますが、何がおかしいかご教授下さい。

Dim xlApplication As Excel.Application = Nothing
' COM オブジェクトの解放を保証するために Try 〜 Finally を使用する
Try
    xlApplication = New Excel.Application()
    ' 警告メッセージなどを表示しないようにする
    xlApplication.DisplayAlerts = False
    Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
    Try
        ' 既存の Excel ブックを開く
         Dim xlBook As Excel.Workbook = xlBooks.Open(wsPath)
         Try
            Dim xlSheets As Excel.Sheets = xlBook.Worksheets
            Try
                Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets(1), Excel.Worksheet)
                Try
                    Dim xlCells As Excel.Range = xlSheet.Cells
                    Try
                        'シートの再計算を中止(処理高速化のため)
                        xlSheet.EnableCalculation = False
                        Dim xlRange As Excel.Range = DirectCast(xlCells(3, 2), Excel.Range)
                        Dim xlBorders As Excel.Borders
                        Try
                            xlRange.Value = deCargoDate.Text
                        Finally
                            If Not xlRange Is Nothing Then
                                Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
                                If iRemainCount <> 0 Then
                                    MessageBox.Show("参照カウントの残り(xlRange) == " & iRemainCount.ToString())
                                End If
                                xlRange = Nothing
                            End If
                        End Try
                         '編集
                        For mrow As Integer = 0 To dt.Rows.Count - 1
                            For mcol As Integer = 0 To dt.Columns.Count - 2
                                xlRange = DirectCast(xlCells(mrow + 6, mcol + 2), Excel.Range)
                                xlBorders = DirectCast(xlRange.Borders, Excel.Borders)
                                Try
                                    xlBorders.LineStyle = Excel.XlLineStyle.xlContinuous
                                    xlRange.Value = dt.Rows(mrow).Item(mcol)
                                Finally
                                    If Not xlBorders Is Nothing Then
                                        Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBorders)
                                        If iRemainCount <> 0 Then
                                            MessageBox.Show("参照カウントの残り(xlBorders) == " & iRemainCount.ToString())
                                        End If
                                        xlBorders = Nothing
                                    End If
                                    If Not xlRange Is Nothing Then
                                        Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
                                        If iRemainCount < 0 Then
                                            MessageBox.Show("参照カウントの残り(xlRange) == " & iRemainCount.ToString())
                                        End If
                                        xlRange = Nothing
                                    End If
                                End Try
                            Next
                        Next
                        ''シートの再計算を再開
                        xlSheet.EnableCalculation = True
                        xlBook.SaveAs(wsNewPath)
                   Finally
                        If Not xlCells Is Nothing Then
                            Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
                            MessageBox.Show("参照カウントの残り(xlCells) == " & iRemainCount.ToString())
                            xlCells = Nothing
                        End If
                    End Try
                Finally
                    If Not xlSheet Is Nothing Then
                        Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
                        MessageBox.Show("参照カウントの残り(xlSheet) == " & iRemainCount.ToString())
                        xlSheet = Nothing
                    End If
                End Try
           Finally
                If Not xlSheets Is Nothing Then
                    Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
                    MessageBox.Show("参照カウントの残り(xlSheets) == " & iRemainCount.ToString())
                    xlSheets = Nothing
                End If
            End Try
        Finally
            If Not xlBook Is Nothing Then
                Try
                    xlBook.Close()
                Finally
                    Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
                    MessageBox.Show("参照カウントの残り(xlBook) == " & iRemainCount.ToString())
                    xlBook = Nothing
                End Try
           End If
       End Try
    Finally
        If Not xlBooks Is Nothing Then
            Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
            MessageBox.Show("参照カウントの残り(xlBooks) == " & iRemainCount.ToString())
            xlBooks = Nothing
       End If
    End Try
Finally
    If Not xlApplication Is Nothing Then
        Try
            xlApplication.Quit()
        Finally
            Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
            MessageBox.Show("参照カウントの残り(xlApplication) == " & iRemainCount.ToString())
            xlApplication = Nothing
        End Try
    End If
End Try

参照カウントの残りはすべてゼロです。
以上、宜しくお願い致します。

引用返信 編集キー/
■25339 / inTopicNo.2)  Re[1]: EXCEL2000でプロセスが開放されない
□投稿者/ おてやわらか (18回)-(2008/09/17(Wed) 21:11:40)
2008/09/17(Wed) 21:20:35 編集(投稿者)

コード自体を詳しく見たわけではないです。
せっかく、綺麗に入れ子にして書いているのですから、
まずは、御自分で、
各入れ子のどの段階まで来たら、解放されないようになっているかを確認する
のが先では、ないでしょうか?

作成されたアプリケーションを終了したら、Excelオブジェクトが解放される、されないのかとか
アプリケーションを終了しても、オブジェクトが解放されないのであれば、何か解放されない
原因があるはずですし、解放されるのであれば、アプリケーション側で対応すべき
何かがあるはずです。

再計算停止にしなければ成らないほどブックを、
テスト時に開くのは、原因切り分けを難しくすると思いませんか?
例えば、
第一段階として、軽い簡単なブックにして、コードをある程度完成させて
第二段階として、実際に近いブック、結果が想定できるもの、テストできるもの
第三段階として、実際のブック

引用返信 編集キー/
■25340 / inTopicNo.3)  Re[1]: EXCEL2000でプロセスが開放されない
□投稿者/ 渋木宏明(ひどり) (881回)-(2008/09/17(Wed) 21:37:20)
渋木宏明(ひどり) さんの Web サイト
> winXPSP2で実行するとプロセスが開放されません。しかし、Windws2003サーバーで実行するとプロセスが開放されます。

たまたまでしょう。
一方の実行環境で Excel.exe のインスタンスが居残らないからといって、それが解放漏れがないことの証明にはなりません。

なお、この場合は「解放」が正しい表現です。

> 色々なサイトで皆さんが飽き飽きしたネタだと思いますが、何がおかしいかご教授下さい。

たとえば

>Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets(1), Excel.Worksheet)

は、あなたが思い込んでいるよりも多く参照カウントがアップされてるはずですよ。

> 参照カウントの残りはすべてゼロです。

「あなたが意識している分」のカウントなので、大して意味ありません。

引用返信 編集キー/
■25343 / inTopicNo.4)  Re[2]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (2回)-(2008/09/17(Wed) 22:16:58)
おてやわらか様、渋木宏明(ひどり)様返信ありがとうございます。

再度詳しく調べてみます。

>>winXPSP2で実行するとプロセスが開放されません。しかし、Windws2003サーバーで実行するとプロセスが開放されます。
>
> たまたまでしょう。
> 一方の実行環境で Excel.exe のインスタンスが居残らないからといって、それが解放漏れがないことの証明にはなりません。

申し訳ございません。
XP SP2 とEXCEL2003、Vista と EXCEL2007の環境でもプロセスが解放されていたのでXPとEXCEL2000の問題と思い込んでいました。

>
> なお、この場合は「解放」が正しい表現です。
>

その通りですね。ご指摘ありがとうございます。

>>色々なサイトで皆さんが飽き飽きしたネタだと思いますが、何がおかしいかご教授下さい。
>
> たとえば
>

IT会議室、DOBON.NET、Visual Basic 初心者掲示板を拝見させて頂いた感想です。

> >Dim xlSheet As Excel.Worksheet = DirectCast(xlSheets(1), Excel.Worksheet)
>
> は、あなたが思い込んでいるよりも多く参照カウントがアップされてるはずですよ。
>

ここのホームページを参照に書いたのでxlSheetの参照カウントが多くアップされるとは思っていませんでした。

>>参照カウントの残りはすべてゼロです。
>
> 「あなたが意識している分」のカウントなので、大して意味ありません。
>

↑これは、私が意識して参照カウントを減らしているもの以外に減らさないといけないという意味でしょうか?
 また上記内容に書かれているxlSheetにかかわってくることでしょうか?

引用返信 編集キー/
■25349 / inTopicNo.5)  Re[3]: EXCEL2000でプロセスが開放されない
□投稿者/ 渋木宏明(ひどり) (882回)-(2008/09/17(Wed) 22:58:26)
渋木宏明(ひどり) さんの Web サイト
> ここのホームページを参照に書いたのでxlSheetの参照カウントが多くアップされるとは思っていませんでした。

DirectCast() により、内部的に COM の IUnknown::QuerInterface() 呼び出しが行われます。
QueryInterface() に成功すると、参照カウントは1増加します。

結果、あなたが思っているのよりも1つ多く参照カウントが増加しているはずです。

> ↑これは、私が意識して参照カウントを減らしているもの以外に減らさないといけないという意味でしょうか?

そういうことです。

引用返信 編集キー/
■25372 / inTopicNo.6)  Re[4]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (3回)-(2008/09/18(Thu) 14:40:00)
2008/09/18(Thu) 14:40:31 編集(投稿者)
お世話になります。
おてやわらか様のご指摘通りに1つずつ確認しているのですが、
EXCELをオープンしてCLOSEするだけで、EXCELプロセスが消えません。
何がおかしいか、ご教授願えませんでしょうか?
Dim xlApplication As Excel.Application = Nothing
' COM オブジェクトの解放を保証するために Try 〜 Finally を使用する
Try
    xlApplication = New Excel.Application()
    ' 警告メッセージなどを表示しないようにする
    xlApplication.DisplayAlerts = False
    Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
    Try
        ' 既存の Excel ブックを開く
         Dim xlBook As Excel.Workbook = xlBooks.Open(wsPath)
         Try

         'この間はコメントアウトしています。

         Finally
            If Not xlBook Is Nothing Then
                Try
                    xlBook.Close()
                Finally
                    Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
                    MessageBox.Show("参照カウントの残り(xlBook) == " & iRemainCount.ToString())
                    xlBook = Nothing
                End Try
           End If
       End Try
    Finally
        If Not xlBooks Is Nothing Then
            Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
            MessageBox.Show("参照カウントの残り(xlBooks) == " & iRemainCount.ToString())
            xlBooks = Nothing
       End If
    End Try
Finally
    If Not xlApplication Is Nothing Then
        Try
            xlApplication.Quit()
        Finally
            Dim iRemainCount As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
            MessageBox.Show("参照カウントの残り(xlApplication) == " & iRemainCount.ToString())
            xlApplication = Nothing
        End Try
    End If
End Try


引用返信 編集キー/
■25373 / inTopicNo.7)  Re[5]: EXCEL2000でプロセスが開放されない
□投稿者/ 魔界の仮面弁士 (858回)-(2008/09/18(Thu) 15:10:27)
No25372 (しんくん さん) に返信
> EXCELをオープンしてCLOSEするだけで、EXCELプロセスが消えません。

一部の環境のみで消えないのですよね。何点か確認させてください。

(1) 自動起動されるアドインあるいは Excel マクロ等が含まれていませんか?
 → VBA などでグローバルオブジェクトにアクセスし、それが解放されていない場合、
  オートメーションで起動された Excel の解放処理を阻害することがあります。

(2) アクティベーションは済ませてありますか?
 → アクティベーションが済んでいない場合、その確認作業のために
  処理が中断される可能性があります。

(3) 現在の実行アカウントで、Excel 本体を一度でも起動した事がありますか?
 → Excelは初回起動時に、ユーザー設定(ユーザー名のイニシャルなど)を
  問い合わせてくる可能性があります。

(4) インストール時に完全インストールが行われていますか?
 → 不足しているコンポーネントがある場合、アドバタイズ インストールのために
  処理が中断される可能性があります。

(5) 対話モードを設定しなおしてみるとどうですか?
 → 強制終了した場合などにおいて、DisplayAlerts/Interactive/Visible が
  正常にリセットされず、それ以降のユーザー手動操作、あるいは外部からの
  オートメーション操作が、期待動作しなくなってしまう事があります。

(6) 管理外の Excel が、別途起動していたという事はありませんか?
 → 不要な Excel を、最初にすべて閉じてから再実行してみてください。
 On Error Resume Next
 Dim x As Nothing = Nothing
 x = GetObject(,"Excel.Application")
 Do Until x IsNot Nothing
  x.Quit
  Marshal.ReleaseComObject(x)
  x = Nothing
 Loop
 On Error GoTo 0

# あえて、非構造化例外処理で記述しています。
引用返信 編集キー/
■25375 / inTopicNo.8)  Re[6]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (4回)-(2008/09/18(Thu) 15:38:05)
魔界の仮面弁士様早速のご返信ありがとうございます。

> (1) 自動起動されるアドインあるいは Excel マクロ等が含まれていませんか?
>  → VBA などでグローバルオブジェクトにアクセスし、それが解放されていない場合、
>   オートメーションで起動された Excel の解放処理を阻害することがあります。
   アドイン及びマクロは含まれていません。   
>
> (2) アクティベーションは済ませてありますか?
>  → アクティベーションが済んでいない場合、その確認作業のために
>   処理が中断される可能性があります。
   EXCEL2000なのでアクティベーションは無いと思います。
>
> (3) 現在の実行アカウントで、Excel 本体を一度でも起動した事がありますか?
>  → Excelは初回起動時に、ユーザー設定(ユーザー名のイニシャルなど)を
>   問い合わせてくる可能性があります。
>
   何度か起動しております。

> (4) インストール時に完全インストールが行われていますか?
>  → 不足しているコンポーネントがある場合、アドバタイズ インストールのために
>   処理が中断される可能性があります。
   標準インストールしています。
   完全インストールで試してみます。
>
> (5) 対話モードを設定しなおしてみるとどうですか?
>  → 強制終了した場合などにおいて、DisplayAlerts/Interactive/Visible が
>   正常にリセットされず、それ以降のユーザー手動操作、あるいは外部からの
>   オートメーション操作が、期待動作しなくなってしまう事があります。
   対話モードで試してみましたが、変化ありませんでした。
>
> (6) 管理外の Excel が、別途起動していたという事はありませんか?
>  → 不要な Excel を、最初にすべて閉じてから再実行してみてください。

   記述していませんでしたが、EXCELをOPENする前にEXCELが起動しているかチェックを行っています。


引用返信 編集キー/
■25380 / inTopicNo.9)  Re[7]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (5回)-(2008/09/18(Thu) 17:20:19)
お世話になります。
色々試していて発見したのですが、Dim xlBook As Excel.Workbook = xlBooks.Open(wsPath)をDim xlBook As Excel.Workbook = xlBooks.AddにするとEXCELのプロセスが解放されます。
ローカルのDISKの中なのですが、見れていないのでしょうか?
テンプレートのファイルを開いてから処理を行いたいのでOPENしたいのですが、OPENの時は何か特別なことをする必要があるのでしょうか?
ご存知の方がいらっしゃいましたら、ご教授下さい。
宜しくお願い致します。


引用返信 編集キー/
■25382 / inTopicNo.10)  Re[8]: EXCEL2000でプロセスが開放されない
□投稿者/ 魔界の仮面弁士 (859回)-(2008/09/18(Thu) 17:52:56)
No25380 (しんくん さん) に返信
> 色々試していて発見したのですが、Dim xlBook As Excel.Workbook = xlBooks.Open(wsPath)を
何も記載されていない、まっさらなブックであっても駄目ですか?
また、ReadOnly:=True モードだとどうでしょう?

> Dim xlBook As Excel.Workbook = xlBooks.AddにするとEXCELのプロセスが解放されます。
= xlBooks.Add(wsPath) だとどうですか?
また、%APPDATA%\Microsoft\Excel\XLSTART は空になっていますか?

> 見れていないのでしょうか?
exe の実行アカウントは、wsPath で指定されたパスへのアクセス権を有していますか?


> ご教授下さい。
引用返信 編集キー/
■25389 / inTopicNo.11)  Re[9]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (6回)-(2008/09/18(Thu) 18:34:57)
魔界の仮面弁士様、ご返信ありがとうございます。

> 何も記載されていない、まっさらなブックであっても駄目ですか?
> また、ReadOnly:=True モードだとどうでしょう?
>
 ReadOnly:=True モードでは変化無かったのですが、まっさらなブックだとプロセスが解放されます。

> = xlBooks.Add(wsPath) だとどうですか?
> また、%APPDATA%\Microsoft\Excel\XLSTART は空になっていますか?
 xlBooks.Add(wsPath)に変更したのですが、変化は無かったです。
 またXLSTARTは空になっています。
> exe の実行アカウントは、wsPath で指定されたパスへのアクセス権を有していますか?
 EXCELファイルを手動で変更できるのでアクセス権は有しています。

 どうやら、EXCELのブックが悪さしているみたいですね。
 でも、見出しがあったり、罫線が引いてあるだけのブックなのですが・・・
 見出しをつけたり罫線を引いたり一つずつやってみます。

 もし、ご存知であればご教授をお願いします。

引用返信 編集キー/
■25393 / inTopicNo.12)  Re[10]: EXCEL2000でプロセスが開放されない
□投稿者/ しんくん (7回)-(2008/09/18(Thu) 19:10:19)
自己レスです。
新しくブックを作成し、元のブックからシートをコピーすると、プロセスが開放されるようになりました。
おてやわらか様、渋木宏明(ひどり)様、魔界の仮面弁士様ありがとうございました。

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


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

このトピックに書きこむ

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

管理者用

- Child Tree -