さきほど初心者質問版で質問させていただいた者ですm(_ _)m
WebbrowserコントロールでHTMLを取得し、解析しています。
解析方法は「WebBrowserで表のデータ収集」に書いてある
方法でやっています(DHTMLでのやり方)
この方法ではWebBrowserコントロールを表示していないと
取得できないようなのです。
VisibleプロパティをFalseにしてみるとできないのです。
この場合Inetを使いたいのですがそうするとDHTMLを使用
できなくなる(Documentプロパティみたいのがない)み
たいなのでどうしようか困っています。
どうにかしてWebbrowserコントロールを使わずにDHTMLの
データを取得する方法はありませんか??
お願いします
IPersistFileインターフェイス、もしくはIPersistStreamInitインターフェイスのLoadメソッドを使えばOKです。
(前者はファイルからの読み込み、後者はストリームからの読み込みとなります)
例えば、以下のようにすれば、変数Docは C:\hoge.html を解析した結果となります。
Dim Doc As MSHTML.HTMLDocument
Dim File As IPersistFile
Set Doc = New HTMLDocument
Set File = Doc
File.Load "C:\hoge.html", STGM_READ
なお、IPersistFileやIPersistStreamInitは、MSHTML.TLBファイル中では定義されていないので、タイプライブラリを別途用意し、それを参照設定しておく必要があります。
すいません、タイプライブラリとはなんでしょうか??
全体的に私の勉強不足でわからないので説明していただけませんか??
すみません…
あ…良く見たら、開発環境が書かれていませんでしたね。
(先のコードは、VB6という前提で書いた物です)
> タイプライブラリとはなんでしょうか??
外部コンポーネントのインターフェイス……プロパティ、メソッドの戻り値やデータ型、あるいは定数などの各種情報を記述したバイナリファイルの事です。
とりあえずは、
『[参照設定]を行う時に使うファイル(DLL、TLB、OLB等)の事』
と考えて貰えれば良いでしょう。
……ただし、IPersistFileやIPersistStreamInit等を定義したタイプライブラリは、標準では存在していませんので、それは別途(自作するなどして)用意する必要があったりします。
(VB6には、[インターフェイス]を定義するための仕組みが無いので、タイプライブラリを経由する必要があるのです)
ありがとうございます。
>あ…良く見たら、開発環境が書かれていませんでしたね。
>(先のコードは、VB6という前提で書いた物です)
すみません、開発環境はVB6です。
過去ログで調べてIPersistFileについてはなんとなくわかりました。
タイプライブラリも魔界の仮面弁士さんが作ったものを使わせていただいています。
ファイルからは読み込むことができたのですがネットワークから直接取得したHTMLのデータを読み込むにはどうしたらよいのでしょうか??
IPersistStreamInitについて調べてみてください。
何とか調べてみてコードを書いてみたのですが
「オブジェクト変数またはWithブロック変数が設定されていません。」というエラーが「Tmp.Load Stm2」の部分ででてしまいます。
Dim InetDoc() As Byte
Dim Stm As Object
Dim Stm2 As IStream
Dim Doc As MSHTML.HTMLDocument
Dim Tmp As IPersistStream
Inet1.protocol = icHTTP
Inet1.url = "http://www.yahoo.co.jp"
InetDoc = Inet1.OpenURL
Set Stm = New ADODB.Stream
Stm.open
Stm.Type = adTypeBinary
Stm.write InetDoc
Stm.Close
Set Stm2 = Stm
Set Doc = New HTMLDocument
Set Doc = Tmp
Tmp.Load Stm2
Debug.Print Doc.getElementsByTagName("TABLE").length
間違っている箇所を教えていただけないでしょうか??
> 間違っている箇所を教えていただけないでしょうか??
≪致命的なエラー:その1≫
宣言しているデータ型が間違っています。
名前は似ていますが、「IPersistStream」と「IPersistStreamInit」は別物です。
≪致命的なエラー:その2≫
『〜変数が設定されていません』の理由ですが、変数TmpがNothing状態なのに、そのLoadメソッドを使っているからです。
この場合は、変数DocをTmpにSetすればOKです。
≪エラーにはならないが修正が必要な点≫
IPersistStreamInit.Load の前に、ADODB.StreamのPositionプロパティを0にしておいてください。
Write直後は、カーソル位置がストリームの最後にあるので、先頭に戻しておかないと、データが正しく渡されません。
≪バグではないが、無駄な点≫
ADODB.StreamはIStreamインターフェイスを有していますので、『Set Stm2 = Stm』のようにせずとも、直接、Loadメソッドの引数に渡せますよ。
できました^^ありがとうございます。
本当に助かりました^^
しかし、別の問題が発生してしまったのです…
コードは以下です。
Dim InetDoc() As Byte
Dim Stm As Object
Dim Stm2 As IStream
Dim Doc As MSHTML.HTMLDocument
Dim Tmp As IPersistStreamInit
Inet1.protocol = icHTTP
Inet1.url = "http://www.yahoo.co.jp"
InetDoc() = Inet1.OpenURL(, icByteArray)
Set Stm = New ADODB.Stream
Stm.open
Stm.Type = adTypeBinary
Stm.write InetDoc()
Stm.position = 0
Set Doc = New HTMLDocument
Set Tmp = Doc
Tmp.Load Stm
Stm.Close
Dim objTable As Object
Set objTable = Doc.getElementsByTagName("TABLE")
Debug.Print objTable.length
これで実行するとobjtable.lengthは0と表示されるのです。
しかし、Set objTable = Doc.getElementsByTagName("TABLE")の場所にブレークポイントをおきF8で順次実行すれば正しく表示されます。
もしかして、Set〜が実行される前にDebug.〜が実行されてるのでしょうか?
> Set〜が実行される前にDebug.〜が実行されてるのでしょうか?
違います。もし、Set実行前に動作しているのだたとしたら、
『オブジェクト変数またはWithブロック変数が設定されていません。』
のエラーになっているはずですよね?
> F8で順次実行すれば正しく表示されます。
MSHTMLパーサによってHTMLが解析されるには、若干の時間が必要なのです。
WebBrowserコントロールを使って処理する時にも、DocumentCompleteイベントが発生するまで、解析は完了しませんよね。それと一緒です。
Loadメソッドで読み込んだ直後は、WebBrowserでいえば、まだNavigateCompleteイベントが発生した段階に過ぎないというわけです。
'==========
Option Explicit
Private WithEvents Doc As MSHTML.HTMLDocument
Private Sub Doc_onreadystatechange()
Debug.Print Doc.readyState
End Sub
Private Sub Command1_Click()
Dim Stm As ADODB.Stream
Dim StmInit As IPersistStreamInit
Set Stm = New ADODB.Stream
Stm.Type = adTypeBinary
Stm.Open
Stm.Write Inet1.OpenURL("http://www.yahoo.co.jp/", icByteArray)
Stm.position = 0
Set Doc = New HTMLDocument
Set StmInit = Doc
StmInit.Load Stm
Stm.Close
Set Stm = Nothing
'この時点で処理しても、解析が終わっているという保証は無い。
Debug.Print Doc.getElementsByTagName("TABLE").length
End Sub
ありがとうございます^^
本当にたすかりました^^
ツイート | ![]() |