- ベストアンサー
二つ目のタブを閉じる方法とは?
- 質問文章では、VBAを使用して複数のタブを開いた後、特定のタブを閉じる方法についての質問です。
- 質問者は、特定のタブのみを閉じる方法を知りたいとしています。
- コードの実行により、最初に開いたタブが閉じられてしまうため、問題を解決したいとしています。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#DOUGLAS_ です。再度失礼いたします。 2番目の回答の「お礼」欄を見落としておりました。 >New キーワードを使えば、 >Set objIE = CreateObject("InternetExplorer.application") >はいらなくなるけど、 >そのかわり、 >Dim objShell As Object >Set objShell = CreateObject("Shell.Application") >この二つが必要になってくるのでしょうか? いいえ、全く違います。 Dim objShell As Object Set objShell = CreateObject("Shell.Application") は、「タブを扱うため」だけのウィンドウオブジェクトです。 1)タブのままでは、IEのオブジェクトとして捕まえることができないので 2)開いているウィンドウオブジェクトの中で 3)該当するインデックスのウィンドウ(IEのタブ)を捕まえておいて 4)そのウィンドウを、「IEの操作ができる」ように 5)IEオブジェクトに代入する といったイメージです。 >objIE.Navigate2 "~~", 2048 >で、2つ目・3つ目のタブを開く場合は、 >すでに1つ目のタブで生成したインスタンスがあるから >Dim objIE2 As New InternetExplorer >Dim objIE3 As New InternetExplorer >にしなくて良いようですね。 概ね、そういうことになりましょう。
その他の回答 (4)
- DOUGLAS_
- ベストアンサー率74% (397/534)
DOUGLAS_ です。 >objIE2、objIE3は、Object型でもいいのですか! 私の書き方が、却って問題を複雑にしたようですね。 >従って、「objIE2」・「objIE3」につきましては、 「As InternetExplorer」とせずに、「As Object」 >でも十分です。 という説明の仕方は不十分でした。 ご質問文内のコードに Dim objIE As InternetExplorer と書いていらっしゃるので、当然、VBE(Visual Basic Editor)で、[Microsoft Internet Controls] に参照設定していらっしゃるかと存じますが、そういうことなので、 Dim objIE As InternetExplorer という変数の宣言ができます(もし、それに参照設定していなければ、「コンパイル エラー: ユーザ定義型は定義されていません。」というエラーが出ます)。 VBE で、ローカル ウィンドウ を開き([表示(V)] - [ローカル ウィンドウ(S)])、#1 のコードの中で、 Dim objIE2 As Object としておいて、[F8] キーを押下しながら、ステップ イン デバッグ してみると、ローカル ウィンドウ の中で、各変数の「型」の変化を観察することができます。 objIE2 は最初、「Object」と表示されていますが、 Set objIE2 = objShell.Windows.Item(objShell.Windows.Count - 1) のタイミングで、「Object/IWebBrowser2」に変化します。 objIE は最初から「InternetExplorer/IWebBrowser2」ですが、objIE3 は Set objIE3 = objShell.Windows.Item(objShell.Windows.Count - 1) のタイミングで、「Object」から「InternetExplorer/IWebBrowser2」に変化します。 「As InternetExplorer」と宣言しようが、「As Object」と宣言しようが、いずれ「IWebBrowser2」というオブジェクトとして働くようになるということです(なお、[Microsoft Internet Controls] に参照設定せず、すべて「As Object」で宣言した場合は、すべて「Object/IWebBrowser2」に変化します)。 ただ、「InternetExplorer/IWebBrowser2」と「Object/IWebBrowser2」とで、何か違いがあるのか、という問題につきましては、 私には分かりません。 ひょっとしたら、メモリの消費量が「As InternetExplorer」の方が少ないのかもしれませんので、 >却って問題を複雑にしたようですね というのは、そういう意味で書きました。 ---------------------------------------- >インデックスがおかしくなるのと似ています。 >そうなのですか。 >この動作はやったことないのでわかりませんが、 >そういう事と同じなんだと覚えます。 1)セル A1:A9 に上から順番に「1,0,1,1,0,1,1,0,1」と入っていたとします。 2)ここで、セル値が「0」の行だけ削除するマクロを書くことにしましょう。 3)最初に「行番号の "小さな" 行から順に削除」するコードを書いてみると、 For i = 1 To 9 If Range("A" & i).Value = 0 Then Rows(i).Delete Next ということになりますが、 4)このコードだと、「i=2」のときに、「A2=0」ですので、2行目が削除されてしまいます。 5)したがって3行目以下が1行ずつ上に繰り上がってきます。 6)そうすると、本来「A3」セルにあったデータが「A2」セルに繰り上がってきます。 7)ところが、「i=2」のときに「Rows(i).Delete」した後、「i=3」になったタイミングで、 8)「Range("A" & i)」は、当然「Range("A3")」を読みにいきますが、 9)(5)の理由により、「Range("A3")」にあるデータは、元々「Range("A4")」に存在したデータですので、 10)つまり、元々「A3」にあったデータを読み飛ばしたことになります。 これが、 >行番号の "大きな" 行から順に削除していかないと >インデックスがおかしくなる と書いた意味です。 ---------------------------------------- >IEブラウザを新規に立ち上げるのも、 >既に立ち上がっているブラウザにタブを増やすのも >「インスタンスの作成をしている」という事になるのでしょうか? 私の環境(IE9)でテストしてみました。 1)[Ctrl] + [Alt] + [Delete] で タスクマネージャを起動します。 2)[イメージ名」をクリックして、名前順に並べ替えます。 3)そこに表示されている「iexplorer.exe」を全て終了してみます。 4)改めてIEを起動してみると、2つの「iexplorer.exe」が現われます。 5)新しいタブを開いてみると、3つ目の「iexplorer.exe」が現われます。 こうして、順次、新しい「IEのウィンドウまたはタブ」を開いてみると、ザクッと下記のようになりました。 「±0」というのは、タスクマネージャ上の「iexplorer.exe」の数が変わらないということです。 ・1番最初に開くIEのウィンドウ → +2(計2) ・2個目のIEのウィンドウまたはタブ → +1(計3) ・3個目のIEのウィンドウまたはタブ → +1(計4) ・4個目のIEのウィンドウまたはタブ → ±0(計4) ・5個目のIEのウィンドウまたはタブ → +1(計5) ・6個目のIEのウィンドウまたはタブ → ±0(計5) ・7個目のIEのウィンドウまたはタブ → ±0(計5) ・8個目のIEのウィンドウまたはタブ → +1(計6) ・9個目のIEのウィンドウまたはタブ → ±0(計6) ・10個目のIEのウィンドウまたはタブ → ±0(計6) ・11個目のIEのウィンドウまたはタブ → +1(計7) ・12個目のIEのウィンドウまたはタブ → ±0(計7) ・13個目のIEのウィンドウまたはタブ → ±0(計7) ・14個目のIEのウィンドウまたはタブ → +1(計8) ・1つずつ閉じていく → ±0(計8) ・最後のウィンドウを閉じる → -8(計0) ということで、 ・1番最初に開くIEのウィンドウ → +2 ・2・3個目のIEのウィンドウまたはタブ → +1 ・4個目以降は「6の倍数-1」個目の IEのウィンドウまたはタブを開いたときのみ → +1 ・閉じる場合は、全てのウィンドウを閉じる前まで → ±0 ・全てのウィンドウを閉じたとき、 → -全 ということで、「タブを追加」するのも、「新しいウィンドウを開く」のも、インスタンスの数の増減という点では、同じ扱いのようですが、その増え方が、上記の様に、ちょっと不規則なようです。
お礼
ご回答ありがとうございました。
補足
Dim objIE2 As Object にした場合、 ウォッチウインドウで「Object/IWebBrowser2」に変化するのを確認しました! Dim objIE As InternetExplorer にした場合、 ウォッチウインドウで「InternetExplorer/IWebBrowser2」に変化するのを確認しました! >「As InternetExplorer」と宣言しようが、 「As Object」と宣言しようが、 いずれ「IWebBrowser2」というオブジェクトとして働くようになるということです。 なるほど!よくわかりました。 「InternetExplorer/IWebBrowser2」と「Object/IWebBrowser2」の違いについては そのような理由なのかもしれないのですね。 エクセルの例、試してみました。意味がわかりました! おっしゃる通り、飛ばされました。 ブラウザを開くテスト、ありがとうございます。 「インスタンスが作成される」=「タスクマネージャーのプロセスが増える」 という事なのですか。 まず、そこからわかってませんでした。 タブやウインドウを開いたから必ずしもプロセスが増えるわけではないようですね。 実験していただいてありがとうございます。 今回とても勉強になりました! まだIE操作でいろいろやりたい事があり、またお世話になるかもしれませんが、その時はどうぞ宜しくお願いします。 ちなみに画像はNANAのシンちゃんですよね!?私もシンちゃん好きです!
- DOUGLAS_
- ベストアンサー率74% (397/534)
#たびたび失礼いたします。 #前回答の表記に誤りがありましたので、訂正いたします。 >しかし、"Shell.Application" のままでは、「Navigateメソッド」などが使えません というのは嘘ですね。 objIE.Navigate2 "http://www.goo.ne.jp/", 2048 objIE.Navigate2 "http://www.google.co.jp/", 2048 というように、IEの新しいインスタンスを複数作成しますので、その一つずつをオブジェクトに代入しておかないと、後で操作ができませんから、「IEの新しいインスタンスを作成」した「タイミング」で、 Set objIE2 = objShell.Windows.Item(objShell.Windows.Count - 1) Set objIE3 = objShell.Windows.Item(objShell.Windows.Count - 1) として、それぞれのウィンドウオブジェクトを「objIE2」・「objIE3」に代入した、と申した方が正しいですね。 従って、「objIE2」・「objIE3」につきましては、 Dim objIE2 As InternetExplorer Dim objIE3 As InternetExplorer とせずに、 Dim objIE2 As Object Dim objIE3 As Object でも十分です。 なお、 >「IEの新しいインスタンスを作成」した「タイミング」で >それぞれのウィンドウオブジェクトを「objIE2」・「objIE3」に代入 せずに、 objShell.Windows.Item(objShell.Windows.Count - 1).Quit などとしてしまうと、ウィンドウオブジェクトのインデックスが変わってしまい、どのウィンドウを操作しているのか判らなくなってしまいますので、やはり、 >「IEの新しいインスタンスを作成」した「タイミング」で >それぞれのウィンドウオブジェクトを「objIE2」・「objIE3」に代入 する必要がある、ということです。 ちょうど、エクセルのワークシートで、何も入っていない行を削除するVBAを書くときに、行番号の大きな行から順に削除していかないと「For i = 1 To Rows.Count ~ Next」の「i」のインデックスがおかしくなるのと似ています。
お礼
objIE2、objIE3は、Object型でもいいのですか! >エクセルのワークシートで、何も入っていない行を削除するVBAを書くときに 行番号の大きな行から順に削除していかないと 「For i = 1 To Rows.Count ~ Next」の「i」のインデックスがおかしくなるのと似ています。 そうなのですか。この動作はやったことないのでわかりませんが、そういう事と同じなんだと覚えます。 ちなみに頭がこんがらがってしまったので確認したいのですが IEブラウザを新規に立ち上げるのも、 既に立ち上がっているブラウザにタブを増やすのも 「インスタンスの作成をしている」という事になるのでしょうか? それともタブを増やすのはインスタンスの作成をしているわけではなくて、 新たにブラウザを立ち上げた時だけ「インスタンスの作成をした」という事にあるのでしょうか? 理解不足で申し訳ございません。ご回答よろしくお願いします。
- DOUGLAS_
- ベストアンサー率74% (397/534)
>objIE2とobjIE3にURLの情報を入れちゃうイメージですね。 まぁ、そのようなご理解でよいかと存じます。 >objIEだけnewを付けるのがポイントのようですね。 いいところに気が付かれました。 VBE(Visual Basic Editor) で「New」にカーソルを当て、[F1] キーを押下すると、[New キーワード] のヘルプが開きますので、[Dim ステートメント] をクリックしてください。 [指定項目] の「New」のところに、 -- ここから引用 ---------------------------------- このキーワードを指定すると、オブジェクトを暗黙的に作成できます。オブジェクト変数を宣言するときにキーワード New を指定した場合は、オブジェクトを最初に参照したときにオブジェクトの新しいインスタンスが作成されるので、Set ステートメントを使ってオブジェクトへの参照を代入する必要はありません。 -- ここまで引用 ---------------------------------- と書かれています。 前のご質問文内のコードに Dim objIE As InternetExplorer と書いていらっしゃいましたので、[Microsoft Internet Controls] に参照設定を施されていることが判りました。 このような場合には、 Set objIE = CreateObject("InternetExplorer.application") のように、「Set ステートメントを使ってオブジェクトへの参照を代入する必要」をなくすために、「キーワード New を指定」すればよいかと存じます。 >objIEだけnewを付けるのがポイントのようですね。 再度、この点について解説いたします。 最初の「InternetExplorer」、つまり「objIE」はIEを起動するためのオブジェクトですので、どうでもIEの新しいインスタンスを作成する必要があります。 従って、 Dim objIE As InternetExplorer Set objIE = CreateObject("InternetExplorer.application") でも良いわけですが、前述の理由により、「キーワード New を指定」して Dim objIE As New InternetExplorer としました。 ところが、2つ目・3つ目の「InternetExplorer」、つまり「objIE2」・「objIE3」につきましては、後から objIE.Navigate2 "~~", 2048 によって作成したIEのインスタンスを代入するためのオブジェクトですので、変数を宣言する時点(Dim)で、「オブジェクトを暗黙的に作成」してはいけませんので、「キーワード New を指定」していません。 ということで、 >CreateObject("InternetExplorer.application") >を使わずに、 >CreateObject("Shell.Application") >を使うべきなのでしょうか? というお尋ねは、ちょっと見当違いなご判断かと存じます。 新しいタブを開く時点で、「objIE2」・「objIE3」などに、直接、IEオブジェクトを格納できればよいのですが、 Dim objIE As New InternetExplorer Dim objIE2 As New InternetExplorer Dim objIE3 As New InternetExplorer としてしまうと、IEのウィンドウが3つ開くことになり、「新しいタブで」ということにはなりません。 ところで、IEの場合は、新しいタブを開くことは、IEの新しいインスタンスを作成することになり、また、IEのウィンドウがエクスプローラと同様のウィンドウオブジェクトとして認識されることを利用して、 >CreateObject("InternetExplorer.application") >を使わずに、 >CreateObject("Shell.Application") を使って、オブジェクトのインデックスにより、タブの番号を指定して操作することができます。 しかし、"Shell.Application" のままでは、「Navigateメソッド」などが使えませんので、 Set objIE2 = objShell.Windows.Item(objShell.Windows.Count - 1) のようにしてIEオブジェクトに代入する、という訳です。 簡単にまとめますと、 1)最初のIEオブジェクトで新しいタブを開く。 objIE.Navigate2 "http://www.goo.ne.jp/", 2048 2)開いたタブのウィンドウインデックスを取得する。 objShell.Windows.Count - 1 3)ウィンドウオブジェクトの中で当該インデックスのウィンドウをIEオブジェクトに代入する。 Set objIE2 = objShell.Windows.Item(objShell.Windows.Count - 1) 4)後は「Navigateメソッド」なり何なり、お好きな様にどうぞ。 objIE2.Quit という段取りです。
お礼
New キーワードのDim ステートメント読みました。 New キーワードを使うと、 ・オブジェクトを暗黙的に作成できる。 ・Set ステートメントを使ってオブジェクトへの参照を代入する必要はない のですね。 ひとつ確認ですが、 New キーワードを使えば、 Set objIE = CreateObject("InternetExplorer.application") はいらなくなるけど、 そのかわり、 Dim objShell As Object Set objShell = CreateObject("Shell.Application") この二つが必要になってくるのでしょうか? objIE.Navigate2 "~~", 2048 で、2つ目・3つ目のタブを開く場合は、 すでに1つ目のタブで生成したインスタンスがあるから Dim objIE2 As New InternetExplorer Dim objIE3 As New InternetExplorer にしなくて良いようですね。 確認してみましたが、 仰る通り、 Dim objIE2 As New InternetExplorer Dim objIE3 As New InternetExplorer にすると新しいIEブラウザが開いてしまいました。 まとめてくださりありがとうございます!
補足
再度二つもご回答いただきありがとうございます。 実は、諸事情で来週の月曜日までVBAがいじれなくて確認ができないので、 頂いたご回答を見ながら来週きちんと自分でVBAを動かしつつ確認してご回答します。 取り急ぎ、お礼を申しあげます。ありがとうございます。
- DOUGLAS_
- ベストアンサー率74% (397/534)
>http://hiroba.chintai.net/qa7823804.html こちらの「お礼」に >仕組みはわかりませんができました! とお書きですので、先ずは、 ●Internet Explorer 7でのIEオブジェクト作成方法・その2 http://www.happy2-island.com/vbs/cafe02/capter00711.shtml をご覧ください。 そこに記載されたコードは、エクセルのVBA用ではなくて、VBScript用ですが、コーディングの作法は、ほぼ同じですので、参考になるかと存じます。 ということで、下記みたいにすれば、指定のタブを閉じることはできます。 ただし、「objShell.Windows」の意味と「.Item(objShell.Windows.Count - 1)」というインデックスを付けるタイミングをよくご理解いただかないと、意図と異なるタブを閉じることになりますので、「- 1」辺りを足したり引いたりすることになるかも知れませんから、sfdajklweさんが書いていらっしゃるコードの実情に応じて書き換えてください。 Sub test() Dim objShell As Object Dim objIE As New InternetExplorer Dim objIE2 As InternetExplorer Dim objIE3 As InternetExplorer Set objShell = CreateObject("Shell.Application") objIE.Visible = True objIE.navigate "http://www.yahoo.co.jp/" objIE.Navigate2 "http://www.goo.ne.jp/", 2048 Set objIE2 = objShell.Windows.Item(objShell.Windows.Count - 1) objIE.Navigate2 "http://www.google.co.jp/", 2048 Set objIE3 = objShell.Windows.Item(objShell.Windows.Count - 1) objIE2.Quit objIE3.Quit objIE.Quit Set objIE = Nothing Set objIE2 = Nothing Set objIE3 = Nothing Set objShell = Nothing End Sub
お礼
まず仕組みを理解してからやるべきでしたね。失礼しました。 「objShell.Windows」 「.Item(objShell.Windows.Count - 1)」 についてはいまいちよくわかっていませんが、もっと調べて理解できるようにします。 objIE2とobjIE3にURLの情報を入れちゃうイメージですね。 あと、 Dim objIE As New InternetExplorer Dim objIE2 As InternetExplorer Dim objIE3 As InternetExplorer のように、 objIEだけnewを付けるのがポイントのようですね。 CreateObject("InternetExplorer.application") を使わずに、 CreateObject("Shell.Application") を使うべきなのでしょうか? 頂いたサンプルコードをを実行したら objIE2.Quitの部分でやりたいような動作になりました。 ありがとうございました。大変参考になりました。
お礼
Set objShell = CreateObject("Shell.Application") のご説明、ありがとうございます。 そういう流れなのですね。 一つ一つご丁寧に回答して頂きありがとうございました。 何度も付き合って頂きありがとうございます。