見出し画像

[SeleniumVBA]業務システムでよく利用する要素検索について


インストールが不要でありながら高機能なSeleniumVBAを利用して、Excelに入力したデータを業務システムに自動登録できるよう開発しています。

使っていくうちに、高頻度で使用する要素検索が分かってきましたので、備忘録も兼ねて以下にExcelVBAコードを記載しています。

1 セレクトボックスの選択

第1位は以下のコードでセレクトボックスの選択に利用しています。

Dim elmfound as WebElement
With driver
  .IsPresent(By.Xpath, "//select[@name='〇〇']/option[text()='××']",2000,,elmfound) = False Then Stop
  elmfound.Click
End With

業務においては、要素が見つかるまで待機処理を必ず行う必要がありますが、「driver.wait 1000」といったような固定秒数による待機は、やむを得ない場合を除き推奨されません。

ここでは、Ispresentの機能により、待機処理(最大2000ミリ秒=2秒)を行いながら、見つかったらelmfoundという要素を返し、見つからなかったとStopするという、複数の処理を一度に記述できることからIspresentをよく利用しています

またBy.Xpathを利用している理由は、Xpathであればselectタグのname属性の指定(〇〇)とoptionタグのテキストの値指定(××)が1行で実行できるところが良く、他の方法(By.name等)では難しかったことからです。

実際には、値を代入する箇所(〇〇や××)は変数を利用しています。〇〇を変数「str1」、××を変数「str2」とすると、以下のとおり&で繋げることになります。

その場合、ダブルコーテーションとシングルコーテーションの使い分けに注意して混乱しないようにしましょう。

Dim elmfound as WebElement
With driver
  If .IsPresent(By.Xpath, "//select[@name='" & str1 & "']/option[text()='" & str2 & "']",2000,,elmfound) = False Then Stop
End With

要素が見つからなかったらStopで止めている理由は、エラーの起きた場所で止まるようにするためです。

【補足】セレクトボックスで選択されている値の取得

まず該当するselect要素を取得してから、GetSelectedOption(要素).GetTextをすることにより、選択状態の値が取得できます。

Dim elmfound as WebElement
Dim str as String
With driver  
'セレクトボックスで選択されている値を取得
    If .IsPresent(By.Xpath, "//select[@name='〇〇']", 2000, , elmfound) = False Then Stop
    str = .GetSelectedOption(elmfound).GetText
End With

2 テキストボックスの文字入力

第2位は以下のコードでテキストボックスの文字入力で使用しています。

Dim elmfound as WebElement
With driver
  If .IsPresent(By.Xpath, "//input[@name='〇〇']", 2000,,elmfound) = False Then Stop
  .ExecuteScript "arguments[0].value='××';", elmfound

  ’××を変数strとする場合、&で繋げる
  .ExecuteScript "arguments[0].value='" & str & "';", elmfound

  '直接、JavascriptのquerySelectorを使ってみる(待機処理なし)
  '//引用符の中に引用符があるので、ダブルコーテーションで代用した
  .ExecuteScript "document.querySelector(""input[name='〇〇']"").value=""××"";"
End With

テキストの文字入力は、ExecuteScriptによりJavaScriptを実行することにより、値(××)を代入しています。

arguments[0]はコンマのうしろに記載しているelmfoundを指しますので、そのvalueの値を××に更新することを示しています。

ExecuteScriptの後に書くJavaScriptのコードは「"」で囲む必要があり、引用符がある場合は「'」で囲みます。

JavascriptのquerySelectorを使いたい場合は、引用符の中に引用符が出てくる可能性がありますが、「""」で囲んだ中に「'」で囲むとエラーになりませんでした。

あえてJavaScriptを使っている理由は、Sendkeysを使うより確実かつ高速に処理ができることが、これまでの経験上明らかだったからです。

3 値の取得処理

第3位は、値の取得処理です。
具体的には「GetAttribute」「GetText」「GetProprety」が該当します。

Dim elmfound as WebElement
Dim str as Stirng
With driver

  'GetAttribute(指定された属性の値を取得する)
  ’//inputタグのうちvalue属性の値を取得
  If .IsPresent(By.Xpath "//input[@name='〇〇']", 2000, , elmfound) = False Then Stop
  str = elmfound.GetAttribute("value")

  'GetText(テキストの値を取得する)
  '//selectタグのうち選択されているoptionのテキストの値を取得
   If .IsPresent(By.Xpath, "//select[@name='〇〇']”, 2000, , elmfound) = False Then Stop
   str = .GetSelectedOption(elmfound).GetText

  'GetProperty(JavaScriptによる書き換え後の値を取得する)
  '//Chromeでは「F12」「Propreties」で確認可能。今回はそのPropertiesのうちvalueの値を取得
  If .IsPresent(By.Xpath, "//input[@name='〇〇']", 2000, , elmfound) = False Then Stop
  str = elmfound.GetProperty("value")

End With

このうち最後の「GetProprety」は、業務システム側で行われたJavaScriptによる書き換え後の値がhtmlに表示されないため、苦しんだうえでの解決策でした。

書き換え後の値は、Chromeを御利用であれば「F12」を押したあとに現れる右側の画面(以下の画像)で確認できます。

ChromeデベロッパーツールのProperties画面

4 チェックボックス/ラジオボタンの選択

選択の際は、IsSelectedにより、選択の有無の確認をしてから行うことになります。

Dim elmfound as WebElement
With driver
 
 'チェックボックス/ラジオボタンを検索
  If .IsPresent(By.Xpath, "//label/input[@name='〇〇']", , , elmfound) = False Then Stop
 
 'もし選択されていなければクリック(選択を解除する場合は「IsSelected = True」)
  If elmfound.IsSelected = False Then elmfound.Click
End With

5 ファイルのアップロード

ファイルをアップロードしたい場合に、ファイル選択ダイアログが表示されるボタンがある場合に使用します。UploadFileは指定したファイルを選択する機能です。

Dim elmfound as WebElement
With driver
   'アップロードするファイルを選択
    If .IsPresent(By.Xpath, "//input[@name='ファイル選択ボタン']", 2000, , elmfound) = False Then Stop
    elmfound.UploadFile "フルパスを指定"
  
  '通常このあと確定ボタンが存在する
    If .IsPresent(By.Xpath, "//input[@name='確定ボタン']", 2000, ,elmfound) = False Then Stop
    elmfound.Click
End With

6 既存要素を基点としてIsPresentで検索

IsPresentでXpathを利用すると、すでに検索した既存の要素を基点として、要素を検索することができ、業務でもよく利用しています。

例えば、私が愛用しているIsPresentを例に挙げますが、以下のとおり2通りの書き方があります。

Dim elmfound1 as WebElement
Dim elmfound2 as WEbElement
With driver

  ’【準備】
  ’Selectタグを調べた。見つかったらelmfound1が返ってくる
  .IsPresent(By.Xpath, "//select[@name='〇〇']",2000,,elmfound1) = False Then Stop

  '上記で見つけた要素(elmfound1)を基点にOptonタグのテキストを調べてelmfound2を取得してクリックする
  ’【記載例1】
  If .IsPresent(By.Xpath, "./option[text()='××']",2000,elmfound1,elmfound2) = False Then Stop
  ’【記載例2】
  If elmfound1.IsPresent(By.Xpath, "./option[text()='××']",2000,elmfound2) = False Then Stop
  'クリックする
  elmfound2.Click

End With

「記載例1」と「記載例2」は、どちらも同じ結果になります。違いは、基点(elmfound1)をどこに書くかです。私は「記載例1」の書き方をよく利用しています。

また両方の記載例にもありますが、Xpathの記述で基点を指定する場合は、「.」から始まるように書かないと、思うように動作しない可能性がありますので御注意ください。

番外 メッセージボックスの表示方法

通常、ブラウザの後ろに隠れてしまうため、MsgBoxの前に下記コードを記述しています。

AppActivate Application.caption
MsgBox "〇〇〇〇"

終わりに

要素が見つからずに困っているという方がいらっしゃいましたら、下記記事を御参考にしていただければ幸いです。

もう一つ紹介すると、By.Xpathは細かい検索条件を設定できるため、要素の特定が難しい案件もこれで困難を乗り切ったことが多々あります。

下記記事には、Xpathを使ったテーブルの特定方法や値の取り出しなど、具体的事例がありますので、こちらも是非御覧ください。


この記事が気に入ったらサポートをしてみませんか?