リンクラフトのレトロゲーム愛好家こと @hayasakasakas です!
早いもので LINCRAFT Advent Calendar 2023 も、もう15日目です。
今回は、今更ですが VBA についての記事です。
私は未だに一日二日で自分以外の作業を自動化する必要がある時などによく使いますが、皆さんはいかがでしょうか?
はじめに
最近、RPA や AI など、機械に作業をやってもらうことが当たり前になってきました。
そこで、今回は非エンジニアにも親和性の高い Excel でシナリオを作成しWebページを操作するRPAを作ってみようと思いました。
需要は限定的ですが、きっと刺さる人はいるはず。。。
ゴール
テスターの方や営業の方などプログラムを書くことができない人でも、
ちょっとしたレクチャーだけで気軽にExcelだけでWeb操作RPAを作れるようにすることです。
完成イメージ
事前準備
このVBAマクロを実行するためには以下のアプリケーションが必要です。
- SeleniumBasic
- .NET Framework
- ChromeDriver
SeleniumBasic
ダウンロード
- ↓ のページから
SeleniumBasic-2.0.9.0.exe
をダウンロードする
https://github.com/florentbr/SeleniumBasic/releases
インストール
-
SeleniumBasic-2.0.9.0.exe
を実行する - コンポーネント選択画面では
WebDriver for Chrome
を選択すること
- 確認画面でインストール先を控えておく(後で使う)
- それ以外の部分はそのまま
next
を押してOK
.NET Framework
インストール
SeleniumBasicのインストールフォルダ内にあるStartChrome.vbs
を実行することで、.NET Framework
をインストールすることができます。
「[インストールフォルダ]\SeleniumBasic\Scripts\StartChrome.vbs」
ChromeDriver
ダウンロード
- ↓ のページからGoogle Chromeのバージョンに合わせた安定版(stable)をダウンロードする
https://googlechromelabs.github.io/chrome-for-testing/
インストール
ダウンロードしたZipファイルの中からchromedriver.exe
を取り出して
SeleniumBasicのインストールフォルダ 「[インストールフォルダ]\SeleniumBasic」に上書きコピーする。
※ 旧バージョンのドライバを残したい場合は、バックアップを取ってから実行してください
作ってみましょう!
Excel から Visual Basic を開く
-
Visual Basic
ボタンを押下する
- Visual Basic ウィンドウが開かれる
-
Microsoft Excel Objects
を右クリックし、`挿入 > 標準モジュールを選択する
- Module1モジュールが作成される
コード
以下のコードをモジュールのソースエディタに貼付します。
'Chromeドライバの読み込み
Dim driver As New Selenium.ChromeDriver
'RPAマクロのメインルーチン
Sub runRPA()
'シートを変数化
Dim sheet As Worksheet
Set sheet = Worksheets("Sheet1")
'ループ内で利用する変数
Dim rowIndex As Long
Dim actionNo As Integer
Dim value1 As String
Dim value2 As String
Dim value3 As String
'2行目から始める
rowIndex = 2
'A列が空になるまで1行ずつ処理する
While sheet.Cells(rowIndex, 1).value <> ""
'ワークシートの値を取り込む
actionNo = sheet.Cells(rowIndex, 1).value
value1 = sheet.Cells(rowIndex, 3).value
value2 = sheet.Cells(rowIndex, 4).value
value3 = sheet.Cells(rowIndex, 5).value
'操作番号ごとに動作を変える
Select Case actionNo
Case 1
'ブラウザを起動する
Call openBrowser
Case 2
'ブラウザを終了する
Call closeBrowser
Case 3
'ページを開く
Call openURL(value1)
Case 4
'ボタンを押す
Call clickButton(value1, value2)
Case 5
'入力する
Call inputText(value1, value2, value3)
Case 6
'スクリーンショットを取る
Call saveScreenShot(value1)
End Select
rowIndex = rowIndex + 1
Wend
End Sub
'ブラウザ(Selenium)起動
Private Sub openBrowser()
Call driver.Start
End Sub
'ブラウザ(Selenium)の終了
Private Sub closeBrowser()
Call driver.Quit
End Sub
'ブラウザで引数のURLを開く
Private Sub openURL(ByVal url)
Call driver.Get(url)
End Sub
'表示中のページのテキストボックスに文字を入力する
Private Sub inputText(ByVal targetType, ByVal key, ByVal value)
'指定方法(ID or NAME)に合わせて利用する関数を変え、入力処理を実施する
If targetType = "ID" Then
Call driver.FindElementById(key).SendKeys(value)
ElseIf targetType = "NAME" Then
Call driver.FindElementByName(key).SendKeys(value)
End If
'JavaScriptの動作を待つ
Call driver.Wait(50)
End Sub
'表示中のページのボタンを押下する
Private Sub clickButton(ByVal targetType, ByVal key)
'指定方法(ID or NAME)に合わせて利用する関数を変え、ボタン押下処理を実施する
If targetType = "ID" Then
Call driver.FindElementById(key).Click
ElseIf targetType = "NAME" Then
Call driver.FindElementByName(key).Click
End If
End Sub
'表示中ページのスクリーンショットを引数のパスに保存する
Private Sub saveScreenShot(ByVal path)
Dim width As Integer
Dim height As Integer
width = driver.ExecuteScript("return document.body.scrollWidth")
height = driver.ExecuteScript("return document.body.scrollHeight")
Call driver.Window.SetSize(width, height)
driver.takeScreenShot.SaveAs path
End Sub
コード解説
ChromeDriver のインスタンス化
Dim driver As New Selenium.ChromeDriver
Choromeドライバを読み込みます。
別のブラウザを使いたい場合は、それに合わせたドライバを読み込ませる必要があります。
ブラウザを起動する処理
driver.Start
この1行だけでブラウザが起動します。
ブラウザはどのページにもアクセスしていない、真っ白な状態になります。
ブラウザを終了する処理
driver.Quit
この1行だけで、ブラウザが終了します。
ページを開く処理
driver.Get "https://www.google.com"
GET関数に URL を指定することで対象URLのページに遷移します。
関数名の通りGETリクエストで送信されます。
ボタンを押す処理
driver.FindElementByID(key).Click
HTMLのID属性を指定して、ボタンをクリックします。
driver.FindElementByName(key).Click
HTMLのName属性を指定して、ボタンをクリックします。
フォーム入力する処理
Call driver.FindElementById(key).SendKeys(value)
HTMLのID属性を指定して、値を設定します。
Call driver.FindElementByName(key).SendKeys(value)
HTMLのName属性を指定して、値を設定します。
スクリーンショットを取る処理
width = driver.ExecuteScript("return document.body.scrollWidth")
height = driver.ExecuteScript("return document.body.scrollHeight")
Call driver.Window.SetSize(width, height)
driver.takeScreenShot.SaveAs path
ExecuteScript
関数でJavaScriptを実行しています。
JavaScriptの内容はそれぞれ、縦と横のHTMLの画面サイズを取得し、
Windows.setSize
関数でウィンドウサイズを変更します。
※ 希望のサイズがある場合は数値を指定してもOKです。
最後のtakeScreenShot.SaveAs
関数で対象のパスにスクリーンショットを保存しています。
ワークシートを作成する
マクロ実行用のシートを作成する
今回は画像のようなインターフェースにしました。
青いセルの部分を利用者に入力してもらう想定です。
図形にマクロを登録する
エクセルでは図形や画像などにマクロを登録することができます。
今回は前述のモジュールで実装した、runRPA
を登録します。
これでワークシート側の準備は完了です。
動かしてみる
RPAスタートボタンを押下すると、
自動でブラウザが立ち上がり、エクセルに記述した通りの動作が自動で行われ、
指定のファイルパスにスクリーンショットを保存することができました。
さいごに
今回は簡単なプログラムでしたが、それなりに手を入れれば、
以下のようなユースケースで効果を発揮するので、役に立つシチュエーションが想像しやすいと思います。
- テスト仕様書(Excel)の自動実行
- テストサイトのエビデンス作成の補助(主にスクリーンショットの自動化)
- API がないサービスの自動データ入力
- いろんなサイトのスクリーンショットを集めたい
プログラムが書ける人はSelenium自体が色々な言語で利用できるので、あえてVBAでやる必要性は薄いのですが、利用者が慣れたUIで操作できることを考慮すれば、選択肢の一つになるのではないでしょうか?
ExcelVBA なので他のExcelドキュメントと連携しやすいのもメリットですね。
それでは、機会があればまたお会いしましょう!
良いエンジニアライフを!!
一緒に働く仲間を募集中です!
リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。
▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit
※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。