こちらの掲示板で教えていただき、VB6 + IE でブラウザの内容を
SHDocVw.WebBrowserとMSHTML.HTMLDocumentを使って取得している
のですが、(その節は魔界の仮面弁士様ありがとうございました。)
次の段階として、ブラウザ上の日付選択メニューと決定ボタンを
操作したいのです。
SELECTとSUBMITを使うのでしょうが、具体的なオブジェクト宣言や
コードを教えていただければありがたいです、お願いいたします。
『決定ボタン』は、submitエレメントの事だと思いますが、
『日付選択メニュー』とは、何を指しているのでしょうか?
とりあえず、以前、某メーリングリストに回答したコードを挙げておきます。参考になれば。
http://www.users.gr.jp/ml/archive/viewer.aspx?name=vb&no=9517
http://www.users.gr.jp/ml/archive/viewer.aspx?name=vb&no=9519
魔界の仮面弁士様、早速のレス、ありがとうございます。
>『日付選択メニュー』とは、何を指しているのでしょうか?
表現が不正確ですみません。
コンボボックスタイプの選択メニューで、具体的には月日を選ぶように
なっているのです。
教えていただいたサンプルで
VBからは、MSHTML.TLB というファイルを参照設定しておいて、とある
のですが、Microsoft HTML Object Library でよいのでしょうか?
教えていただいたサンプルを私の状況に合わすと
Private ie As SHDocVw.WebBrowser
Private ieDoc As MSHTML.HTMLDocument
Private mobjSelect As Object
'中略
Private Sub selectB1_click()
Dim objDocument As Object
Dim objOption As Object
Combo1.Clear
Set objDocument = ieDOC.documentElement
Set mobjSelect = objDocument.getElementById("sc") '←
For Each objOption In mobjSelect.options
Debug.Print objOption.text, objOption.Value
Combo1.AddItem objOption.text
Next
Combo1.ListIndex = 0
Set objDocument = Nothing
End Sub
←の部分でオブジェクトはこのプロパティ、メソッドをサポートしてないと
言われます。その前の行が間違いでしょうか?(汗)
よろしくお願いします。
> Microsoft HTML Object Library でよいのでしょうか?
はい、それです。
(まぁ、参照設定はせずとも動かせますが、しておいた方が楽でしょう)
> Set objDocument = ieDOC.documentElement
> Set mobjSelect = objDocument.getElementById("sc") '←
ieDocが、WebBrowser1.Documentへの参照を保持しているのであれば、
「objDocument.getElementById(id名)」ではなく、
「ieDoc.getElementById(id名)」となります。
# ちなみに、『ieDOC.documentElement』が返すものは、
# (Dynamic HTMLでいうところの)documentオブジェクトではなく、
# その中のルート要素…すなわち、HTMLエレメントです。
魔界の仮面弁士様、お忙しいところ、ありがとうございます。
>ieDocが、WebBrowser1.Documentへの参照を保持しているのであれば、
>「objDocument.getElementById(id名)」ではなく、
>「ieDoc.getElementById(id名)」となります。
getElementById(id名)のid名というのがどうもわからないのですが(汗!!!)、
getElementByTagNameを使って取得はできました。
Private Sub selectB1_click()
Dim objDocument As Object
Dim objOption As Object
Combo1.Clear
Set objDocument = ieDOC.documentElement
Set mobjSelect = ieDoc.getElementsByTagName("OPTION")
For Each objOption In mobjSelect
Debug.Print objOption.text, objOption.Value
Combo1.AddItem objOption.text
Next
Combo1.ListIndex = 0
Set objDocument = Nothing
End Sub
次にsubmitなんですが、(おいおい次に進むのかよと言われそうですが)
ボタンが他にもいくつかあるので決定ボタンをスマートに指定するには
どうしたらいいのでしょうか。
ボタンは Type="SUBMIT" Name="" Value="決定"です。
よろしくお願いします。
> getElementById(id名)のid名というのがどうもわからないのですが(汗!!!)、
HTMLで <select id="hoge"> と書かれていた場合に、
.getElementById("hoge") のように記述する、という事です。
# 逆にいうと、id属性の無いエレメントの場合は、
# このメソッドでは取得できない事に注意してください。
> getElementByTagNameを使って取得はできました。
…getElementsByTagName の事ですよね?(^_^;)
id属性というのは、1つのHTML文書中で、同じ値が重複して現れてはいけないのです。
だから、get「Element」ByID なわけですね。
一方、要素名(TagName)は、同じ名前が使われることもありますので、
複数形で get「Elements」ByTagName というわけで。
で、提示されたコードですと、HTML中にSELECT要素が複数あった場合に、
どちらの項目(OPTION要素)なのかを判断できません。
この場合はまずSELECT要素を取得してから、そのSELECT要素が持つ
optionsコレクションを取得するようにした方が良いと思いますよ。
> 次にsubmitなんですが、
もし、submitボタンにid属性かname属性が付いているなら、
getElementById/getElementsByNameメソッドが使えるでしょう。
それらの属性が付加されていない場合は、INPUT要素をFor Each〜Nextで
列挙して、その中で、typeプロパティがsubmitになっているものを
探す事になると思います。
ただし、INPUT TYPE="submit"要素があるという事は、通常、
その祖先要素としてFORM要素があると思いますので、id/nameが無い場合は、
FORM要素を取得するだけでも十分かも知れません。もし、submitボタンを
押すことだけが目的なのであれば、FORM要素のsubmitメソッドを
呼び出すだけで済みますの。
(FORM要素は、documentのformsコレクション経由で取得出来ます)
ただし、submitボタンのonclickイベントに処理が割りあたっている時は、
submitボタンのclickメソッドを呼ぶ必要があるでしょうけれども。
> (おいおい次に進むのかよと言われそうですが)
もし、きちんと勉強する気があるなら、HTMLの基本的なタグと、
DHTMLについて簡単に学んでおくと、コーディングがスムーズに進みますよ。
魔界の仮面弁士様、たびたびありがとうございます。
>で、提示されたコードですと、HTML中にSELECT要素が複数あった場合に、
>どちらの項目(OPTION要素)なのかを判断できません。
>この場合はまずSELECT要素を取得してから、そのSELECT要素が持つ
>optionsコレクションを取得するようにした方が良いと思いますよ。
なるほど、気がつきませんでした、大変勉強になります。
>それらの属性が付加されていない場合は、INPUT要素をFor Each〜Nextで
>列挙して、その中で、typeプロパティがsubmitになっているものを
>探す事になると思います。
下のようなアプローチでいいでしょうか?
Dim mobjInput As Object
Dim objInput As Object
Set mobjInput = ieDoc.getElementsByTagName("INPUT")
For Each objInput In mobjInput
Debug.Print objInput.Type
If objInput.Value = "SUBMIT" And objInput.Value = "決定" Then
ieDoc.form.submit
End If
Next
しかし ieDoc.form.submit はエラーになってしまいます。
結局もformもオブジェクトとして取得しないといけないのでしょうか。
だとしたら魔界の仮面弁士様が下のように言われている部分
>押すことだけが目的なのであれば、FORM要素のsubmitメソッドを
>呼び出すだけで済みますの。
>(FORM要素は、documentのformsコレクション経由で取得出来ます)
これを採用した方が効率的かと思いますが、
colForms objform を列挙した後、FORM要素を取得する手順が
わかりません。.elements を指定してもエラーになって……。
何度も手間を取らせて恐縮ですがお願いします。
>もし、きちんと勉強する気があるなら、HTMLの基本的なタグと、
>DHTMLについて簡単に学んでおくと、コーディングがスムーズに進みますよ。
その通りです、オブジェクトブラウザで探しても、何をどういう手順で
使えばいいのかわからないんですよね、勉強します(汗!!)。
> 下のようなアプローチでいいでしょうか?
「INPUT TYPE=SUBMIT要素を探す」しておいて、
「FORM要素のsubmitメソッドを呼び出す」のは無駄かと。
ボタンを探したなら、そのclickメソッドを呼べば良いし、
ボタンを探さないなら、FORMのsubmitメソッドを呼べばOK。
> しかし ieDoc.form.submit はエラーになってしまいます。
先にも回答しましたように、FORM要素は『documentのformsで』取得します。
『documentのformで』取得するのではありません。(^^;
例えば、
Set objForms = Me.WebBrowser1.Document.forms
のように書けば、そのページに含まれるFORM要素のコレクションがとれますし、
Set objForm = objForms(0)
とするか、もしくはFor Eachを使うなどすれば、個々のFORMが得られます。
(formsコレクションの数は、objForms.length にて得られます)
ちなみに、今見ているこのページであれば、
Set F = Me.WebBrowser1.Document.forms(0)
F.NAME.value = "ぐぅぐる"
F.EMAIL.value = "japanese@google.com"
F.HPAGE.value = "http://www.google.co.jp/"
F.SOLVED.checked = False
F.MESSAGE.value = "これは" & vbCrLf & "本文です。"
F.submit
Set F = Nothing
などとすれば、メッセージの送信が行われます。
(他にも、いろいろな指定方法があります)
> その通りです、オブジェクトブラウザで探しても、何をどういう手順で
デバッグ時に、VB6の『ローカル ウィンドウ』も併用すると良いですよ。
> 使えばいいのかわからないんですよね、勉強します(汗!!)。
HTMLの操作は、(VBの知識ではなく)DHTMLの知識が必要とされますので、
基本的な部分だけでも、頑張って学習してください。
魔界の仮面弁士様、何度も丁寧なレス、ありがとうございます。
>『documentのformで』取得するのではありません。(^^;
あ、また魔界の仮面弁士様に《こいつ、トンチンカンやなー》マークを
出されてしまった(大汗!!!!)。
> Set objForm = objForms(0)
>とするか、もしくはFor Eachを使うなどすれば、個々のFORMが得られます。
>(formsコレクションの数は、objForms.length にて得られます)
そこまではなんとか自力で気づいたのですが、求める決定ボタンに
Name、IDがないので何番目のFORMに含まれるか調べるところで
足踏みしています。
ちょっとDHTMLも勉強してトライしてみます。
魔界の仮面弁士様、ありがとうございました。
> 求める決定ボタンにName、IDがないので
そうですね。input type="text" や input type="hidden" には、
大抵 name が付けられますが、ボタンに関しては、idもnameも付いていない事が
少なくありません。
> 何番目のFORMに含まれるか調べるところで
一つのHTML中に、複数のFORMエレメントがあるという事ですか?
ところで……今回の『決定ボタン』というのは、どのエレメントなのでしょうか?
もし、input type="submit"エレメントのボタンを押すのであれば、
》 F.submit
だけで済みますが(FはFORMエレメントを指しています)、input type="button"エレメントや
buttonエレメントなどを押すのであれば、それぞれのエレメントオブジェクトを取得してから、
clickする事になりますね。
もし、後者の「clickメソッド」による方法で取得するのであれば、
以下のように、幾つかの手法が考えられます。
Option Explicit
'フォームの送信ボタンを押すためのコード
Private Sub Command1_Click(Index As Integer)
Dim objDocument As Object 'As MSHTML.HTMLDocument
Dim objForm As Object 'As MSHTML.HTMLFormElement
Dim objElement As Object 'As MSHTML.IHTMLElement
Dim objElements As Object 'As MSHTML.IHTMLElementCollection
'最初のフォームを取得します。なお、フォームにnameかidがあるなら、
'それらも利用して取得した方が良いでしょう。
Set objDocument = Me.WebBrowser1.Document
Set objForm = objDocument.forms(0)
'フォームデータを送信します。
Select Case Index
'formオブジェクトのsubmitメソッドを呼び出す方法
'→送信ボタンが、そのFORM中に一つしか無い時に使えます。
Case 0
objForm.submit
'elements + インデックス番号でinput type="submit"を探し、
'そのclickメソッドを呼び出す方法
'→送信ボタンのインデックスが分かっている時に使えます。
Case 0
'elementsは、コントロールのみを含んだコレクションです。
'つまり、INPUT/TEXTAREA/SELECTなどが返されます。
objForm.elements(6).click
'all + インデックス番号 で input type="submit"を探し、
'そのclickメソッドを呼び出す方法
'→送信ボタンのインデックスが分かっている時に使えます。
Case 1
'allは、コントロール以外のエレメントも返します。
'つまり、NOBR/BR等も含まれます。
objForm.all(15).click
'elementsまたはallを列挙して、最初のinput type="submit"を探し、
'そのclickメソッドを呼び出す方法
'→送信ボタンのインデックスが分からない時に使えます。
Case 2
Set objElements = objForm.elements
For Each objElement In objElements
If objElement.tagName = "INPUT" Then
If LCase(objElement.Type) = "submit" Then
objElement.click
Exit For
End If
End If
Next
End Select
Set objForm = Nothing
Set objDocument = Nothing
End Sub
Private Sub Form_Load()
Dim Cmd As VB.CommandButton
For Each Cmd In Me.Command1
Cmd.Enabled = False
Next
Me.WebBrowser1.Navigate2 "http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200309/03090009.txt"
End Sub
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Dim Cmd As VB.CommandButton
For Each Cmd In Me.Command1
Cmd.Enabled = True
Next
End Sub
魔界の仮面弁士様、何度も何度もありがとうございます。
場合分けしてコードまで示していただいて、大変よくわかりました。
僕はsubmitがFORMの要素で、(誤解を受けるかもしれない言い方ですが)
個々のFORMに従属してIndexを持っていると勘違いしてました。
formsコレクションの要素なのですべてが一挙に列挙取得できるのですね。
>一つのHTML中に、複数のFORMエレメントがあるという事ですか?
そうなんです、3つのFORMがあるんです。
>ところで……今回の『決定ボタン』というのは、どのエレメントなのでしょうか?
SUBMITです。 ID や NAMEはなく VALUE="決定"です。
そして3つのFORMにひとつずつ<INPUT TYPE="SUBMIT" が含まれています。
今回の決定ボタンは3つ目のFORMだとわかっているので
objDocument.forms(2).submit
でもよいということですね。
ただひとつのFORMに複数のsubmitというケースがあるなら、最初のsubmitが
実行されてしまうのでしょうかね?
将来的にページ構造が作り手により変更されてしまう可能性も考えると
For Each で列挙検索した方がより実践的ということですか。
Set Input = ieDoc.getElementsByTagName("INPUT")
For Each objInput In mobjInput
If Lcase(objInput.Type) = "submit" and objInput.Value = "決定" Then
objInput.click
End If
Next
Lcase()というのも実践的な小技ですよね、感心しました。
idもnameもValueもない場合は、いただいたサンプルのCase 2の形を利用
すればよいのですね。
おかげさまで少しずつHTMLについてわかってきたように思います。
魔界の仮面弁士様、本当にありがとうございました。
> 場合分けしてコードまで示していただいて、大変よくわかりました。
ありゃ……良く見たら『Case 0』が2つありましたね。失礼しました。(^_^;)
> ただひとつのFORMに複数のsubmitというケースがあるなら、最初のsubmitが
> 実行されてしまうのでしょうかね?
いえ、違います。どちらのボタンも押されないのです。
例えば……以下のようなHTML FORMがあったとします。
<form method="post" action="http://〜〜〜">
<input type="hidden" name="A" value="myData">
<input type="text" name="B" value="foo">
<input type="submit" name="C" value="1">
<input type="submit" name="D" value="2">
</form>
この時、ユーザーがデータを送信する為には、
[1] テキストボックス上で Enter を押した時
[2] ボタン1を押下した時
[3] ボタン2を押下した時
のいずれかの動作を行うわけですが、form.submit()というのは、
このうちの[1]の動作に相当する行為になります。
ちなみに[1]やform.submit()の場合は、form.actionで指定したURLに対して
『A=myData&B=foo』というデータが送られるのですが、[2]の操作では
『A=myData&B=foo&C=1』というデータが送られますし、[3]の操作ならば
『A=myData&B=foo&D=2』というデータが送られる事になります。
魔界の仮面弁士様、重ねてありがとうございました。
この手の問題になると、参考書も触れてないので、あきらめてしまう人も
多いと思うのですが、魔界の仮面弁士様はすばらしい指導者です。
プログラムも問題なく動くように出来ました。
もう、大感謝です。
DHTMLも少しずつ勉強して、そのうちデータバインドも
手を出してみようかと考えています。
また何かありましたら、なんて図々しくて書けませんが、
(いや既に書いてますが)、教えていただければ幸いです。
本当にありがとうございました。
J_Message
J_Message
J_Message
J_Message
J_Message
スイマセン。。。誤射してしまいました汗
J_Message
J_Message
ツイート | ![]() |