見出し画像

[SeleniumVBA]メンテを考えたプログラムとデータの分離について一案


はじめに

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

ただし、作成したExcelVBAにバグがあったり、業務システム側でWEBページの構成要素に変更があったりする場合もあるので、常にプログラムの更新があることを念頭に入れなければなりません

当初の運用

当初は、SeleniumVBA.xlamを参照設定し、入力用Excelファイル側の標準モジュールに独自に実装したプログラム(例:ボタンを押した時の処理)を組み込んで運用していました。この運用であればSeleniumVBA.xlamの差替えは簡単です。

(備考)GitHubでは諸事情によりxlam形式のファイルは公開されなくなりましたが、xlsm形式をダウンロードして「名前を付けて保存」により簡単に変換できます。

しかし、独自実装のプログラムを更新したい場合、入力用Excelファイルがコピペされ複数になったりすると、そのデータを維持しながらプログラムのみを更新することが面倒になってしまいました。

改善策

やはり、プログラムとデータは分離して別ファイルにするべきとの考えに傾き、プログラム部分はSeleniumVBA.xlamに独自に実装するプログラムを標準モジュールに追加「下記(1)参照」することで、SeleniumVBA.xlamで担当するようにしました。

(1)SeleniumVBA.xlamの標準モジュールに記述

Public Sub 〇〇()
'*********************************************************'
'〇〇ボタンを押した時の処理
'*********************************************************'
  Dim driver As WebDriver:Set driver = New_WebDriver
  ’//ここはアドインファイルなので呼び出し元のシートを取得できる
  Dim Ws As Worksheet:Set Ws = ActiveSheet
  '以下に処理を書く
  '(処理)
End Sub

Private Sub GetUpdate()
'*********************************************************'
' 更新日をステータスバーに表示
'*********************************************************'
  Const VERUPDATE As Date = #11/02/2024#  ' バージョン更新日を記入
  Application.StatusBar = Format(VERUPDATE, "yyyy/MM/dd") & "更新"
End Sub

データ部分となる入力用Excelファイルには、起動時にSeleniumVBA.xlamを呼びだすプログラム「下記(2)参照」を追加しました。

(2)入力用Excelファイル「Thisworkbook」モジュールに記述

Private Sub Workbook_Open()
'*********************************************************'
'* 処理名 :Workbook_Open
'* 機能  :ワークブックOpen時イベント
'* 機能説明:アドインを開き、SeleniumVBA.xlamを起動する
'*********************************************************'
Dim objFso As Object: Set objFso = CreateObject("Scripting.FileSystemObject")
Dim objWBK As Workbook: Set objWBK = ThisWorkbook
Const FILEADDINNAME As String = "SeleniumVBA.xlam"
Dim fullAddinName As String: fullAddinName = objFso.BuildPath(objWBK.Path, FILEADDINNAME)

' アドインの存在確認(ワークブックと同じフォルダ)
FILEADDINNAME = "SeleniumVBAcustom.xlam"
fullAddinName = objFso.BuildPath(objWBK.Path, FILEADDINNAME)
If Not objFso.FileExists(fullAddinName) Then
    MsgBox "「" & FILEADDINNAME & "」が同じフォルダにありません", vbCritical
    GoTo Open_AddinEXIT
End If

On Error GoTo Open_AddinError
'更新日をステータスバーに表示
'//アドインにあるGetUpdateメソッドを実行。実行できないとOpen_AddinError
Application.Run FILEADDINNAME & "!GetUpdate"
GoTo Open_AddinEXIT

'//アドインが開かれていない時の処理
Open_AddinError:
    ' アドインを開く
    Application.Workbooks.Open Filename:=fullAddinName
    On Error GoTo 0
    '自ブックをアクティブに
    objWBK.Activate
    Resume

' 終了
Open_AddinEXIT:
    Set objFso = Nothing
End Sub

さらに、入力用Excelファイルシートに設置したボタンを押した時にSeleniumVBA.xlamの該当メソッドを呼びだすプログラム「下記(3)参照」を追加し、呼び出すだけの最小限のプログラムで運用することにしました。

(3)入力用Excelファイルの標準モジュールに記述

Public Sub Button_〇〇()
'*********************************************************'
'* 処理名 :Button_〇〇
'* 機能  :「〇〇」ボタンを押したときに発生する処理
'* 機能説明:SeleniumVBA.xlamの〇〇メソッドを実行
'*********************************************************'
  Const FILEADDINNAME As String = "SeleniumVBA.xlam"
  Application.Run FILEADDINNAME & "!〇〇"
End Sub

結局、SeleniumVBA.xlamはアドインとしての設定は何もしていないので、データを保管しないプログラムファイルとしての運用をしていることになります。

運用上のメリットとデメリット

(1)メリット

メリットは、参照設定が一切不要であることと、例えばNAS上で運用する場合においても、SeleniumVBA.xlamと入力用Excelファイルを同一フォルダに置く運用が可能で、更新作業が楽になります。

また、入力用Excelファイルの起動時に、ステータスバーにプログラムの更新日を表示させることが可能で、バージョン管理もできることがメリットに感じています。

(2)デメリット

デメリットは、SeleniumVBAのバージョンアップがあると、独自実装の標準モジュールをインポートする必要があること(そんなに手間ではありませんが)。

また入力用Excelシートにおいてボタンの追加があると、双方のファイルでコードの変更が必要となるので、入力用Excelシートの内容がある程度固まっていないと、かえって作業が大変になる点です。

終わりに

参考にしたURLは以下のとおりです。ありがとうございました。
https://www.asahi-net.or.jp/~ef2o-inue/haifu/sub06_010.html

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