はじめに
テキストボックスに文字入力する方法は標準のSendKeysのほか、JavaScriptによる文字入力を行う方法もある。それぞれの方法にメリット/デメリットはないのか、実際に検証することとした。
検証方法
検証用サイトとして、PHP & JavaScript Roomの「onKeyDownの使用例」をお借りして、以下の画像の入力フォームを利用した。
上の入力欄に文字入力してEnterキーを押すと、イベントが発火して下の欄に入力した文字を表示するようになっている。
検証コード
標準モジュールに記述した下記コードにより【事例1】から【事例4】の方法を用いて、「あ」を1000回連続させた文字をテキストボックスに入力した。下記コードをコピーして、新規の標準モジュールに貼り付けると動作確認が可能。
もし、SeleniumVBAがまったく初めての方は、こちらの記事を参考に新規の標準モジュール作成まで行う。
事例 | 方法 | 説明 |
---|---|---|
1 | JavaScript | JavaScriptでの文字代入 |
2 | JavaScript (dispatchEvent付) |
JavaScriptでの文字代入に加え、dispatchEventによるイベント強制発火 |
3 | SendKeys(クリップボード経由) | SendKeysでのクリップボード経由による文字代入 |
4 | SendKeys | SendKeysでの直接文字代入 |
Option Explicit
Sub A_Sendkeys()
Dim driver As SeleniumVBA.WebDriver
Set driver = SeleniumVBA.New_WebDriver
With driver
.StartChrome
.OpenBrowser
.ImplicitMaxWait = 2000
.NavigateTo "https://phpjavascriptroom.com/?t=js&p=event#a_onkeyup"
Dim elmfound As WebElement
Dim startTime As Double
Dim endTime As Double
'入力文字を変数に格納
Dim str As String
str = String(1000, "あ") '「あ」を1000回繰り返す
'テキストボックス
If .IsPresent(By.XPath, "//input[@onkeydown='fCopy(this.form)']", 2000, , elmfound) = False Then Stop
'【事例1】JavaScriptの場合
startTime = Timer
.ExecuteScript "arguments[0].value= arguments[1];", elmfound, str
endTime = Timer
Debug.Print "事例1の処理時間は" & endTime - startTime & "秒"
'【事例2】JavaScriptの場合(dispatchEvent)
startTime = Timer
Dim strScript As String
strScript = "arguments[0].value= arguments[1];"
strScript = strScript & "arguments[0].dispatchEvent(new Event('keydown'));"
.ExecuteScript strScript, elmfound, str
endTime = Timer
Debug.Print "事例2の処理時間は" & endTime - startTime & "秒"
'【事例3】SendKeys クリップボード経由の場合(最も安全なテキストボックス使用)
startTime = Timer
Dim keys As SeleniumVBA.WebKeyboard: Set keys = SeleniumVBA.New_WebKeyboard
Dim objForm As Object: Set objForm = CreateObject("Forms.TextBox.1")
objForm.MultiLine = True: objForm.text = str
objForm.SelStart = 0: objForm.SelLength = objForm.textLength
objForm.Copy: Set objForm = Nothing 'クリップボードにコピー
elmfound.SendKeys keys.CtrlKey & "v", True '「Ctrl+V」で貼り付け
endTime = Timer
Debug.Print "事例3の処理時間は" & endTime - startTime & "秒"
'【事例4】SendKeys 引数に直接文字を指定した場合
startTime = Timer
elmfound.SendKeys str, True
endTime = Timer
Debug.Print "事例4の処理時間は" & endTime - startTime & "秒"
.CloseBrowser
.Shutdown
End With
End Sub
処理時間計測結果はイミディエイトウインドウに表示される
検証結果
結果は以下のとおりとなった。
1 速度
・ 速い【事例1】【事例2】【事例3】
・ 遅い【事例4】
2 イベント発現の有無
・ 発現なし【事例1】
・ 発現あり【事例2】【事例3】【事例4】
3 コード量(メンテナンス性)
・ 最も少ない【事例4】
・ 少ない【事例1】
・ 多い【事例2】
・ かなり多い【事例3】
まとめ
まずは、手動動作の再現性が保証されるSendKeysの利用を考えるが、処理速度を優先したい場合はJavaScriptの選択もありうる。
順位 | 方法 | 説明 |
---|---|---|
2 | JavaScript | 処理速度を最優先し、その後の動作に支障がない場合に選択 |
3 | JavaScript (dispatchEvent付) |
イベント発火を必要とする場合で、dispatchEventが記述できる場合に選択可能であるが、複雑になる |
3 | SendKeys(クリップボード経由) | 処理速度は向上するが、複雑になるうえクリップボードの使用自体に不安感は残る |
1 | SendKeys | 手動動作の再現性が保証されるため、第1順位となる |
ちなみに、私の環境ではイベント発生を必要とせず、処理速度向上が必須であっため、JavaScript使用を選択しています。
おわりに
この記事における動作確認は2025年1月17日時点です。
最後に、最適な検証材料を公開していただいたPHP & JavaScript Room様、どうもありがとうございました。