【VBA】SeleniumBasicのchromedriverを自動更新する

本ページはプロモーションが含まれています

PythonのSeleniumはchromedriverをchromeに合わせて自動更新する方法が確立していますが、VBA用のSeleniumBasicにはそんな機能備わっていないので独自に作ってみました

手間が減るのはもちろん、プログラムを誰かに渡した時にchromedriverの入替を案内する必要がなくなるのでSeleniumBasic界隈では歓喜してもらえるはず!

当然私も使っているプログラムなので必要に応じて改修もしますので何かあればコメントください

※このページのプログラムはchromeのバージョン115以上が前提です

更新情報

2025/08/03

  • プログラム微調整しました
  • フォルダへの書き込み権限がない時の対応を追記しました

このプログラムにはVBA-JSONが必要です

後述しますがchromedriverの情報を収集する際に情報がJSONが必要になるためVBA-JSONとセットで利用いただく必要があります

VBA-JSONについては別でまとめていますのでご存じない方は↓↓を参照

加えてSeleniumBasicとVBA-JSONの組み合わせだと特有のエラーが発生するので↓↓を参考に調整必要なのでご注意を

やっていること

結構プログラムが長くなってしまったのでざっくりやってることを順番にまとめました

  1. chromedriverの保存先は端末環境によって違うので候補となる3箇所のフォルダ有無を確認
  2. chromeの保存先も端末環境によって違うので候補となる3箇所のフォルダ有無を確認
  3. chromedriverのバージョンは同一フォルダのconfig.iniに残すようにしているので最後にダウンロードした時のバージョンを取得する
  4. PowerShellでchromeのバージョンを取得する
    ※なので一瞬PowerShellの画面がチラつきます
  5. chromedriverとchromeのバージョンが一致していればここで終了
  6. chromedriverとchromeのバージョンが不一致だったらchromeのバージョン情報をもとに公式の?JSON endpointsから対象になるchromedriverのダウンロードURLを取得する
  7. ダウンロードしたファイルを解凍してchromedriverを入れ替える
  8. config.iniに残しているchromedriverのバージョンを上書きする

ざっくりとした動きはこんな感じ

ちなみに、本当はchromedriverのバージョン情報を調べる方法はchromedriver.exeを実行してログを正規表現なんかで解析した方が確実だと思うのですが、実行エラーになったり、最後にクローズできなかったりと環境依存なのかエラーが発生することが多いので諦めました・・・

ファイルへの反映手順

サンプルファイルとソースは下部に準備していますがファイルへの反映方法がわからない方向けに反映と使い方です

そんなことわかってるからはよソースを!って方は下部のソースまで飛んじゃってください

プロパティウィンドウを表示しておく

あとからモジュール名を変更したいので、もし表示されていない時は表示しておく

ヘッダーメニュー:表示 → プロパティウィンドウ ※F4がショートカットキー

標準モジュールを追加

自動更新プログラム用にモジュールを追加する

ヘッダーメニュー:挿入 → 標準モジュール

モジュール名を変更する

必須ではないんですが、わかりやすい運用のためにはモジュール名変更推奨です

今回は”ChromeDriverAutoUpdateModule“にします

プログラムの使い方

<モジュール名>.<プロシージャ名>() ※”<モジュール名>.”は省略可」でプログラムを呼び出せるので、本体プログラムの最初に「ChromeDriverAutoUpdateModule.ChromeDriverAutoUpdate()」を追加すれば必要なときにchromedriverが自動更新されます

Sub main()
'---Chromedriverの自動更新 ※別モジュールを参照
If ChromeDriverAutoUpdateModule.ChromeDriverAutoUpdate Then
    Exit Sub
End If

'--・--・--以下にプログラムを--・--・--
End Sub

今後の課題

とりあえず問題なく動くことを確認していますが、もう少し作りこんだ方がいい気もするので気が向いた時に今わかっている課題を確認しようと備忘として残しておきます

2023/8/15の更新で対応しました

  • 今までなかったwin64は使うべき??※今のところwin32で問題なく動いてる
  • chromedriverファイルをダウンロードするURLは決め打ちしてるけど本当はJSON API endpoints(known-good-versions-with-downloads.json)から条件に合わせてURL検索した方が良さそう
  • 相変わらずリビジョン番号だけの相違だけならchromedriverは動くようなので更新条件を緩和してもいい?

2025/7/22の更新でconfig.iniの保存場所を変えました(ユーザー権限次第で”C:\Program Files”配下のフォルダにファイルを作成できない場合があるため)

Chromedriverの書き込み権限がない時

管理者権限でSeleniumBasicをインストールした場合、Chromedriverを更新しようとすると書き込み権限なしエラーが発生するので対応まとめました

画像の通りですが下記手順で権限設定ができます

  1. “C:\Program Files”にある”SeleniumBasic”フォルダを右クリック
  2. 右クリックメニューで”プロパティ”をクリック
  3. セキュリティタブに移って”編集”ボタンをクリック
  4. “Users({コンピュータ名}\Users)”をクリック
  5. “フルコントロール”にチェックがついていないはずなのでクリックしてチェックを付ける
  6. “適用”ボタンをクリック

サンプルファイル

JSON-VBA含めて最低限のモジュールをセットしたファイル準備したので一から作る時のベースにしていただければ

最後に実際のソース

かなり長いですがコピペ用

Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
                         (ByVal lpApplicationName As String, _
                          ByVal lpKeyName As Any, _
                          ByVal lpDefault As String, _
                          ByVal lpReturnedString As String, _
                          ByVal nSize As Long, _
                          ByVal lpFileName As String) As Long
                           
Private Declare PtrSafe Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
                         (ByVal lpApplicationName As String, _
                          ByVal lpKeyName As Any, _
                          ByVal lpString As Any, _
                          ByVal lpFileName As String) As Long
                           
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                        (ByVal pCaller As Long, _
                         ByVal szURL As String, _
                         ByVal szFileName As String, _
                         ByVal dwReserved As Long, _
                         ByVal lpfnCB As Long) As Long
Private Declare PtrSafe Function SHCreateDirectoryEx Lib "shell32.dll" Alias "SHCreateDirectoryExA" _
                        (ByVal hwnd As LongPtr, ByVal pszPath As String, ByVal psa As LongPtr) As Long
#Else
Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
                         (ByVal lpApplicationName As String, _
                          ByVal lpKeyName As Any, _
                          ByVal lpDefault As String, _
                          ByVal lpReturnedString As String, _
                          ByVal nSize As Long, _
                          ByVal lpFileName As String) As Long
                           
Private Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" _
                         (ByVal lpApplicationName As String, _
                          ByVal lpKeyName As Any, _
                          ByVal lpString As Any, _
                          ByVal lpFileName As String) As Long
                           
Private Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                        (ByVal pCaller As Long, _
                         ByVal szURL As String, _
                         ByVal szFileName As String, _
                         ByVal dwReserved As Long, _
                         ByVal lpfnCB As Long) As Long
Private Declare Function SHCreateDirectoryEx Lib "shell32.dll" Alias "SHCreateDirectoryExA" _
                        (ByVal hwnd As LongPtr, ByVal pszPath As String, ByVal psa As LongPtr) As Long
#End If
 
Private Type VersionClass '---本当はクラスオブジェクトにしたいけどこれだけのためにモジュール作りたくない
    Major As Long
    Minor As Long
    Build As Long
    Revision As Long
    FullVersion As String
    ShortVersion As String
End Type

Private Const CONFIG_FILE As String = "config.ini" '---chromedriverの情報を残すiniファイル
Private Const SECTION_NAME As String = "chromedriver" '---セクション名
Private Const CHROME_VERSION_KEY As String = "chrome_version"
Private Const CHROMEDRIVER_VERSION_KEY As String = "chromedriver_version"

Private Const DOWNLOAD_DIR_NAME As String = "drivercheck" '---chromedriverのzipファイルを保存するフォルダ名
Private Const DOWNLOAD_FILE_NAME As String = "chromedriver.zip" '---chromedriverのzipをダウンロードする時のファイル名
Public Function ChromeDriverAutoUpdate(Optional ByVal ForcedExecution As Boolean = False) As Boolean
'====================================================================================================
'chrome.exeとchromedriver.exeのバージョンを比較してchromedriverを自動更新する
'もしくは強制実行フラグ(ForcedExecution)がTrueでも実行する
'====================================================================================================
    Dim chromePath As String '---chrome.exeが保存されているパス
    Dim ChromeFullpath As String '---chrome.exeまで含めたフルパス
    Dim ChromedriverPath As String '---chromedriver.exeが保存されているパス
    Dim WorkPath As String '---chromedriver.exe更新作業用のパス
    Dim ChromedriverVersion As VersionClass
    Dim ChromeVersion As VersionClass
    Dim objFso As Object
    Dim result As Long
    
    '---chrome本体のフォルダを探す
    Set objFso = CreateObject("Scripting.FileSystemObject")
    Select Case True
        Case objFso.FolderExists(Environ("ProgramW6432") & "\Google\Chrome\Application")
            chromePath = Environ("ProgramW6432") & "\Google\Chrome\Application"
        Case objFso.FolderExists(Environ("ProgramFiles") & "\Google\Chrome\Application")
            chromePath = Environ("ProgramFiles") & "\Google\Chrome\Application"
        Case objFso.FolderExists(Environ("LOCALAPPDATA") & "\Google\Chrome\Application")
            chromePath = Environ("LOCALAPPDATA") & "\Google\Chrome\Application"
        Case Else
            MsgBox "'chrome'フォルダが見つかりません", vbCritical
            ChromeDriverAutoUpdate = False
            Exit Function
    End Select
    '---念のためchrome.exeを確認する
    If objFso.FileExists(chromePath & "\chrome.exe") = True Then
        ChromeFullpath = chromePath & "\chrome.exe"
    Else
        MsgBox "'chrome.exe'が見つかりません", vbCritical
        Exit Function
    End If
    Set objFso = Nothing
    
    '---SeleniumBasicのフォルダを探す
    Set objFso = CreateObject("Scripting.FileSystemObject")
    Select Case True
        Case objFso.FolderExists(Environ("ProgramW6432") & "\SeleniumBasic")
            ChromedriverPath = Environ("ProgramW6432") & "\SeleniumBasic"
        Case objFso.FolderExists(Environ("ProgramFiles") & "\SeleniumBasic")
            ChromedriverPath = Environ("ProgramFiles") & "\SeleniumBasic"
        Case objFso.FolderExists(Environ("LOCALAPPDATA") & "\SeleniumBasic")
            ChromedriverPath = Environ("LOCALAPPDATA") & "\SeleniumBasic"
        Case Else
            MsgBox "'SeleniumBasic'のフォルダが見つかりません", vbCritical
            ChromeDriverAutoUpdate = False
            Exit Function
    End Select
    '---念のためchromedriver.exeを確認する
    If objFso.FileExists(ChromedriverPath & "\chromedriver.exe") = True Then
        
    Else
        MsgBox "'chromedriver.exe'が見つかりません", vbCritical
        Exit Function
    End If
    Set objFso = Nothing
    
    '--- 作業用フォルダの宣言 ※Pythonで作られるフォルダに相乗りする
    WorkPath = Environ("USERPROFILE") & "\.cache\selenium\seleniumbasic"
    result = SHCreateDirectoryEx(0&, WorkPath, 0&)
    
    '---chrome.exeのバージョンを取得する
    If GetChromeVersion(ChromeFullpath, ChromeVersion.Major, ChromeVersion.Minor, ChromeVersion.Build, ChromeVersion.Revision, ChromeVersion.FullVersion, ChromeVersion.ShortVersion) = False Then '---chrome.exeのバージョンを取得する
        MsgBox "'chrome.exe'のバージョンが取得できませんでした", vbCritical
        ChromeDriverAutoUpdate = False
        Exit Function
    End If
    
    '---chromedriver.exeのバージョンを取得する
    If GetChromeDriverVersion(WorkPath, ChromedriverVersion.Major, ChromedriverVersion.Minor, ChromedriverVersion.Build, ChromedriverVersion.Revision, ChromedriverVersion.FullVersion, ChromedriverVersion.ShortVersion) = False Then '---chromedriverのバージョンを取得する
        MsgBox "'chromedriver.exe'のバージョンが取得できませんでした", vbCritical
        ChromeDriverAutoUpdate = False
        Exit Function
    End If
    
    '---chrome.exeとchromedriver.exeのバージョンが不一致か強制実行フラグがTrueだったらexeとchromedriver.exeを更新する
    If (ChromeVersion.FullVersion <> ChromedriverVersion.FullVersion) Or ForcedExecution Then
        '---chromeのバージョン情報でchromedriverを更新する ※本当はTargetPlatformをwin32とwin64のどちらにするか判定したい
        If UpdateChromeDriver(WorkPath, ChromedriverPath, ChromeVersion, ChromedriverVersion, ForcedExecution:=ForcedExecution, TargetPlatform:="win32") = True Then
            Call WritePrivateProfileString(SECTION_NAME, CHROME_VERSION_KEY, ChromeVersion.FullVersion, WorkPath & "\" & CONFIG_FILE) '---chromeのバージョン情報をiniに上書きする
            Call WritePrivateProfileString(SECTION_NAME, CHROMEDRIVER_VERSION_KEY, ChromedriverVersion.FullVersion, WorkPath & "\" & CONFIG_FILE) '---chromedriverのバージョン情報をiniに上書きする
        Else
            ChromeDriverAutoUpdate = False
            Exit Function
        End If
    End If
    '---結果として更新していない場合もあるが、更新失敗じゃなくて更新不要な判定だからTrueにしている
    ChromeDriverAutoUpdate = True
End Function
Private Function GetChromeVersion(ByVal ChromeFullpath As String, ByRef Major As Long, ByRef Minor As Long, ByRef Build As Long, ByRef Revision As Long, ByRef FullVersion As String, ByRef ShortVersion As String) As Boolean
'====================================================================================================
'PowerShellでchrome.exeのバージョン情報を取得する ※一瞬PowerShellが立ち上がる
'====================================================================================================
    Dim strCmd As String
    Dim objRet As Object
    
    On Error GoTo ErrLabel
        '---chromeバージョン情報の初期値
        Major = 1
        Minor = 0
        Build = 0
        Revision = 0
        '---chrome.exeのバージョンを取得するPowerShellコマンド
        strCmd = "(Get-Item -Path '" & ChromeFullpath & "').VersionInfo.FileVersion"
        '---PowerShellの実行結果をセット
        Set objRet = CreateObject("WScript.Shell").EXEC("powershell -NoProfile -ExecutionPolicy Unrestricted " & strCmd)
        '---PowerShellのコマンドレットの実行結果を取得
        FullVersion = Trim(objRet.StdOut.ReadAll)
        '---情報の取得が終わったらオブジェクトをクリアする
        Set objRet = Nothing
        '---改行コードが含まれているから削除する
        FullVersion = Trim(Replace(Replace(Replace(FullVersion, vbCrLf, vbNullString), vbCr, vbNullString), vbLf, vbNullString))
        '---バージョン情報を分けて返す
        With CreateObject("VBScript.RegExp") '---正規表現の準備
            .Pattern = "\d+\.\d+\.\d+(\.\d+)?"
            .Global = True
            If .test(FullVersion) Then '---念のため正規表現でバージョン情報をチェックする
                Major = CLng(Split(FullVersion, ".")(0))
                Minor = CLng(Split(FullVersion, ".")(1))
                Build = CLng(Split(FullVersion, ".")(2))
                If UBound(Split(FullVersion, ".")) >= 3 Then Revision = CLng(Split(FullVersion, ".")(3)) '---リビジョン番号があれば※基本あるはず
                FullVersion = Join(Array(Major, Minor, Build, Revision), ".") '---念のためバージョン情報を再セットする
                ShortVersion = Join(Array(Major, Minor, Build), ".") '---リビジョンを覗いたショートバージョン情報をセットする
            Else '---正規表現不一致なら失敗で返す
                GetChromeVersion = False
                Exit Function
            End If
        End With
        GetChromeVersion = True
    On Error GoTo 0
    Exit Function
ErrLabel:     '---予期せぬエラーの分岐
    MsgBox "chrome.exe のバージョン情報取得に失敗しました" & vbCrLf & "[" & Error(Err) & "]" & vbCrLf & "※この画面のキャプチャを作成者へ送ってください"
    GetChromeVersion = False
End Function
Private Function GetChromeDriverVersion(ByVal WorkPath As String, ByRef Major As Long, ByRef Minor As Long, ByRef Build As Long, ByRef Revision As Long, ByRef FullVersion As String, ByRef ShortVersion As String) As Boolean
'====================================================================================================
'chromedriver.exeと同じフォルダにconfig.iniを保存してバージョンを管理して取得している
'====================================================================================================
    Dim intFF As Long
    Dim objFso As Object
    
    On Error GoTo ErrLabel
        Set objFso = CreateObject("Scripting.FileSystemObject")
        If objFso.FileExists(WorkPath & "\" & CONFIG_FILE) Then
            FullVersion = ReadIni(WorkPath & "\" & CONFIG_FILE, SECTION_NAME, CHROMEDRIVER_VERSION_KEY, Default)
            If FullVersion = "0" Then
                '---ファイルはあるけどキーがない時の分岐
                Major = 1
                Minor = 0
                Build = 0
                Revision = 0
            Else
                '---iniに情報がある時
                Major = CLng(Split(FullVersion, ".")(0))
                Minor = CLng(Split(FullVersion, ".")(1))
                Build = CLng(Split(FullVersion, ".")(2))
                Revision = CLng(Split(FullVersion, ".")(3))
            End If
            FullVersion = Join(Array(Major, Minor, Build, Revision), ".") '---リビジョンを覗いたショートバージョン情報をセットする
            ShortVersion = Join(Array(Major, Minor, Build), ".") '---リビジョンを覗いたショートバージョン情報をセットする
        Else '---config.iniが無いなら作る
            intFF = FreeFile
            Open WorkPath & "\" & CONFIG_FILE For Output As #intFF
                Major = 1
                Minor = 0
                Build = 0
                Revision = 0
                FullVersion = Join(Array(Major, Minor, Build, Revision), ".") '---リビジョンを覗いたショートバージョン情報をセットする
                ShortVersion = Join(Array(Major, Minor, Build), ".") '---リビジョンを覗いたショートバージョン情報をセットする
                Print #intFF, "[" & SECTION_NAME & "]"
                Print #intFF, CHROME_VERSION_KEY & "=1.0.0.0"
                Print #intFF, CHROMEDRIVER_VERSION_KEY & "=1.0.0.0"
            Close
        End If
         
        If objFso.FolderExists(WorkPath & "\" & DOWNLOAD_DIR_NAME) = True Then '---zip保存用フォルダが残っていたら一度削除する
            objFso.DeleteFolder WorkPath & "\" & DOWNLOAD_DIR_NAME, True
        End If
        objFso.CreateFolder WorkPath & "\" & DOWNLOAD_DIR_NAME
        Set objFso = Nothing
        GetChromeDriverVersion = True
    On Error GoTo 0
    Exit Function
ErrLabel:     '---予期せぬエラーの分岐
    MsgBox "chromedriver.exe のバージョン情報取得に失敗しました" & vbCrLf & "[" & Error(Err) & "]" & vbCrLf & "※この画面のキャプチャを作成者へ送ってください"
    GetChromeDriverVersion = False
End Function
Private Function UpdateChromeDriver(ByVal WorkPath As String, _
                                    ByVal ChromedriverPath As String, _
                                    ByRef ChromeVersion As VersionClass, _
                                    ByRef ChromedriverVersion As VersionClass, _
                                    Optional ByVal ForcedExecution As Boolean = False, _
                                    Optional ByVal TargetPlatform As String = "win32") As Boolean
'====================================================================================================
'ビルドまでの情報が不一致だったらchromedriverをダウンロードする
'全リビジョンのバージョンが準備されるわけではないので準備されている中で一番近いバージョンを探している
'※TargetPlatformは固定にしているがwin64でもいいかもしれない
'====================================================================================================
    Dim objFso As Object
    Dim rc As Long
    Dim strUrl As String
    Dim objHttp As Object
    Dim compatible_versions As Object
    Dim compatible_version_key As Variant
    Dim objRet As Object
    Dim objVersion As Object
    Dim objDownloads As Object
    Dim tmpRevision As Long
    Dim targetRevision As Long
    Dim newDriverPath As String
    Const JSON_ENDPOINTS_URL As String = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"
    
    On Error GoTo ErrLabel
        Set objHttp = CreateObject("MSXML2.XMLHTTP")
        With objHttp
            .Open "GET", JSON_ENDPOINTS_URL, False
            .Send
            Set objRet = JsonConverter.ParseJson(.responseText) '---JSON endpoints から情報を収集する
            Set compatible_versions = CreateObject("Scripting.Dictionary") '---対象候補を一時的に取得する
            For Each objVersion In objRet("versions")
                If objVersion("version") Like ChromeVersion.ShortVersion & "*" Then '---リビジョンを除いたバージョン情報が一致して入れば候補にする
                    For Each objDownloads In objVersion("downloads")("chromedriver") '---取得対象をchromedriverに限定して
                        If objDownloads("platform") = TargetPlatform Then '---対象のplatformかチェックしてcompatible_versionsに追加する
                            compatible_versions.Add objVersion("version"), objDownloads("url")
                        End If
                    Next
                End If
            Next
            Set objRet = Nothing
            
            targetRevision = 0 '---取得対象にするバージョンのリビジョンの初期値
            For Each compatible_version_key In compatible_versions.Keys
                tmpRevision = CLng(Replace(compatible_version_key, ChromeVersion.ShortVersion & ".", vbNullString)) '---バージョン情報からリビジョンだけ取得する
                If tmpRevision <= ChromeVersion.Revision Then '---取得対象(Chrome.exe)のリビジョン以下で候補の中の最大値を確認する
                    If targetRevision < tmpRevision Then
                        targetRevision = tmpRevision
                    End If
                End If
            Next
        End With
        Set objHttp = Nothing
        
        
        If (ChromeVersion.ShortVersion <> ChromedriverVersion.ShortVersion) Or _
            (targetRevision <> ChromedriverVersion.Revision) Or _
            ForcedExecution Then  '---ビルドまでの情報不一致orリビジョン情報不一致or強制実行フラグがTrueだったらダウンロードする
            strUrl = compatible_versions(ChromeVersion.ShortVersion & "." & CStr(targetRevision)) '---取得対象バージョン情報からchromedriverのURLを取得する
            rc = URLDownloadToFile(0, strUrl, WorkPath & "\" & DOWNLOAD_DIR_NAME & "\" & DOWNLOAD_FILE_NAME, 0, 0) '---ファイルをダウンロードするWinAPI
            If rc = 0 Then
                Application.DisplayAlerts = False
                With CreateObject("Shell.Application") '---zipを既定のフォルダに向けて解凍する
                    .Namespace((WorkPath & "\" & DOWNLOAD_DIR_NAME)).CopyHere .Namespace((WorkPath & "\" & DOWNLOAD_DIR_NAME & "\" & DOWNLOAD_FILE_NAME)).Items
                End With
                '--- 解凍したフォルダからchromedriver.exeのフルパスを取得する
                newDriverPath = SearchFilesRecursively(WorkPath & "\" & DOWNLOAD_DIR_NAME, "chromedriver.exe")
                If newDriverPath = "" Then
                    MsgBox "chromedriver.exe の更新に失敗しました"
                    UpdateChromeDriver = False
                End If
                
                '--- chromedriver.exeを上書きして作業用フォルダを削除する
                With CreateObject("Scripting.FileSystemObject")
                    If .FileExists(ChromedriverPath & "\chromedriver.exe") Then '--- chromedriver.exeを一旦削除する
                        .DeleteFile ChromedriverPath & "\chromedriver.exe", True
                    End If
                    .MoveFile newDriverPath, ChromedriverPath & "\chromedriver.exe"
                    .DeleteFolder WorkPath & "\" & DOWNLOAD_DIR_NAME, True
                End With
                Application.DisplayAlerts = True
                UpdateChromeDriver = True
            Else
                UpdateChromeDriver = False
            End If
            
            '---ini上書き用に最終的なダッシュボードから取得できたchromedriverのバージョンで上書きする
            ChromedriverVersion = ChromeVersion
            With ChromedriverVersion
                .Revision = targetRevision
                .FullVersion = Join(Array(.Major, .Minor, .Build, .Revision), ".") '---リビジョンを覗いたショートバージョン情報をセットする
                .ShortVersion = Join(Array(.Major, .Minor, .Build), ".") '---リビジョンを覗いたショートバージョン情報をセットする
            End With
        End If
    On Error GoTo 0
    UpdateChromeDriver = True
    Exit Function
ErrLabel:     '---予期せぬエラーの分岐
    MsgBox "chromedriver.exe の更新に失敗しました" & vbCrLf & "[" & Error(Err) & "]" & vbCrLf & "※この画面のキャプチャを作成者へ送ってください"
    UpdateChromeDriver = False
End Function
Private Function ReadIni(ByVal FName As String, ByVal SName As String, ByVal KName As String, ByVal Default As String) As String
'====================================================================================================
'WinAPIでiniファイルから情報を取得する
'====================================================================================================
    Dim retStr As String
    Dim retCD As Long
    
    retStr = Space$(256)
    retCD = GetPrivateProfileString(SName, KName, Default, retStr, 255, FName)
    ' 戻り値設定
    If retCD > 0 Then
        If InStr(retStr, Chr$(0)) > 0 Then
            ReadIni = Left$(retStr, InStr(retStr, Chr$(0)) - 1)
        Else
            ReadIni = ""
        End If
    Else
        ReadIni = Default
    End If
End Function
Function SearchFilesRecursively(ByVal folderPath As String, fileName) As String
    Dim fso As Object
    Dim folder As Object
    Dim subFolder As Object
    Dim file As Object
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set folder = fso.GetFolder(folderPath)
    
    ' ファイル一覧表示
    For Each file In folder.Files
        If file.Name = fileName Then
            SearchFilesRecursively = file.Path
            Exit Function
        End If
    Next file
    
    ' サブフォルダを再帰的に探索
    For Each subFolder In folder.SubFolders
        If SearchFilesRecursively(subFolder.Path, fileName) = subFolder.Path & "\" & fileName Then
            SearchFilesRecursively = subFolder.Path & "\" & fileName
            Exit Function
        End If
    Next subFolder
    SearchFilesRecursively = ""
End Function

あとがき

SeleniumはスクレイピングだけじゃなくてRPA的にも使えて本当に便利なんですが、SeleniumBasicはPythonとかのSeleniumに比べて機能が少ないので独自に追加してあげると使い勝手が爆上がりです

自作でにPythonにある機能を移植するだけでもかなり変わってくると思うのでちょっとずつでもモジュールを作っていきたいです

コメント

  1. 山田 廣一 より:

    コンパイルエラーが表示されます。私の環境だけかな?

    「End Sub, End FunctionまたはEnd Property以降には、コメントのみが記述できます。」

    エラー部分として、以下がハイライトされています。
    Private Declare PtrSafe Function GetPrivateProfileString Lib “kernel32” Alias “GetPrivateProfileStringA” _
    (ByVal lpApplicationName As String, _
    ByVal lpKeyName As Any, _
    ByVal lpDefault As String, _
    ByVal lpReturnedString As String, _
    ByVal nSize As Long, _
    ByVal lpFileName As String) As Long

    • ジャベ雄 より:

      ご高覧いただきありがとうございます。
      記事の情報が中途半端になっていたので本日更新かけます!
      明日以降にまた訪問してもらえればわかるようにしておきますm(_ _)m

      • 山田 廣一 より:

        今日、再トライしましたが、エラー表示変わりません。

        折角、作られた凄いプログラムを利用できないのは、涙目です。

        • ジャベ雄 より:

          色々微調整したついでにサンプルファイルをページに付けました!
          これでダメならお手上げです(^^;

          • 山田 廣一 より:

            サンプルファイルで動作確認できました。

            動作も軽く極めて実用的だと思います。

            ありがとうございます。

            今後も素晴らしいブログを活用させていただきます。

  2. 山田 廣一 より:

    サンプルファイルを導入した日は完全動作しましたが、翌日やってみるとダメでした。

    自作分の半自動更新プログラムも含め、いろいろ試行錯誤し、やっていると、Microsoft Smart Screenなるセキュリティ設定等も動作の邪魔していそうで、セキュリティ設定を一部解除するなどやってみましたが、どうも上手くいかない。

    一方、自作分の「WEBアドレス指定でのダウンロードプログラム」と「Zip解凍およびchromedriver上書きプログラム」をそれぞれボタンを設定し、2回クリックで動作させた場合は動作するものの、上の2プログラムを合体して重複する設定を対応したプログラムはファイル上書き部分でエラーが出るなど、も~良く分からない部分があって困ったもんです。

    • ジャベ雄 より:

      なんでしょうね?
      もちろん私自身も使ってるプログラムで特に問題ないので環境差異なのか、、、
      ちゃんと調べれば何かわかるかもですがコメントでは厳しそうですね^^;

      • あめ より:

        とても参考になりましたし、たすかります。
        私の環境では正常に動作するようです。
        ありがとうございます。

        特に問題ないのですが、一点気になったので、指摘させていただきます。
        FullVersion = ReadIni(ChromedriverPath & “\” & CONFIG_FILE, SECTION_NAME, CHROMEDRIVER_VERSION_KEY, Default)

        ↑の箇所の最後の引数(Default)が存在しないと思います。
        サンプルファイルではコンパイルエラーとなりませんが、
        恐らく開発者の意図した参照ではないのだろうと思いました。
        いかがでしょうか。

        • ジャベ雄 より:

          おぉ!確かに・・・
          今回の流れではReadIni関数のDefaultをOptionalにしつつこの一文からはDefaultを削除するのが正しそうです
          元々Constで宣言してたんですが移植したときの調整漏れなので更新の機会があれば修正しておきます
          (まぁエラーにはならないのでそっとしておいてください・・)

  3. あめ より:

    ご確認ありがとうございます。
    (そっと感謝だけさせてください・・)

タイトルとURLをコピーしました