- ベストアンサー
「FindWindow」、ウィンドウハンドルについて
知恵を貸してください。 VB6.0にて作業しています。 コモンダイアログからExcelファイルを指定して開く際、 現在起動中のものを二重起動しないために「FindWindow」 を用いました。 最初は正常に動作したのですが、何度か操作しているうちに、 Excelを起動していない(ctrl+Alt+Delで確認し、何度も再起動しました)のに 起動中の処理(ハンドルを表示)をするようになってしまいました。 (1)ソースの正否 (2)ウィンドウハンドルからウィンドウを特定する方法 ハンドル(3409196)が表示されるため、この番号から 指定されたウィンドウを特定できれば 原因特定にいたるのではないかと考えました。 についてアドバイスいただけないでしょうか? 以下にコードを記述します。 *モジュール側の記述は省略しました。 Private Sub Command1_Click() Dim hwindow As Long Dim Fname As String Dim XLSApp As Object (前述分省略) cdl.ShowOpen Fname = cdl.FileName hwindow = FindWindow("XLMAIN", vbNullString) If hwindow = 0 Then Set XLSApp = GetObject(Fname) (以下指定ファイルを開く処理) Else MsgBox hwindow End If End Sub 以上です、よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
まったく別のアプローチですが、以下の方法を当方はよく利用します '------------------------------------------------ Dim XLSApp As Object On Error Resume Next 'エクセルが起動していない場合エラーになるためエラーを抑止 Set XLSApp = GetObject(, "Excel.Application") '開いているエクセルを取得 On Error GoTo 0 'エラー抑止を解除 If XLSApp Is Nothing Then MsgBox "エクセルは起動していません" Else MsgBox "エクセルは起動中です" End If '------------------------------------------------ また、以下の様に関数化して使用する方がよりお勧めです '------------------------------------------------ 'ActiveXExeが起動中か否かを返す '起動中=True/起動していない=False Public Function ExistActiveXExe(Byref argActiveXClassName As String)As Boolean Dim ObjExistCheck As Object On Error Resume Next Set ObjExistCheck = GetObject(, argActiveXClassName) On Error GoTo 0 ExistActiveXExe = Not (ObjExistCheck Is Nothing) Set ObjExistCheck = Nothing End Function '------------------------------------------------ 業務などで、"On Error Resume Next"使用禁止などの(頑迷な)ルールがある場合等、また"On Error Go To [ラベル]"が使用できる場合は関数化の方法なら簡単に書き換えられます。 On Error禁止の場合は、上記方法はあきらめてください。
その他の回答 (4)
- JeanneNet
- ベストアンサー率48% (100/208)
こんにちは、じゃんぬねっと です。 ひとつ気になったのが、 > Excelを起動していない(ctrl+Alt+Delで確認し、何度も再起動しました)のに これは、アプリケーション タブではなく、 プロセス タブに EXCEL がないことまで確認したんですよね? もし、マクロによって何らかのファイルを掴んでいたとしても、 ここに表示されると思いますので...
補足
じゃんぬねっと様 返信ありがとうございます。 私が見たのはアプリケーションタブの方です。 プロセスタブの方も確認し、確かにExcelの「.Exe」の表示はあったと記憶しています。 果たして終了させていいものか。。。と思いその箇所は触らずにいました。 確認するのはアプリケーションだけではないんですね。 ありがとうございます。m(_ _)m
- BellBell
- ベストアンサー率54% (327/598)
関数化の場合の使用方法を割愛したせいで混乱を招いたみたいですみません。 >If ExistActiveXExe("XLMAIN") = False Then の、"XLMAIN"部分ですが、エクセルの判定を行う場合に渡す文字列(ActiveXオブジェクト名)は"Excel.Application"です。 全文を書くと If ExistActiveXExe("Excel.Application") = False Then です。
お礼
BellBell様 ご説明ありがとうございます。 >関数化の場合の使用方法を割愛したせいで混乱を招いたみたいですみません。 ⇒とんでもありません。こちらこそ知識が足りずお手数おかけしました。当然ですが、無事動作しました^^; 無知は免罪符になりませんが、頂いたアドバイスを自分のものにできるよう精進したいと思います。 ありがとうございました。m(__)m
- JeanneNet
- ベストアンサー率48% (100/208)
あ、間違えた、Excel 自身の話だったのね... orz 試して見ましたが、何度やっても正しく動きます。 プロセスも死んでいたんですよね?
お礼
No.1にあわせてお礼いたしました。 遅くなりすみません。起動確認しておりました。
- JeanneNet
- ベストアンサー率48% (100/208)
こんにちは、じゃんぬねっと です。 二重起動防止ならば、Mutex を使う方法の方が確実だと思います。 こんなワードで検索してみてください。 http://www.google.co.jp/search?hl=ja&q=%E4%BA%8C%E9%87%8D%E8%B5%B7%E5%8B%95+%E7%A6%81%E6%AD%A2+Mutex&lr=
お礼
じゃんぬねっと様、回答ありがとうございます。 実はPCを数時間ほおっておいたところ、障害無く起動できるようになりました。 もしかして、マクロ入りのExcelを開いたことが原因でしょうか?(できるのかな、と思い昨日何度か試してました)
お礼
BellBell様、回答ありがとうございます。 なるほど、こういうアプローチ方法もあるのですね。 "On Error Resume Next"使用禁止はありませんので参考にさせてください。 なお、じゃんぬねっと様へのお礼の欄にも書きましたが、 プログラムが動くようになりました。 マクロを起動させたために、ずっとExcelが開放されなかった(表現が違っていたらすみません) のかと思っています。 もし、マクロが原因ならば、マクロを含むEXCELは、はじく処理もいれないと。。。ですね。
補足
頂いた回答で教えていただきたいのですが、 関数化の方は、'ActiveXExeが起動中か否かを返す' なので、Excelが起動中かどうかを調べるためには Function ExistActiveXExe の所をExcelに変えればよいのでしょうか? ExistActiveXExe argActiveXClassName ObjExistCheck は単なる文字列だと解釈していたので、宣言部分をそのまま使い、 下記のように記述したところ If ExistActiveXExe("XLMAIN") = False Then Excelを起動中でも起動していなくても同じ結果を返してきました。(どちらの回答も起動中) せっかく教えていただいたので、関数化の方も使いたいと考えています。 大変お手数ですが、使い方を教えてください。 申し訳ありません。