Shell32ライブラリのインスタンスのオブジェクト

このQ&Aのポイント
  • ExcelからInternet Explorerを操作して、任意のURLからデータを取得するための関数を作成しようとしています。
  • 関数はURLのアドレスとテキスト名を引数にとり、Internet Explorerへのオブジェクトを返します。
  • しかし、うまく動作しません。誰か詳しい方がいらっしゃいましたら教えてください。
回答を見る
  • ベストアンサー

Shell32ライブラリのインスタンスのオブジェクト

エクセルからインターネットエクスプローラを操作して、任意のULRをからデータを取得しようと考えています。URLのアドレスとテキスト名を引数として、IEへのオブジェクトを返す関数を作ろうかと思いましたが、一向にうまくいきません。コードの99%は、ネット、雑誌からの引用なので問題はない(継ぎ接ぎ上の問題はあるかと思いますが)と思います。やりたいことは、関数から返されるオブジェクトを使ってのTest()の最後の2行の.body.innerTextと、.body.innerHTMLの取得です。 どなたか詳しい方がいらっしゃいましたら教えてください。よろしくお願いいたします。 Sub test() Dim myIE As Object Dim URL_address As String Dim URL_Title As String Dim IE_Text As String Dim IE_Html As String ULR_address = "http://oshiete1.goo.ne.jp/c232.html" Ulr_Title = "教えて!goo Office系ソフト" myIE = IE_URL(URL_address, Ulr_Title) IE_Text = myIE.document.body.innerText IE_Html = myIE.document.body.innerHTML End Sub Function IE_URL(URL_address As String, URL_Title As String) As Object Dim myIE As SHDocVw.InternetExplorer Dim myIE2 As Object ' 起動しているIEの中にURL_Titleと合致するULRがあるか調べる With New Shell32.Shell For Each myIE In .Windows If UCase(Dir(myIE.FullName)) = "IEXPLORE.EXE" Then If myIE.document.Title = URL_Title Then myIE.Navigate URL_address Exit For End If End If Next End With 'URL_Titleと合致するURLがない場合、新たにIEを立ち上げて表示させる If myIE Is Nothing Then With New SHDocVw.InternetExplorer ' .Navigate URL_address .Visible = True End With Application.Wait Now + TimeValue("00:00:01") 'myIEにオブジェクトをセットさせるために再度全体を検索する(上のwithでオブジェクトを取得できれば不要) With New Shell32.Shell For Each myIE In .Windows If UCase(Dir(myIE.FullName)) = "IEXPLORE.EXE" Then If myIE.document.Title = URL_Title Then myIE.Navigate URL_address Exit For End If End If Next End With End If Set myIE2 = GetObject(myIE.FullName) IE_URL = myIE2 End Function

質問者が選んだベストアンサー

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。Wendy02です。 解決したようですが、 >オブジェクト変数またはWithブロック変数が定義されていませんって出てきました。 最初に書いたけれども、それは、消してしまいました。 >コードの99%は、ネット、雑誌からの引用なので問題はない(継ぎ接ぎ上の問題はあるかと思いますが)と思います。 すみません。読み違えました。ちょっと、言い訳させていただきます。ふだんは、気にしないのですが、今回は、特別なのです。私も、掲示板を長く利用していますが、ここはよいけれども、荒っぽい所もあるので、トラブルだけは、よく覚えています。 回答者として、他人のものを触れるのは、なかなか、難しい時があります。特に、異質な内容のコードは、神経質になってしまうのです。回答者側の私が、うかつに、(良否関係なく)注釈やコメントを書いて、その後、まったく関係のないことで、トラブルに巻き込まれることがあるからです。 どこをどの程度、直したのかはわかりませんが、今回のコードは、7割ぐらいはオリジナルを残しているように思えたのです。概して、そのコードは、上級レベルのワザはあるのですが、全体が、ちぐはぐしているのです。おそらく、オリジナル自体がそうだとは思うのですが、今回のようなレベルのコードが、一番、コメントなどが書きづらいものなのです。元を書いた人の実力のレベルが透けて見えてくるからです。こういう場合は、こちらが最初から書いたほうが、よほど気持ち的に楽なのです。 >?の件については、半角スペースが入るとgoo登録時に化けるみたいです。 それも、そのようですね。失礼しました。 この後に、だいたいは、IE_Hteml 側から切り分け作業をしていくのですが、その時に、正規表現のスキルを持たないと、ものすごく面倒になります。

wan_wan
質問者

お礼

なんども丁寧にありがとうございます。 私も、その点については、気になっておりました。VBA初心者の私は、やはり、自動記録と書籍、ネットからの引用の改編で基本部分を作るのですが、著作権の問題や、原本を書かれた人への配慮から、何度か、ここを利用させて頂いた時もできる限り別の例にたとえて質問をするようにしています。タダ、レベルが高くなればなるほど、例えでは、目的とする回答を得ることができなかったり、レス自体がつかなかったりします。今回は、自分のスキルを超えた範疇と思い、引用させて頂きました。(誠に問題ながら、原本を書かれた人に断っていませんが・・)そのお蔭で、Wendy02さんより、例えでは得られない貴重な意見も頂けました。特に、With New SHDocVw.InternetExplorer の部分なんて、Newってこのようにもつかえるんだぁ!てな程度でしか受け止めていませんでした。また、Setについても、随分、理解できた。に近づいたと思います。本当にありがとうございました。今後ともよろしくお願いいたします。

その他の回答 (1)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんばんは。Wendy02です。 ご自身のコードですか? コードのスタイルも独特ですし、無意味な部分がところどころあります。もし、他人のものでしたら、なるべく、そのURLはともかくとして、自分のものではない旨を書いてください。その人の力のレベルが分からなくなるのです。初歩的なミスがあるので、分かっているのか分かっていないのか、良く分からないのです。 ULR_address = "?http://oshiete1.goo.ne.jp/c232.html?" 最初に、VBAでは、この「?」区切り記号は、使えないと思います。 まったくの余談ですが、今は、 "http://oshiete1.goo.ne.jp/goo_oshiete.php3?c=232" このURLです。こちらのマクロで開かないので、何か失敗したかと思いました。 確か、前のURLのはずです。 Main側のコードには、最後に、  Set myIE = Nothing を入れてください。 Function IE_URL の中の、 With New Shell32.Shell は、参照設定した上でのことでしょうけれども、コードの中で、何度も、インスタンスを作っていたのでは、プロシージャの取得したオブジェクトがつながりません。 作成後に整えるためには可能でも、製作中の段階ではこういうのはしません。ローカルモジュールが見られないからです。 今回のコードは、まだ、緒についただけで、この先が難しいように思います。がんばってトライしてください。   With New Shell32.Shell   'myIE は、IEオブジェクトではありません。ただのオブジェクトです。     For Each myIE In .Windows       'Dir がヘンです。ありえません。      If UCase(Dir(myIE.FullName)) = "IEXPLORE.EXE" Then        'タイトルでチェックは難しいです。        '= では、ロジックが違います。<> です。         If myIE.document.Title = URL_Title Then           myIE.Navigate URL_address           Exit For         End If       End If     Next   End With     IEのTitel比較は、たとえば、このようなスタイルがよいです。   例:    If InStr(myIE.LocationName, "教えて") > 0 Then      UCase(Dir(myIE.FullName)) = "IEXPLORE.EXE" IE があるなしの前提なんていうのは、コード以前の問題だと思うのです。 ShellオブジェクトのWindow の中を探さなくてはいけません。 最後の部分で、別にGetObjectで、インスタンスを取り直す意味がないと思います。 僭越かもしれませんが、なるべく、元の雰囲気を壊さずに、私のほうから手直しをさせていただきました。一部、無駄な部分もありますが、元のコードと比較してみてください。レベル的には、そんなに難しいものではありません。 Function IE_URL(URL_address As String, URL_Title As String) As Object   Dim o As Object   Dim myIE As SHDocVw.InternetExplorer   Dim mySh As Shell32.Shell   Dim Connectflg As Boolean   Dim cnt As Long      On Error GoTo ErrHandler      Set myIE = New SHDocVw.InternetExplorer   Set mySh = New Shell32.Shell   Connectflg = False      ' 起動しているIEの中にURL_Titleと合致するULRがあるか調べる   With mySh          For Each o In .Windows       If StrComp(TypeName(o), "IWebBrowser2") = 0 Then 'TextCompare         If o.ReadyState = READYSTATE_COMPLETE Then          If o.LocationURL = URL_address Then           Set myIE = o           Connectflg = True           Exit For          End If         End If        End If     Next o   End With      'URL_Titleと合致するURLがない場合、新たにIEを立ち上げて表示させる   If Connectflg = False Then     With myIE       .Navigate2 URL_address       .Visible = True     End With   End If   With myIE     Application.Wait Now + TimeValue("00:00:01")          Do Until .ReadyState = READYSTATE_COMPLETE       cnt = cnt + 1       If cnt > 10000 Then  '失敗の時に、カウントを取って、離脱させる          MsgBox "アクセスできませんでした。", 64         Exit Function       End If     Loop   End With   Set IE_URL = myIE ErrHandler:   If Err.Number > 0 Then     MsgBox Err.Number & " : " & Err.Description   End If   Set myIE = Nothing   Set mySh = Nothing End Function

wan_wan
質問者

お礼

懇切丁寧な、回答ありとがとうございます。 私が、1から作ったコードでないことは、 >コードの99%は、ネット、雑誌からの引用なので問題はない(継ぎ接ぎ上の問題はあるかと思いますが)と思います。 と、お断りしておいたつもりですが、言葉が足らずにすみませんでした。ご指摘の問題点の何点かも、継ぎ接ぎから来た問題だと思います。 教えて頂いたことを、何度も読み返し、自分のものにしていきたいと思います。 ただ、教えて頂いたコードの中で、ErrHandler:の一行前に、Exit Functionを追加して Sub test() Dim myIE As Object Dim URL_address As String Dim URL_Title As String Dim IE_Text As String Dim IE_Html As String URL_address = "http://oshiete1.goo.ne.jp/c232.html" URL_Title = "教えて!goo Office系ソフト" myIE = IE_URL(URL_address, URL_Title)'←この部分でエラー発生!! IE_Text = myIE.document.body.innerText IE_Html = myIE.document.body.innerHTML End Sub で、呼び出してみたところ、オブジェクト変数またはWithブロック変数が定義されていませんって出てきました。オブジェクトへの参照の受取ができないという基本的なことだと思いますが、もし、おゆるし頂けるのならば、呼び出し側のコードについて、もう少し教えて頂けないでしょうか? よろしくお願いいたします。 ?の件については、半角スペースが入るとgoo登録時に化けるみたいです。

wan_wan
質問者

補足

追伸: 本当にありがとうございます。 myIE = IE_URL(URL_address, URL_Title) を set myIE = IE_URL(URL_address, URL_Title) としたところできました。 本当にありがとうございます。 今後ともよろしくお願いいたします。

関連するQ&A

  • Internet Explorerの起動状態をチェック

    IEが起動中の時はそれを使い、未起動の場合は新規に作成する、、、というのがしたくて次のようなコードをつくってみました。 ところが、 Set myIE = myShellwindows のところでエラーになります。 これを防ぐにはどのようにするといいのでしょうか? Sub Set_IE() Dim myIE As Object Dim myShellwindows As Object Dim myObject As Object Dim Flag As Boolean Set myShellwindows = CreatmyObject("Shell.Application").Windows() Flag = False For Each myObject In myShellwindows If TypeName(myObject) = "IWebBrowser2" Then Flag = True Exit For End If Next If Flag = True Then Set myIE = myShellwindows Else Set myIE = CreatmyObject("InternetExplorer.application") myIE.Visible = True End If Set myShellwindows = Nothing Set myIE = Nothing End Sub

  • オブジェクト??

    またまた困っております inputboxで入力した日付を検索して複数選択しようとしたのですが unionの使い方がよくわかりません(・・;) どこが間違っているのかもしくは何が足りないのか教えてください<m(__)m> どうかよろしくお願いします! Option Explicit Sub グラフ() Const SH_NAME As String = "VBA" Dim art As String Dim i Dim ws As Worksheet Dim endrow As Long Dim msg As String Dim writerow As Integer Dim grahu As Chart Dim target As Range Set ws = ThisWorkbook.Worksheets(SH_NAME) writerow = 2 art = InputBox("日付を入力してください") With ws endrow = .Cells(Rows.Count, 2).End(xlUp).Row For i = 2 To endrow If art = .Range("A" & i) Then Set target = Union(target, "D" & i) Else If InStr(msg, .Range("A" & i)) = 0 Then msg = msg & .Range("A" & i) & vbCrLf End If End If Next i target.Select End With If msg <> "" Then MsgBox msg End If MsgBox "グラフベースを作成しました" End Sub Set target = Union(target, "D" & i) ↑ここでエラーが起きて 「オブジェクトが必要です」と言われました どうすればよいのでしょうか?

  • VBAで起動しているIEの操作

    IEでOKWAVEを開いていたら イミディエイトウィンドウに タイトルを表示するのに 次の 記述をしましたが エラーになりました。 実行時エラー '-2147467259 (80004005)': 'Document' メソッドは失敗しました: 'IWebBrowser2' オブジェクト なぜでしょうか? IEは11です。 エクセルは2013 OSは windows7 ホームプレミアム vbsは次の通り Sub okwave() Dim colSh As Object Dim win As Object Dim strTemp As String Dim objIE As Object Set colSh = CreateObject("Shell.Application") For Each win In colSh.Windows If TypeName(win.document) = "HTMLDocument" Then If InStr(win.document.Title, "okwave") > 0 Then Set objIE = win Exit For End If End If Next Debug.Print objIE.document.Title End Sub

  • オブジェクト参照がオブジェクト インスタンスに設定されていません  というエラーについて

    タイトルの「オブジェクト参照がオブジェクト インスタンスに設定されていません」についてですが、 このエラーは、 null を参照しようとして例外が発生している エラーだと解釈しているのですが、nullでないのに、このエラーが出る場合はどのように対処すればいいのか教えてください。 下記のような文があるとします。 Dim aaa as String 'aaaは、データベースからデータをとってきています。 If aaa IsNot DBNull.Value Then DropDownList.SelectedItem.Text = aaa.TrimEnd 'ここでエラー End If aaaは、NullではないのでIf文の中に入っていくのですが、DropDownListにデータを入れようとすると、タイトルのようなエラーが発生します。 デバッグでaaaの値を見ても、ちゃんとデータが入っているし、Nullではないのですが、なぜこのようなエラーが出るのかわかりません。 このエラーは他に違う意味があるのでしょうか? また、他に影響している部分があるのでしょうか? どなたか教えてください。 よろしくお願いいたします。

  • サイトタイトルを取得するマクロが「応答なし」になる

    下記のマクロは、選択したセルのURLからサイトタイトルを取得するものです。 このマクロを使って、1万を越えるURLの作業をやろうとしています。 作業に取り掛かったのですが、下記のマクロがすぐに「応答なし」になり、 エクセルの画面が真っ白になり、Escでマクロを止めることもできません。 ようやくマクロを止めても応答なしのときはマクロが動いておらず、作業が進みません。 取得するサイトタイトルの数が多いため、 寝てるときにマクロを動かしてやっていきたいです。 下記のマクロを「応答なし」にせずに、順調にサイトタイトルを取得していくには、 どのような記述にすれば、できるようになるでしょうか? EXCEL2016です。 よろしくお願いいたします。 ↓応答なしになるマクロ Sub サイトタイトル() Dim rng As Range Dim url As String Dim s As String For Each rng In Selection url = rng.Value If url <> "" Then If url Like "*://*" Then s = GetTitle(rng.Value) Else s = GetTitle("https://" & url) If s = "Error" Then s = GetTitle("http://" & url) If s = "Error" Then s = GetTitle("https://www." & url) If s = "Error" Then s = GetTitle("http://www." & url) End If rng.Offset(, 1) = s End If Next End Sub Function GetTitle(url As String) As String Dim http As Object Dim html As Object Set http = CreateObject("MSXML2.XMLHTTP") Set html = CreateObject("htmlfile") GetTitle = "Error" On Error Resume Next http.Open "GET", url, False http.send If http.Status <> 200 Then Exit Function On Error GoTo 0 html.Write http.responseText GetTitle = html.Title End Function

  • Shell.ApplicationでのIEオブジェ

    目的のタブページのオブジェクトを取得することに成功したのですが、質問があります。 コードはVBSで書いています。 Dim objIE Set Shell=Wscript.CreateObject("Shell.Application") for each tmp in Shell.Windows if TypeName(tmp.document)="HTMLDocument" then'HTMLDocumentかつ if tmp.document.title="Google" then'そのページのタイトルが「Google」なら set objIE=tmp'代入 end if end if Next if objIE="" then WScript.Echo("目的のページが表示されてないっぽいです") WScript.Quit end if 'この時点で、objIEがその目的のページでのオブジェクト ここで、 objIE.alert("hoge")とできないのはどうしてなのでしょうか? alertはjavascriptの関数?だからですか?? でも、objIE.document.write("hoge")で、documentオブジェクトが使えるのはどうしてなんですか? documentオブジェクトはjavascirptのオブジェクトじゃないんですか? それともう1つ、上記コードの場合ですが、JSの場合 Shell.Windows.item(0)というので参照?できるっぽいですが、itemというメソッドはjavascirptだけのものなのでしょうか?vbsでは使えないのですか?何故なんですか?同じcomオブジェクトを参照してるんじゃないんですか?(?) どのオブジェクトがどれで、どのメソッドがどれなのかわからなくなります。 あと1つだけ! 上記コードでの、tmp.documentとはなんなのでしょうか?HTMLDocumentとは・・w 頭が混乱してます。どなたか回答よろしくお願いいたします。

  • 現在開いている全てのIEのURLのタイトルを取得し

    現在開いている全てのIEのURLのタイトルを取得したいのですが Sub test() Dim shl As Object Dim wnd As Object Dim doc As Object Dim frg As Boolean Set shl = CreateObject("Shell.Application") For Each wnd In shl.Windows() If TypeName(wnd.Document) = "HTMLDocument" Then Set doc = wnd.Document Debug.Print doc.Title Set doc = Nothing End If Next Set shl = Nothing End Sub このコードが If TypeName(wnd.Document) = "HTMLDocument" Then でエラーになる時とならない時があります。 エラーになる時は、 実行時エラー -2147467259 ’Document’メソッドは失敗しました:'IWebBrowser2'オブジェクト となります。 エラーが発生する時としない時の違いが分かりません。 そもそもどういう意味のエラーでしょうか? IE11、オフィス2010です。

  • サンプルプログラムでエラーが出てしまいます、対処法を教えて下さい。

    Sub test写真の連続挿入()   Dim myDir As String   Dim myFile As String   Dim i As Integer   Dim n As Integer   n = 10   myDir = "D:\写真\" myFile = Dir(myDir, vbNormal)   Application.ScreenUpdating = False   Do Until myFile = ""   If myFile <> "." And myFile <> ".." Then   If (GetAttr(myDir & myFile) And 16) <> 16 Then   i = i + 1   With ActiveSheet.OLEObjects("Image" & i)    .Object.PictureSizeMode = 3    .Object.Picture = LoadPicture(myDir &myFile)   End With   If i = n Then Exit Do   End If   End If   myFile = Dir   Loop   Application.ScreenUpdating = True End Sub このWith ActiveSheet.OLEObjects("Image" & i)の行でエラーが出てしまいます、対処法を教えて下さい。( 実行時エラー'1004'OLEObjects プロパティを取得できません)

  • VBAでWebに値を入力

    VBAでWebに値を入力する操作を考えています。 エクセルシートのA1に入っている値をWeb上に入力する操作なのですが、 以下のコードを実行すると「AllLog.keyword.Value = t」の部分でエラーになります。 googleではkeywordのところを「q」、yahooではkeywordのところを「p」にすれば問題ないのですが、 神奈川中央交通のページではエラーになってしまいます。 なぜですか?? Sub google() Dim objIE As InternetExplorer '参照設定:Microsoft Shell Controls and Automation Dim objShell As Shell Dim WinFlg As Boolean Dim objWin As Object Dim AllLog As Object On Error GoTo EndProcess Set objShell = New Shell For Each objWin In objShell.Windows If TypeName(objWin) = "IWebBrowser2" Then WinFlg = True Set objIE = objWin Exit For End If Next Set objShell = Nothing If WinFlg = False Then MsgBox "IEオブジェクトが取得できません", vbCritical Exit Sub End If EndProcess: If Err() > 0 Then MsgBox Err.Description End If With objIE Set AllLog = .Document.all t = Cells(1, 1) AllLog.keyword.Value = t End With Set objIE = Nothing End Sub

  • VBAでMicrosoft Edgeから開く方法

    ExcelVBAマクロについて確認させてください。 これは「Internet Explorer(IE)」になっているので「Microsoft Edge」また「Google Chrome」ソフトに変更する場合はどのように変更すればよいかご教授くださいm(_ _)m 下記のプログラムの具体的な仕様 1)現在開いているInternet ExplorerのWebサイトアドレスをA1セルから順に出力する。 2)A1セルに主力したWebサイトアドレスを一つずつ開いて、閉じる。 Sub test() '現在開いているURLの取得 Dim sh As Object Dim win As Object Dim buf As String Dim i As Integer Dim n As Integer Dim strUrl As String Set sh = CreateObject("Shell.Application") For Each win In sh.Windows 'ウインドウの数だけ回す If win.Name = "Internet Explorer" Then buf = buf & " " & win.LocationURL End If Next '空白毎に区切ってセルに代入 Worksheets(1).Range("A1").Resize(UBound(Split(Trim(buf), " ")) + 1).Value = WorksheetFunction.Transpose(Split(Trim(buf), " ")) i = Worksheets(1).Cells(1, 1).End(xlDown).Row '現在開いているURLの数を取得 For n = 1 To i strUrl = Worksheets(1).Cells(n, 10) '文書策定画面を文字列strUrlに代入 'IEオブジェクトを作成 Dim ie As InternetExplorer Set ie = New InternetExplorerMedium 'IEを表示(見えるようにする) ie.Visible = True '指定したURLをIEで開く ie.navigate strUrl 'サイトの読み込みが完了するまで待つ Do While ie.Busy = True Or ie.readyState < READYSTATE_COMPLETE DoEvents Loop 'オブジェクトを閉じる ie.Quit 'メモリからオブジェクトを破棄 Set ie = Nothing Next n End Sub

専門家に質問してみよう