VBAからRを実行する

Windowsを扱っている会社であれば、業務プロセスにExcelマクロが組み込まれているケースは割と多いのではないでしょうか。私の会社でもVBAの認知度が比較的高く、他のプログラミング言語に比べ抵抗感が少ない人が多い事などもあり自身もVBAを扱ったりします。

ただ場合によってはどうしても中間プロセスでRやPythonに処理を任せたい場合などがあります。そのような時、シームレスにVBAからRを実行させる方法について記録します。
(以下は自身のPCでは問題なく作動したことを確認しましたが、実際に試される場合は自己責任でお願いします)

まずは「R.exe」ファイルの場所を取得するためのファンクションを定義します。

' ----------------------------------------------------------------
'  FileSearch: ファイルを検索するファンクション
' ----------------------------------------------------------------
' 引数:
' Path:ファイルが保存されていると考えられる親フォルダ
' Target_Path:目的の取得したいパス
' ----------------------------------------------------------------
Function FileSearch(Path As String, Target As String, ByRef Target_Path As String)
    Dim FSO As Object, Folder As Variant, File As Variant
    ' FileSystemObject を使ったファイル操作
    Set FSO = CreateObject("Scripting.FileSystemObject")
    ' サブフォルダ毎にファイル検索をかける
    For Each Folder In FSO.GetFolder(Path).subfolders
        Call FileSearch(Folder.Path, Target, Target_Path)
    Next Folder
    For Each File In FSO.GetFolder(Path).Files
        ' ターゲットファイルが見つかったら終了
        If File.Name = Target Then
            Target_Path = File.Path
            Exit Function
        End If
    Next File
End Function

上記で定義した関数を使って実際にRを実行します。

' ----------------------------------------------------------------
'  Exe_R: Rを実行するプログラム
' ----------------------------------------------------------------
Sub Exe_R()
    Dim shell As Object, Target_Path As String
    Dim R_ExePath As String, ExeCommand As String
    Dim waitTillComplete As Boolean: waitTillComplete = True
    Dim style As Integer: style = 1
    Set shell = VBA.CreateObject("WScript.Shell")
    
    ' R.exeファイルのパスを検索
    Call FileSearch("C:\Program Files\R", "R.exe", Target_Path)
    R_ExePath = "(実行したいRスクリプトのパス)\samle.R"

    ' 実行コマンドを作成
    ExeCommand = """" & Target_Path & """" & "CMD BATCH --vanilla --slave " & R_ExePath
    ' Rを実行する
    ErrorCode = shell.Run(ExeCommand, style, waitTillComplete)
End Sub

今回は以上になります。



損害等の責任について
当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますので、ご了承ください。