前にExcelのセルに入力された値をYahoo!で検索させるという仕掛けについて書いた。
この仕掛けは実際に仕事で使っているが、一つ難があった。IEでURLを開く際に、
CreateObject("InternetExplorer.Application")
だと実行するたびに新しいIEが起ち上がってしまう。うざいのでどうにかしようといろいろ調べたら、WindowsShellオブジェクトというのを使えばいいらしいことが分かった。開いているIEとエクスプローラがコレクションとして取得できるのである。
「If StrConv(objWindow.FullName, vbUpperCase) Like ~」が判別しているところ。
なんともかっこ悪いが、FullNameで実行ファイルのフルパスが返されるので「IEXPLORE.EXE」という文字列が含まれるか調べているのである。
Set objShell = CreateObject("Shell.Application") Set objWindows = objShell.Windows() For Each objWindow In objWindows If StrConv(objWindow.FullName, vbUpperCase) Like "*IEXPLORE.EXE" Then Set objIE = objWindow Exit For End If NextobjWindowsに開いているIEとエクスプローラが格納されるので、ループで一つずつ調べてIEかエクスプローラかを判別する。
「If StrConv(objWindow.FullName, vbUpperCase) Like ~」が判別しているところ。
なんともかっこ悪いが、FullNameで実行ファイルのフルパスが返されるので「IEXPLORE.EXE」という文字列が含まれるか調べているのである。
ループを抜けた後もobjIEがNothingだったら起動しているIEが無いということなので、今度こそ"InternetExplorer.Application"で新規に起ち上げればよい。
しかしこれだけではまだ解決しない。
起動しているIEを取得しただけでは、そのウィンドウはアクティブにならないからだ(新規に起ち上げれば勝手にアクティブになるが)。
起動しているIEを取得しただけでは、そのウィンドウはアクティブにならないからだ(新規に起ち上げれば勝手にアクティブになるが)。
AppActivateかと思ってやってみたが、引数にタイトルバーの文字列が必要である。
Windowオブジェクトのプロパティから生成できないこともないが、サイトによっては生成した文字列と実際のタイトルバーとが一致しなかった。
Windowオブジェクトのプロパティから生成できないこともないが、サイトによっては生成した文字列と実際のタイトルバーとが一致しなかった。
結局APIか。でもかんたんだった。
'強制的に最前面にさせる Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long '最小化されているか調べる Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Long '元のサイズに戻す Private Declare Function ShowWindowAsync Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long起動しているIEが最小化されていなければ、一つ目のSetForegroundWindowだけでアクティブにできる。最小化されている場合は、まずウィンドウを元の大きさに戻さないとアクティブにならない。なので三つ必要なのである。
で、実験用のプログラム。
ボタンをクリックするとIEがアクティブになり、A1のセルに入力されたURLを開く。
ボタンをクリックするとIEがアクティブになり、A1のセルに入力されたURLを開く。
もちろんこれならハイパーリンクになったセルをクリックすれば済む話だが、実際にはURLではなく検索したい文字列が入っている。文字列を元にURLを生成して、コード内でNavigateの引数として渡すのである。
ここは実験ってことで(^_^;)
ボタンに割り当てているコード↓
ここは実験ってことで(^_^;)
ボタンに割り当てているコード↓
Private Const SW_RESTORE = 9 'ShowWindowAsyncで元の大きさに戻す定数 Public Sub Open_IE() Set objShell = CreateObject("Shell.Application") Set objWindows = objShell.Windows() For Each objWindow In objWindows If StrConv(objWindow.FullName, vbUpperCase) Like "*IEXPLORE.EXE" Then Set objIE = objWindow hWnd = objIE.hWnd If IsIconic(hWnd) Then ShowWindowAsync hWnd, SW_RESTORE SetForegroundWindow objIE.hWnd Exit For End If Next If objIE Is Nothing Then Set objIE = CreateObject("InternetExplorer.Application") objIE.Visible = True End If objIE.Navigate Range("A1") End Sub ※変数宣言・エラー処理は略IE6でもIE7でも動いた。
ただしもっと細かいことを言えば、これだと複数のIEが起動していた場合は必ず最初に起動してあったIEで実行されてしまう。またIE7で複数のタブが開かれていた場合は、最初のタブで実行されてしまう(なので他のタブがアクティブにされていたら間抜けな状態になる)。
が、IEをいくつも開きっぱなしで仕事をしてる人など自分の周りにはいないので、とりあえずこれで解決したことにした。もっとちゃんとやればできるらしい。
それとAPIのSetForegroundWindow。
ここではちゃんと動いているが、ほんとはいろいろ難しい問題もあるらしい。
ここではちゃんと動いているが、ほんとはいろいろ難しい問題もあるらしい。
正直、難しくて分かりません(´・ω・`)