VBAプログラム開発、スクレイピング・ログイン機能【2-5-2】共通処理をクラスモジュール化する(ログイン処理)
前回記事にてクラスモジュールとして、IE読み込み待ち処理をクラス化しました。
当初これだけで、本番組み込みを考えていたのですが、事前にログイン処理についてもクラス化をしてから組み込むことにしました。
テスト用のモジュールを利用して、ログイン処理についてもクラスモジュールへの分割を行います。
今回の目的
同一処理プロシージャが複数モジュールに配置されているので、一つに統合する
なぜやるか
プログラム作成観点として、同一処理は集約して参照できるようにするため。
IE読み込み処理はクラス化したが、ログイン処理のクラス化についても事前に動作確認してから実装するため
やりたいこと
- クラス化したモジュールから、次のクラス化方法を検討する
- クラスを追加する
- 変数宣言を変更する
- クラスから別のクラスへ値を渡せるようにする
やったこと
- ログイン処理用クラスを作成する
- 変数宣言をクラスで行う
- メインプロシージャで変数処理を変更する
- ログイン処理クラスからIE読み込み処理クラスへの値引渡をする
- 動作確認をする
実施内容
ログイン処理のクラス化をする
ログイン処理については専用のプロシージャとして標準モジュール内で分割することは以前実施しました。
今回は、この分割できているログインプロシージャをそのままクラスモジュールに載せ替えます。
そして、クラスモジュール化したログインプロシージャが動作してくれれば完了です。
クラスモジュールとして作成しなおす
まずは、クラスモジュールとして作成します。
クラスモジュールにBookdataLoginという名前で追加しました。
そして、モジュールにログインプロシージャをそのままコピーします。
# クラスモジュール(ログイン処理)
Sub CheckLogin(waitObjIE As waitObjIE, htmlDoc As HTMLDocument, _
Domain As String, ProcessDir As String, CheckFirstLogin As Boolean)
Dim LoginDir As String
LoginDir = "login"
Dim LoginPageURL As String
LoginPageURL = Domain & LoginDir
Dim LoginEmail As String
Dim LoginPassword As String
LoginEmail = ThisWorkbook.Worksheets("ログイン設定").Cells(2, 1).Value 'Email
LoginPassword = ThisWorkbook.Worksheets("ログイン設定").Cells(2, 2).Value 'Password
Dim LoginAnswer As String
Dim ExitMsg As String
Dim ProcessPageURL As String
Dim ResponseURL As String
If CheckFirstLogin = True Then
ProcessPageURL = LoginPageURL
Else
ProcessPageURL = Domain & ProcessDir
End If
waitObjIE.objIE.navigate ProcessPageURL
waitObjIE.WaitResponse
ResponseURL = waitObjIE.objIE.document.URL
If ResponseURL = LoginPageURL Then
Set htmlDoc = waitObjIE.objIE.document
htmlDoc.getElementsByName("email")(0).Value = LoginEmail
htmlDoc.getElementsByName("password")(0).Value = LoginPassword
htmlDoc.getElementsByClassName("form-group__submit")(0).Click
waitObjIE.WaitResponse
ResponseURL = waitObjIE.objIE.document.URL
If ResponseURL = LoginPageURL Then
LoginAnswer = "ログイン失敗"
waitObjIE.objIE.Quit
ExitMsg = "ログインに失敗しました。"
MsgBox ExitMsg
End
Else
LoginAnswer = "ログイン成功"
End If
Else
LoginAnswer = "ログイン済み"
End If
Set htmlDoc = waitObjIE.objIE.document
If CheckFirstLogin = True Then CheckFirstLogin = False
End Sub
※再掲となるので、コメントは除外しています。
ログイン処理内にもIE読み込み待ち処理は利用しているので、前回のIE読み込み処理をクラスモジュール化した時に関連する変数について変更しています。
クラスモジュールからさらにクラスモジュールへアクセスする…という処理も必要となります。
ログインプロシージャの引数を再設定する
ログイン処理にはいくつか引数を設定していました。
# クラスモジュール(ログイン処理)
Sub CheckLogin(waitObjIE As waitObjIE, htmlDoc As HTMLDocument, _
Domain As String, ProcessDir As String, CheckFirstLogin As Boolean)
クラスモジュール化により、データの渡し方を変更する必要がありそうです。
IE読み込み待ち処理ではどうしていたかというと…。
# クラスモジュール(IE処理)
Public objIE As InternetExplorer
Sub WaitResponse() 'Webブラウザ表示完了待ち
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE '読み込み待ち
DoEvents
Loop
End Sub
クラスモジュール側でobjIEを宣言していました。
さらに、これを扱うためにした設定はというと…、
# メインモジュール(テスト用プロシージャ)
Sub getURLtest()
'クラスモジュール化テスト
Dim waitObjIE As waitObjIE
Set waitObjIE = New waitObjIE
Set waitObjIE.objIE = CreateObject("Internetexplorer.Application")
メインモジュール側でクラスモジュールが扱える様に宣言しておき、クラスモジュールで宣言している変数に対してデータを格納していました。
これで動作していたので、今回のログイン処理も同じ方法を使うことにしました。
ログイン処理クラスモジュールで変数宣言する
まずは、クラスモジュール側で変数宣言します。
# クラスモジュール(ログイン処理)
Public htmlDoc As HTMLDocument
Public Domain As String
Public ProcessDir As String
Public CheckFirstLogin As Boolean
Public waitObjIE As waitObjIE
Sub CheckLogin()
~ ログイン処理 ~
End Sub
今までプロシージャの引数としていた変数をすべて宣言しました。
これでこのクラスモジュール内で値を取り出して扱える状態となります。
次に、このクラスで宣言した変数に対して値を設定する必要が出てくるので、メインモジュールでの設定を変更します。
# メインモジュール(テスト用プロシージャ)
Sub getURLtest()
'クラスモジュール化テスト(IE読み込みチェック
Dim waitObjIE As waitObjIE 'IE読み込み待ちモジュール作成
Set waitObjIE = New waitObjIE
Set waitObjIE.objIE = CreateObject("Internetexplorer.Application")
waitObjIE.objIE.Visible = False
'クラスモジュール化テスト(ログイン
Dim Login As BookdataLogin 'ログインクラスモジュール作成
Set Login = New BookdataLogin
Login.Domain = "https://protected-fortress-61913.herokuapp.com/" 'ドメイン格納
Login.ProcessDir = "book" 'ディレクトリ指定
Login.CheckFirstLogin = True 'ログインチェックフラグ
Set Login.waitObjIE = waitObjIE 'IEオブジェクトをLoginに引渡
'IEオブジェクト
Dim objIE As InternetExplorer 'IEオブジェクトを準備
Set objIE = CreateObject("Internetexplorer.Application") '新しいIEオブジェクトを作成してセット
objIE.Visible = False 'IEを表示
'HTMLオブジェクト
Dim htmlDoc As HTMLDocument 'HTML全体
'URL設定
Dim Domain As String 'Webドメイン名
Domain = "https://protected-fortress-61913.herokuapp.com/" 'ドメイン格納
Dim ProcessDir As String '処理実施ディレクトリ
ProcessDir = "book" 'ディレクトリ指定
'VBA動作初回ログインチェック
Dim CheckFirstLogin As Boolean 'ログインチェックフラグ
CheckFirstLogin = True
クラスモジュールで変数宣言したので、メインプロシージャ内では、対応するクラスとして処理する変数を作成し、その中の変数として値を設定しなおしました。
基本的に実施していることはクラスモジュール.変数名=値の形式に入れ替えているという所です。
後はwaitObjIEを使う都合上、ログイン処理に引き渡す変数に同じ物を格納しています。
この変更を行うことで、クラスモジュール側の変数に必要な値が準備できました。
ログイン処理をよびだす
ログイン処理をクラスモジュール化したので、メインプロシージャからの呼び出し処理を変更します。
# メインモジュール(テスト用プロシージャ)
'ログイン状態チェック
Call CheckLogin(waitObjIE, htmlDoc, Domain, ProcessDir, CheckFirstLogin)
Login.CheckLogin
ログイン処理を実施するクラスモジュールとして宣言したLogin変数に対してCheckLoginプロシージャを実施できるように変更します。
変更処理は完了です、最後に今まで通りの動作であることを確認すれば完了です。
クラスモジュールを利用した動作が確認できれば、メインモジュール内のログインプロシージャは不要となります。
不要となったプロシージャを削除して、念のため再度動作確認すれば、今回の目的は達成です。
IE読み込み待ちとログイン処理についてクラスモジュール化が完了したので、次に既存VBAをさらに編集してクラスモジュール対応を行っていきます。