前回の記事
に引き続き、VBAのDOM操作を利用した特殊なVBAプログラミング処理に関する解説です。
今回は「KeyboardEvent」というものを使用し、keyupイベントを強制的に発生させる処理を組んでみます。
ちなみにこの処理を使用する事で、”メルカリ”の商品登録画面の「商品名」や「商品説明」といった入力ボックスに値をセットできる様になります。
APIを使わずに自動化ツールを作ろうとした場合は欠かせない技術ですね。
メルカリに値をセットしてみる部分は最後にちょっと触れる予定です。
それではまずイベントを発生させる手順について確認していきます。
- 目次 -
処理の組み方
私は以下の様な形で処理を組みました。
Dim evt As Object Dim obj As Object 'evtにKeyboardEventをセット Set evt = ie.document.createEvent("KeyboardEvent") 'KeyboardEventの初期化処理 evt.initKeyboardEvent "keyup", True, False, Null, 1, False, False, False, 1, 1 '~~~~~~~~~省 略~~~~~~~~~~ '1.objにテキストボックスオブジェクトを格納 '2.テキストボックスに値セットする処理 '~~~~~~~~~~~~~~~~~~~~~~ 'イベントを発生させる obj.dispatchEvent evt
前回changeイベントを発生させた時の処理と良く似ていますね。
初期化時の引数の数が多いので、そこだけ注意です。
ちなみにこれ・・・動く事は確認したのですが、後半の引数あってるのか分かりません。
このイベント自体元々JavaScriptにある物の様で、このへん(KeyboardEvent.initKeyboardEvent())とかを参考に色々組んでみたのですが・・・うーん・・・
↑の解説曰く、引数の順番は以下の通り。
・typeArg
・canBubbleArg
・cancelableArg
・viewArg
・charArg
・keyArg
・locationArg
・modifiersListArg
・repeatArg
しかし実際値を入れてみるも、ウォッチウィンドウで中身を見ると何か違う・・・
※↓ウォッチウィンドウ
typeArg~viewArgまでは合ってるんですけどね、charArg以降が微妙に違う様な・・・これはVBAだからかなーと思いつつ色々試してみた結果、上の様な処理の記述にしました。
引数に「Null」を指定している所がviewArg。
その一つ後の「1」を渡している所が「key」の指定っぽいです。
Falseとか書いてる所はもしかしたらIntとかLongの値を渡すべき所かもしれません。
この辺の引数について詳しい人が居たら指摘して頂けると嬉しいです。
まぁ今回の処理で一番重要なのは「typeArg」に指定している「”keyup”」です。
keyupを指定したイベントを「obj.dispatchEvent evt」で実行させる事により、対象のオブジェクトにkeyupを行なわれたと認識させる訳ですね。
JavaScript経験がある方なら思い付くと思いますが、
もちろん「keydown」、「keypress」と指定する事も可能です。
イベントの発生を確認してみる
実際にイベントが発生している事を確認してみます。
今回は以下のサイトにてテストを行いました。
CMAN > WEBページ作成TOP > javascriptサンプル > キーコード一覧
こちらのページにある「キーコードを取得するサンプル」を対象にして、以下の処理を組んで実行させてみました。
Dim ie As InternetExplorer Dim obj As Object Dim evt As Object Dim evt2 As Object Dim evt3 As Object '現在開いているIEの中で、タイトルに「キーコード」をが含まれるサイトを取得 '※getRunningIEは独自関数なので、別途作成する必要があります Set ie = getRunningIE("キーコード") '「キー入力」のテキストボックスオブジェクトをobjに格納 Set obj = ie.document.getElementById("inkey") Set evt = ie.document.createEvent("KeyboardEvent") Set evt2 = ie.document.createEvent("KeyboardEvent") Set evt3 = ie.document.createEvent("KeyboardEvent") evt.initKeyboardEvent "keydown", True, True, Null, 1, False, False, False, 1, 1 evt2.initKeyboardEvent "keypress", True, True, Null, 2, False, False, False, 1, 1 evt3.initKeyboardEvent "keyup", True, False, Null, 3, False, False, False, 1, 1 obj.dispatchEvent evt obj.dispatchEvent evt2 obj.dispatchEvent evt3
実行結果がこちら。
プログラムで指定した通り、バラバラのキーコードを検知していますね。
どういう事か簡単に解説すると、
こちらのページにある「キー入力」というテキストボックス内でキーボード入力を行うと、下の「キーコード取得結果」の表に、実行されたイベント別に押されたキーの内容が表示される仕組みとなっています。
キーを押し込むと「keydown」と「keypress」が反応し、キーを離すと「keyup」の表示が更新されるはずです。
今回プログラム上で「evt」、「evt2」、「evt3」というオブジェクトそれぞれにkeydown、keypress、keyupのイベントを設定し、キーとして渡す値も分かりやすく別々のものをセットして実行しました。
結果は見ての通り、nameに表示された値を見ることで、それぞれの処理によって適切にイベントが実行された事が分かると思います。
という事でこの処理で問題無い事が分かりましたね。
次は実際にメルカリでこの処理を使用してみます。
メルカリのテキストボックスに値を入れてみる
この処理を使う事で、本当にメルカリの出品操作を自動化できるのか確認していきます。
手入力してみる
まずは普通通りキーボードを手入力で確認してみます。
※入力が正常に認識されているかどうかは、テキストボックス入力後に出品画像登録の四角部分をクリックして、「ファイル選択のダイアログを表示」⇒「キャンセル」を行う事で確認できます。
結果は・・・
商品名に入力した内容が残っています。
当たり前ですね。
DOMを使ってValueに直接値をセットする
続いて以下の商品名inputタグのvalueにただ値をセットするだけの処理を組みます。
Dim ie As InternetExplorer Dim obj As Object '現在開いているIEの中で、タイトルに「メルカリ」をが含まれるサイトを取得 Set ie = getRunningIE("メルカリ") '「商品名」のinputタグオブジェクトをobjに格納 'このページの中の一つ目のinputタグが商品名のものになるので、(0)で指定 Set obj = ie.document.getElementsByTagName("input")(0) obj.value = "テスト"
上記の処理を実行してみると、見た目上は手入力した時と同じく商品名に「テスト」という文字が入力されますが・・・
画像登録用のダイアログを出した後に閉じると、
入力した内容は消えてしまいます。
続いて最初に画像とかを全て設定した後に上の処理で商品名をセットして、そのまま出品ボタンを押してみます。
しかしその場合は、
この様にそもそも入力自体が認識されていない状態となってしまいます。
この理由は単純で、以下の様にinputタグへの入力時に特定のイベントが発生する様になっているためです。
つまりvalueに値を設定するだけでは足りず、このイベントを発生させないと入力値を認識してくれない事になります。
このイベントを発生させる方法が、冒頭から説明していたKeyboardEventを使った方法です。
inputタグのValueに値をセットして、KeyboardEventでイベントを発生させてみる
先程のvalueセット処理と冒頭のKeyboardEvent処理を組み合わせて、以下の様に記述します。
Dim ie As InternetExplorer Dim obj As Object Dim evt As Object '現在開いているIEの中で、タイトルに「キーコード」をが含まれるサイトを取得 Set ie = getRunningIE("メルカリ") 'keyupイベントを作成 Set evt = ie.document.createEvent("KeyboardEvent") evt.initKeyboardEvent "keyup", True, False, Null, 1, False, False, False, 1, 1 '「キー入力」のテキストボックスオブジェクトをobjに格納 Set obj = ie.document.getElementsByTagName("input")(0) obj.Value = "テスト" 'イベント実行 obj.dispatchEvent evt
以上の様にvalue入力後にkeyupイベントを強制的に実行させる事で、サイト側が入力を認識してくれる様になります。
ちなみにkeydownやkeypressは設定されていない様でした。
元々作っていた自動化ツールではこの部分をSendKeysで代用していたため、他の作業ができなかったり常に操作対象のWindowをアクティブ状態にしていないといけないといった面倒事があったのですが・・・それも解決出来そうですね!
しかしまだ『カテゴリ選択部分の処理』という強敵が残っています。
ただ今回の件で何となく解決の糸口が見えてきましたので、SendKeysに頼らない理想型のツールまで後一歩という所です。
色々試していたら既存の知識で既に解決できていた事が判明しました。
よって、私の想定している理想型のツールは完成出来そうです。(理論上)
今回はここまでとなります。
使えるサイトは色々あると思いますので、ぜひ参考にしてみて下さい。