アプリ版:「スタンプのみでお礼する」機能のリリースについて

エクセルからインターネットエクスプローラを操作して、任意の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

A 回答 (2件)

こんばんは。

Wendy02です。

解決したようですが、
>オブジェクト変数またはWithブロック変数が定義されていませんって出てきました。

最初に書いたけれども、それは、消してしまいました。

>コードの99%は、ネット、雑誌からの引用なので問題はない(継ぎ接ぎ上の問題はあるかと思いますが)と思います。

すみません。読み違えました。ちょっと、言い訳させていただきます。ふだんは、気にしないのですが、今回は、特別なのです。私も、掲示板を長く利用していますが、ここはよいけれども、荒っぽい所もあるので、トラブルだけは、よく覚えています。

回答者として、他人のものを触れるのは、なかなか、難しい時があります。特に、異質な内容のコードは、神経質になってしまうのです。回答者側の私が、うかつに、(良否関係なく)注釈やコメントを書いて、その後、まったく関係のないことで、トラブルに巻き込まれることがあるからです。

どこをどの程度、直したのかはわかりませんが、今回のコードは、7割ぐらいはオリジナルを残しているように思えたのです。概して、そのコードは、上級レベルのワザはあるのですが、全体が、ちぐはぐしているのです。おそらく、オリジナル自体がそうだとは思うのですが、今回のようなレベルのコードが、一番、コメントなどが書きづらいものなのです。元を書いた人の実力のレベルが透けて見えてくるからです。こういう場合は、こちらが最初から書いたほうが、よほど気持ち的に楽なのです。

>?の件については、半角スペースが入るとgoo登録時に化けるみたいです。

それも、そのようですね。失礼しました。

この後に、だいたいは、IE_Hteml 側から切り分け作業をしていくのですが、その時に、正規表現のスキルを持たないと、ものすごく面倒になります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/04/09 09:14

こんばんは。

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

この回答への補足

追伸:
本当にありがとうございます。
myIE = IE_URL(URL_address, URL_Title)

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

補足日時:2007/04/08 22:41
    • good
    • 0
この回答へのお礼

懇切丁寧な、回答ありとがとうございます。
私が、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登録時に化けるみたいです。

お礼日時:2007/04/08 21:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!