Excelのロセスを終了する方法は??


ゆう  2004-08-04 22:13:54  No: 115347  IP: [192.*.*.*]

VB.NETでエクセルを操作するとタスクマネージャのプロセスに
EXCEL.EXEが残ってしまいます。
自分なりにプロセスを終了する方法を試してみたのですが、できません。

こんな感じで終わらせています。
Dim oExcel As Object

oExcel.Application.Quit()
oExcel = Nothing
GC.Collect()

EXCELのプロセスを終了する何かいい方法はないでしょうか?

編集    削除
ファリンファリン  2004-08-04 22:17:58  No: 115348  IP: [192.*.*.*]

System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
で、どうでしょう?
詳しくは
http://support.microsoft.com/default.aspx?scid=kb;ja;317109

編集    削除
ゆう  2004-08-05 02:01:43  No: 115349  IP: [192.*.*.*]

遅くなって申し訳ありません。
最初に
Imports Microsoft.Office.Interop
を追加しました。

oExcel.Application.Quit()
            oExcel = Nothing
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
            GC.Collect()
その後このように記述したのですがエラーになってしまいます。
なにか間違っているところがあるのでしょうか??

編集    削除
ファリンファリン  2004-08-05 02:41:26  No: 115350  IP: [192.*.*.*]

ご紹介したページでは
ReleaseComObject()
した後に
oExcel = Nothing
してますよ。
参照されてますか?

出来れば、エラーが発生する行を教えて頂けると
原因がつかみ易いです。

編集    削除
魔界の仮面弁士  2004-08-05 02:46:44  No: 115351  IP: [192.*.*.*]

# KBの317109のコードにも若干の問題はありますが、それはさておき。

> oExcel.Application.Quit()
Applicationプロパティは、基本的に使わないで下さい。

この場合、oExcel は Excel.Applicationクラスの変数だと思いますが、
もしそうなら、oExcel.Quit() で充分ですよ。


> oExcel = Nothing
> System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
これはつまり、
 System.Runtime.InteropServices.Marshal.ReleaseComObject(Nothing)
という事になりますよね。これでは意味がありません。

使い終わったActiveXコンポーネント(COMコンポーネント)は、
「Marshal.ReleaseComObjectしてから、Nothingする」ようにしてください。
(つまり、順番が逆です)


なお、ReleaseComObjectメソッドは Excel.Application に対してだけではなく、
「全てのCOMオブジェクト」に対して行う必要があります。
http://www.bcap.co.jp/hanafusa/bbs/wforum.cgi?mode=allread&no=997&page=0

編集    削除
ゆう  2004-08-05 17:37:25  No: 115352  IP: [192.*.*.*]

返信有難うございます。

oExcel.Quit()
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
            oExcel = Nothing
            GC.Collect()

編集    削除
ゆう  2004-08-05 17:37:25  No: 115353  IP: [192.*.*.*]

返信有難うございます。

oExcel.Quit()
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
            oExcel = Nothing
            GC.Collect()

編集    削除
ゆう  2004-08-05 17:42:09  No: 115354  IP: [192.*.*.*]

↑    ↑    ↑      ↑
これらの記述に書き直し実行したらエラーは出ないのですが、
プロセスのEXCEL.EXEがのこってしまいます。

なにか間違っているのでしょうか??

編集    削除
魔界の仮面弁士  2004-08-05 21:08:14  No: 115355  IP: [192.*.*.*]

> なにか間違っているのでしょうか??

正しくコーディングされていれば、最後の Marshal.ReleaseComObject(oExcel) を
実行した時点で、Excelのプロセスが消えるはずです。それで消えないなら、
他にも「ReleasComObjectしていないオブジェクト」があるのだと思います。

# .NETとCOMではメモリ管理方法に違いがあるので、.NETからCOMを
# 呼ぶ場合には、すべてのCOMオブジェクトを Marshal.ReleaseComObjectで
# 明示的に解放する必要があります。


たとえば…
  oExcel.Visible = True
  oBook = oExcel.Workbooks.Open("C:\Book1.xls")
  MessageBox.Show("開きました。")
  oBook.Close(False)
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
  oBook = Nothing
  oExcel.Quit()
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
  oExcel = Nothing

のようなコードの場合、
 「Excel.Application」オブジェクト (変数 oExcel)
 「Excel.Workbook」オブジェクト (変数 oBook)
は解放されていますが、
 「Excel.Workbooks」オブジェクト
が解放されていないため、プロセスが残ってしまいます。

このコードの場合、Workbooksも解放すればプロセスは残りません。

  oExcel.Visible = True
  oBooks = oExcel.Workbooks
  oBook = oBooks.Open("C:\Book1.xls")
  MessageBox.Show("開きました。")
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
  oBook.Close(False)
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
  oBook = Nothing
  oExcel.Quit()
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
  oExcel = Nothing

他のオブジェクト(WorksheetsやRangeなど)についても、解放し忘れている
物が無いか、よく探して見てください。

編集    削除
ゆう  2004-08-05 23:05:34  No: 115356  IP: [192.*.*.*]

返信有難うございます。

返信内容を元に

System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel.worksheets)
oExcel.worksheet.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel.worksheet)
oExcel.worksheet = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel.workbooks)
oExcel.workbook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel.workbook)
oExcel.workbook = Nothing

oExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel = Nothing
GC.Collect()

これで実行すると一番最初のworksheetsのクローズのところでエラーになってしまいます。

ちなみにプログラムで使っているのは

oExcel.worksheets

oExcel.workbooks

oExcel

                            だけです。


力不足で申し訳ありませんが宜しくお願いします。

編集    削除
Dental  2004-08-06 06:03:12  No: 115357  IP: [192.*.*.*]

ファリンファリンさんの回答にあるサイトや、魔界の仮面弁士さんのコードを、よ〜く見てください。

  oBooks = oExcel.Workbooks
     :
  (oBooksを利用したコード)
     :
  System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)

のように書いてありますよね。

それに対して、ゆうさんが書かれたコードは
> System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel.worksheets)
です。コードが違いますよね。

編集    削除
ゆう  2004-08-06 18:16:44  No: 115358  IP: [192.*.*.*]

返信有難うございます。

ようやく皆様が言っている内容が理解できました。
これで自分では間違っていないと思うのですが☆のところで
エラーがでてしまいます。

Dim oExcel As Object
Dim oBook As Object
Dim oBooks As Object
Dim oSheets As Object
Dim oSheet As Object

oExcel.Visible = False
oBooks = oExcel.Workbooks
oBook = oBooks.Open(FilePach)
oSheets = oExcel.worksheets
osheet = oSheets(Trim(lotNo))

System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheets)
oSheet.Close(False)    ☆(ここでエラー)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet)
oSheet = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
oBook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
oBook = Nothing

oExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel = Nothing
GC.Collect()

oSheetオブジェクトは必要なのでしょうか??

編集    削除
Dental  2004-08-06 21:24:56  No: 115359  IP: [192.*.*.*]

そもそも、最初の
> oExcel.Visible = False
でエラーになると思いますよ。
CreateObject等がされていないので、oExcel は Nothing ですよね。

> osheet = oSheets(Trim(lotNo))
lotNo に関する説明が無いので判断できませんが、この時点で、
oSheet は正しく取得出来ているのでしょうか?

> oSheet.Close(False)    ☆(ここでエラー)
どのようなエラーですか?

> oSheetオブジェクトは必要なのでしょうか??
使っているなら必要ですし、使っていないなら不要です。

編集    削除
ゆう  2004-08-06 22:13:35  No: 115360  IP: [192.*.*.*]

>CreateObject等がされていないので、oExcel は Nothing ですよね
すみません。
oExcel = CreateObject("Excel.Application")
でやっています。

>oSheet は正しく取得出来ているのでしょうか?
エクセルのシートの内容をフォームに持ってこれているので多分大丈夫です。
>どのようなエラーですか?
「型'Worksheet'でパブリックメンバ'Close'が見つかりません。
というエラーです。

oSheetはこのように使っています。
khk22.text データ表示用

khk22.Text = oSheet.Cells(i, 3).Value

編集    削除
ファリンファリン  2004-08-06 23:24:14  No: 115361  IP: [192.*.*.*]

>「型'Worksheet'でパブリックメンバ'Close'が見つかりません。
>というエラーです。
メンバに存在しないメソッドを呼ぼうとしているようです。
確かにWorkSheetにCloseは無いですね。
もしかして、VB6.0やVBAなどのコードをそのまま
写し書きしてたりします?

編集    削除
ゆう  2004-08-07 00:43:13  No: 115362  IP: [192.*.*.*]

>もしかして、VB6.0やVBAなどのコードをそのまま
写し書きしてたりします?

VBAをちょっとやっていたのでエクセル操作はその知識を元にやっています。

oSheetをCloseするのをやめたらエラーはでなくなったのですが、
EXCEL.EXEのプロセスが消えません。

編集    削除
特攻隊長まるるう  2004-08-09 20:29:21  No: 115363  IP: [192.*.*.*]

なんか基本的なところで気に入らないコーディングなのですが…
皆さん息切れ気味?なので書き込みしてみます。

>VBAをちょっとやっていたのでエクセル操作はその知識を元にやっています。
それは VBA には Worksheet オブジェクトに Close メソッドが
あったということですか???無いと思うんですが?。エクセルの
ヘルプなんかでちゃんと調べた上でのコーディングですか?
>これで自分では間違っていないと思うのですが
根拠はあるんですか?ちゃんと調べた上でのケアレスミスなら修正
すれば良いだけだと思いますが、適当な勘によるコーディングの結果
なら、そのスタイル自身変えないと、いつまでも同じような所で
前に進めないかもしれません。魔界の仮面弁士さんの書き込みから
も分かると思いますが、ご質問の問題は正確なオブジェクトの使い方
と開放の仕方が問題となりますから…。
で、変数の宣言なんですが、
>Dim oExcel As Object
>Dim oBook As Object
>Dim oBooks As Object
>Dim oSheets As Object
>Dim oSheet As Object
…何故、全部 Object 型なんですか?ファリンファリンさんご紹介の
リンク先も、魔界の仮面弁士さんご紹介のリンク先も Object 型は
使ってないと思いますが? Object 型は何でも入ってしまって
コーディングの段階でエラーが分かり難いです。当然、コーディングも
適当になりがちです。ですからボクは気に入りません。知識不足を補う
為にも
Dim oExcel As Excel.Application
Dim oBooks As Excel.Workbooks
Dim oBook As Excel.Workbook
Dim oSheets As Excel.Worksheets
Dim oSheet As Excel.Worksheet
と宣言して下さい。ついでにコードファイルの1行目で
Option Strict On
とするか[プロジェクト]の[プロパティ]から[共通プロパティ]
[ビルド]を選択し、Option Strict を On にして下さい。
変数と、その変数に用意されているメソッドやプロパティを
意識して使って下さい(まぁ、Excelオブジェクトを参照してる
時点でどうしても上手くいかない部分はありますが、その段階で
初めて Off にして下さい)。

まず、基本的な操作を花ちゃんさんのサイトから学んで下さい。
http://www.bcap.co.jp/hanafusa/dotnet/Excelflm.htm

サンプルそのままのコードで試してみて下さい。
ちゃんと説明コメントも読んで、適切な修正をしてからテスト
して下さいね?。ただし、おおまかなプログラムの流れは絶対に
変えないで下さい。コメントアウトを戻すとか、ファイルの
パスを修正するとか…その程度の修正のみにとどめて下さい。
その上でまだ EXCEL.EXE のプロセスが消えないのであれば
その段階で教えて下さい。
消えるのであれば一つ一つ自分のやりたいコードに近づけて、
どの段階で EXCEL.EXE のプロセスが消えなくなるか調べて
下さい。最初だけですから地道にやって下さいね?

編集    削除
uchiyama akira  2005-04-09 05:15:20  No: 115364  IP: [192.*.*.*]

VB6で、excelに対して処理するプログラムを作成しています。
そこで解決できない問題がありまして・・・

(したいこと)
1シート目を集計シートとして、2シート目〜最後のnシート目までの
同セル位置の合計(数式)を貼り付ける。

(エラー)
詳しい文言がでません(出し方を知らないだけですね・・・)が、
以下のコードstepです。
--------
Public Function SetData(wb As Object, xNumber As Integer, xAmount As Integer, yoko As Integer, j As Integer) As Integer

With wb.Sheets(j + 1)

'計算式をセルに設定
.Cells(xNumber, yoko).FormulaR1C1 = _
        "=SUM(" & LstBUYS1050(j + 1).BgMeisho & ":" & LstBUYS1050(NumBUYS1050 - 1).BgMeisho & "!RC)"
.Cells(xNumber, yoko).Copy

.Range("I12:Q79").Select
.Selection.PasteSpecial Paste:=-4123, Operation:=-4142, SkipBlanks:= _
    False, Transpose:=False  '☆←のstepでエラーになる(T◇T)

End With
--------
多分、.Selection.PasteSpecialの使い方が間違っているのだと思うのですが、
今現在、手元に書籍とかなく、webで検索した限りでは解りませんでした・・・
大変申し訳ないのですが、もしお知恵のある方いましたらアドバイス頂けませんでしょうか?

編集    削除
いな  2005-04-09 08:07:55  No: 115365  IP: [192.*.*.*]

>>もしお知恵のある方いましたらアドバイス頂けませんでしょうか?

アドバイスですが、
全く新しい質問は、新規でスレッドを起こすべきだと思います。

編集    削除
じゃんぬねっと  URL  2005-04-09 19:43:29  No: 115366  IP: [192.*.*.*]

> ご紹介したページでは
> ReleaseComObject()
> した後に
> oExcel = Nothing
> してますよ。

Com リリースしてあれば、通常は、Null 値を入れる必要はないですね。
通常は保険として、Finally に入れておくべきものです。
http://jeanne.wankuma.com/tips/programing/02-releasecom.html

編集    削除
特攻隊長まるるう  2005-04-09 20:35:34  No: 115367  IP: [192.*.*.*]

というか
uchiyama akira さんの質問はこちら↓で続けましょう
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200504/05040037.txt

…このスレッドの続きなら別に構いませんが…。

編集    削除