Excelが既に起動しているか?

解決


よっしー  2009-07-30 21:29:36  No: 142284  IP: 192.*.*.*

Excelが既に一つでも起動しているかを知りたいのですが、
下の様にするとExcelが起動していてもしていなくても
起動している事になります。
どうおかしいでしょうか?やはり
GetObject(, "Excel.Application")
ここだとは思うのですが、わかりません。
御願いします。

    Private Sub Excel_chk()
        Dim xlApp As Object
        On Error Resume Next
        xlApp = GetObject(, "Excel.Application")
        MsgBox(xlApp.name)
        If xlApp Is Nothing Then
            MsgBox("Excelは起動してません")
        Else
            MsgBox("Excelは起動してます" & vbLf & xlApp.ActiveCell)
        End If
        On Error GoTo 0
        xlApp = Nothing
    End Sub

編集 削除
まずは  2009-07-31 04:45:47  No: 142285  IP: 192.*.*.*

なにが
>わかりません。
であるのか不明ですが

On Error Resume Next

はすべてのエラーを無視するわけですからこれをとること
により別のことが明らかになってくるはずです。

編集 削除
まずは  2009-07-31 04:48:13  No: 142286  IP: 192.*.*.*

表現がよくないですね

>これをとること
とはこの行を無効にすること、コメントアウトすること、です。

        Dim xlApp As Object
        'On Error Resume Next
        xlApp = GetObject(, "Excel.Application")

編集 削除
よっしー  2009-07-31 10:32:02  No: 142287  IP: 192.*.*.*

VB2008ですが、下の様にしてみました。
結果は、Excelを起動していてもいなくても
メッセージは  Microsoft Excelと表示して、
更に"Excelは起動してます"と表示されます。

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim xlApp As Object
        'On Error Resume Next
        xlApp = GetObject(, "Excel.Application")
        MsgBox(xlApp.name)
        If xlApp Is Nothing Then
            MsgBox("Excelは起動してません")
        Else
            MsgBox("Excelは起動してます")
        End If
        On Error GoTo 0
        xlApp = Nothing
    End Sub
End Class

編集 削除
特攻隊長まるるう  2009-07-31 11:30:47  No: 142288  IP: 192.*.*.*

VB2008 ですが結果が違います。
[GetObject 関数 (Visual Basic)]
http://msdn.microsoft.com/ja-jp/library/e9waz863.aspx

> 既定の動作
の解説どおりの動きを確認できました。
起動していない時はエラーが発生しますので、提示された
コードでは判定できませんが。

Excel のプロセスだけずっと残ってるんじゃないですか?
つまり起動していない時のテストができていないのでは?

編集 削除
特攻隊長まるるう  2009-07-31 11:37:25  No: 142289  IP: 192.*.*.*

あ、再現しました。判定文を
> If xlApp Is Nothing Then
にしてるからですね。
エラーが起こっても戻り値は作成されていて
Nothing では無いですね。
それを無理やり On Error Resume Next で
動かしてるから同じ結果しか出せないようです。

デバッグ実行して変数の中身確認すれば分かったことでは?

編集 削除
特攻隊長まるるう  2009-07-31 11:51:44  No: 142290  IP: 192.*.*.*

あ、違う違う!
まずは さんの提案に従って
>On Error Resume Next
コメントアウトしてるんだから
エラーにならないとおかしい。

最初の現象の説明は「判定文が違う」だけど
コメントアウトしてからの動作がヘルプ(MSDN)
と違うのは別の原因です。
確認方法が悪いか、プロセスが残ってるか、
別の場所で起動しちゃってるかあたりだと思います。

編集 削除
よっしー  2009-07-31 13:01:13  No: 142291  IP: 192.*.*.*

こちら超ひよこの為わからない事だらけで済みませんが、
コメントの件も気になるので、下の様にして再度確認
しました。

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim xlApp As Object
        xlApp = GetObject(, "Excel.Application")
        MsgBox(xlApp.name)
        If xlApp Is Nothing Then
            MsgBox("Excelは起動してません")
        Else
            MsgBox("Excelは起動してます")
        End If
        xlApp = Nothing
    End Sub
End Class

結果は、Excelを起動していてもいなくても
メッセージは  Microsoft Excelと表示して、
更に"Excelは起動してます"と表示されます。

Windowsのタスクマネージャのアプリケーションを見てみると
Excelは起動してません。
>Excel のプロセスだけずっと残ってるんじゃないですか?
と言う事ですが、これを確認したら起動していないと考えて
良いと思っているのですが、違いますか?

編集 削除
魔界の仮面弁士  2009-07-31 13:03:33  No: 142292  IP: 192.*.*.*

> Windowsのタスクマネージャのアプリケーションを見てみると

[アプリケーション]タブではなく、
[プロセス]タブを見てください。

非表示のウィンドウは[アプリケーション]タブには表示されません。

編集 削除
よっしー  2009-07-31 15:34:59  No: 142293  IP: 192.*.*.*

お世話になります。
Excelがタスクマネージャーのプロセスにありましたので、
終了して再度実行しましたら。
異なるエラーが出ました。
***
exceptionはハンドルされませんでした。
cannot crate activex componet
***
と表示されました。
ヘルプをいろいろ見ていると

Visual Basic (宣言) 
Public ReadOnly Property InnerException As ExceptionVisual Basic (使用法) 

Dim instance As Exception
Dim value As Exception
value = instance.InnerException

これらをいれろと書いている様に思えますが、入れるとまたエラーの嵐で不明です。

編集 削除
魔界の仮面弁士  2009-07-31 16:06:15  No: 142294  IP: 192.*.*.*

> 異なるエラーが出ました。
『異なるエラー』という事は、今までもエラーが出ていたのでしょうか?

Excel が起動していないのにエラーになるのは、正常な動作です。


Excel が起動していなかった場合、GetObject は失敗しますので、
そのエラーを Try Catch もしくは On Error で処理する事で、
起動済みかどうかを判定するというのが、この処理の骨子です。

ただし、
> xlApp = GetObject(, "Excel.Application")
> MsgBox(xlApp.name)
これはいけません。GetObject が失敗した場合、xlApp にはオブジェクトが
割り当てられませんので、その Name プロパティにはアクセスできません。
Name プロパティを利用するなら、起動判定の If 文の後にしましょう。

# ついでにいうと、Marshal.ReleaseComObject の呼び出しを行わずに
# ただ Nothing をセットしているだけというのも問題ありますが。


> ヘルプをいろいろ見ていると
ヘルプの表記は、その例外処理の定義を表しているだけであって、
利用者のコードに、そのような記述を求めている訳ではありません。

内部例外(InnerException)を扱いたい場合には、On Error の代わりに
  Try
      ここにエラーの発生する処理を記述
  Catch ex As Exception
      MsgBox(ex.Message)
      If ex.InnerException IsNot Nothing Then
        MsgBox(ex.InnerException.Message)
      End If
  End Try
といった Try〜Catch 構文を利用する事になります。

編集 削除
よっしー  2009-07-31 23:29:19  No: 142295  IP: 192.*.*.*

>『異なるエラー』という事は、今までもエラーが出ていたのでしょうか?
済みません間違いです。今までExcelが残っていたので、エラーは無い状態でした。
お陰様で少しわかりました。色々と手抜きプログラムであろうと言う事。
しかし、今はこの程度でよしとします。
とりあえず手抜きでも私としては満足となりましたので、
ご報告致します。どうも有り難う御座いました。

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim xlApp As Object
        On Error Resume Next
        xlApp = GetObject(, "Excel.Application")
        If xlApp Is Nothing Then
            MsgBox("Excelは起動してません")
        Else
            MsgBox("Excelは起動してます")
        End If
        xlApp = Nothing
    End Sub
End Class

編集 削除