Running R script in VBA Wrong Directory - r

I have a macro that edits an R script.
That R script is then supposed to be called by the following VBA:
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = """" & "C:\Program Files\R\R-3.3.2\bin\i386\R.exe" & """ """ & "R RAM Cluster Script.R" & """"
errorCode = shell.Run(path, style, waitTillComplete)
The above code was from this question.
When I execute the macro, however, the R Command Line gives me an error stating:
'\\dm\home\myaccount\*Path of my original Excel File*'
"CMD.EXE was started with the above path as the current directory.
UNC Paths are not supported. Defaulting to Windows directory.
Argument 'R RAM Cluster Script.R' Ignored"
The script is stored in the folder that my Excel workbook is in.
Can anyone help me out with finding my problem?

Try this:
Sub test()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = """C:\Program Files\R\R-3.3.1\bin\RScript.exe""" & """c:/temp/R RAM Cluster Script.R"""
errorCode = shell.Run(path, style, waitTillComplete)
End Sub

I would suggest trying to use powershell as a wrapper for your script because it DOES support UNC paths. So, something like this should work:
path = "Powershell.exe -executionpolicy bypass -Command &{'C:\Program Files\R\R-3.3.2\bin\i386\R.exe " & ThisWorkbook.Path & "\R RAM Cluster Script.R'}"

Related

Run R script from VBA

I have tried several examples found on forums to run my R script from VBA, but it doesn't work. The R script works well alone. Here is the code I ran:
Sub RunRscript()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = "RScript C:\Users\Documents\Code.R"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
I'm getting an error message saying that running object "IWshShell3" failed. Is there anything special to write on the R code prior to running this macro? Shall I load a package, or load the files in a specific folder?
Your script is not able to find the executable (RScript).
Provide the absolute path, then it should work well.
See here on where to find it: http://datacornering.com/how-to-run-r-scripts-from-the-windows-command-line-cmd/
Edit:
I saw right now, that you could stumble into further problems regarding missing environments.
See here: Setting .libPaths() For Running R Scripts From Command Line Using Rscript.exe
This is how I would do it.
Sub RunRscript1()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
' path to R executable: C:\your_path\Documents\R\R-3.2.5\bin\x64\R.exe
' path to R script: C:\your_path\Documents\R\Download.r
' see more setup details here
' http://shashiasrblog.blogspot.com/2013/10/vba-front-end-for-r.html
path = "C:\your_path\Documents\R\R-3.2.5\bin\x64\R.exe CMD BATCH --vanilla --slave C:\your_path\Documents\R\Download.r"
'path = """C:\your_path\Documents\R\R-3.2.5\bin\i386"" C:\Users\rshuell001\Documents\R\Download.R"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
Finally, here is a solution working well:
Function Run_R_Script(sRApplicationPath As String, _
sRFilePath As String, _
Optional iStyle As Integer = 1, _
Optional bWaitTillComplete As Boolean = True) As Integer
Dim sPath As String
Dim shell As Object
'Define shell object
Set shell = VBA.CreateObject("WScript.Shell")
'Wrap the R path with double quotations
sPath = """" & sRApplicationPath & """"
sPath = sPath & " "
sPath = sPath & sRFilePath
Run_R_Script = shell.Run(sPath, iStyle, bWaitTillComplete)
End Function
Sub Demo()
Dim iEerrorCode As Integer
iEerrorCode = Run_R_Script("C:\Program Files\R\R-3.6.1\bin\x64\Rscript",
"C:\Users\myname\Desktop\Code.R")
End Sub

Running R script in VBA using Shell

VBA code is running, but it is not saving files from R output (Write.CSV files)
Sub R_Click()
runs an external R code through Shell
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = """" & "C:\Users\a.af.jain\Documents\R\R-3.4.1\bin\x64\RScript" & """ """ & "C:\Users\a.af.jain\Desktop\Missing_data.R" & """"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
R Code
setwd("C:/Users/a.af.jain/Desktop/R")
input_missing = read.csv("input_missing.csv")
Input_LGD = read.csv("Insert_LGD.csv")
Result_data_missing = merge(input_missing,Input_LGD,all.x = TRUE)
write.csv(Result_data_missing,"Result_data_missing.csv")
VBA is able to read input_missing file from R, But i don't know that whether it is doing merge or not and VBA code is not able to save files from R(write.csv file)
Your quotation is off, you need to wrap the address of Rscript by double quotations and leave one space character between the Rscript address and the address of the R file that should be executed:
path = """C:\Users\a.af.jain\Documents\R\R-3.4.1\bin\x64\RScript"" C:\Users\a.af.jain\Desktop\Missing_data.R"
or
path = """C:\Users\a.af.jain\Documents\R\R-3.4.1\bin\x64\RScript""" & " " & "C:\Users\a.af.jain\Desktop\Missing_data.R"

Run R script through access vba

I'm trying to run an R Script from my access DB so it will process some data before it is imported, however i'm having trouble as it fails at the errrorCode on the last line.The scrip is:
Private Sub cmdRcode_Click()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 2
Dim errorCode As Integer
Dim path As String
path = "C:\Users\Liam\Dropbox (BGD_058)\BGD_058\19_BFI_data\Analysis\r_scripts\BFI_DAT_1.R"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
EDIT:
Upon advice from the comments i've changed my file path, avoid spaces and substituted the errorCode as follows:
path = "Rscript C:\Users\Documents\BFI_Field_Forms\R\BFI_DAT_1.R"
errorCode = shell.Run("C:\Users\R\BFI_DAT‌​_1.R", 1, True)
I then updated the environment path to Advanced System Settings/Environment Variable and created a new variable called "PATH" with the line: C:\Program Files\R\R-3.2.2\bin\x64;
The result is that it opens my R file, however it does not run the R script. The priority is for it to run the script (so the data is processed), and if possible, the R file would not be visible to the user.
Any advice appreciated.

VBA could find R library

I am trying to use EXCEL as the front end for a R script. So far, I tested my R script in Windows CMD but I could not make it work in VBA. The error message is Error in library(readxl) : there is no package called 'readxl'. So it looks like VBA environment is picky.
Any suggestions on fixing this error? (fixed now)
Is there a way to run R script and save the function returned value (now it is 5) into a variable in VBA? I can do this by saving a text file and load again, but not sure if there is a better way to handle this.
a simple example of R script, which defines a function and calls it later.
est_var_dw <- function(){
library(readxl)
library(minpack.lm)
library(msm)
return(2+3)
}
est_var_dw()
a simple example of VBA
Sub run_r()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = """" & Cells.Range("B1") & """ """ & Cells.Range("B2") & """ & Pause"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
Update
I figured out the first issue was due locations of different R packages, which can be solved by using .libpath
.libPaths(c(R_library_pth1, R_library_pth2))
There is a very good function for the second part of your question here: Capture output value from a shell command in VBA?
bburns-km defines a vba function ShellRun:
Public Function ShellRun(sCmd As String) As String
'Run a shell command, returning the output as a string'
Dim oShell As Object
Set oShell = CreateObject("WScript.Shell")
'run command'
Dim oExec As Object
Dim oOutput As Object
Set oExec = oShell.Exec(sCmd)
Set oOutput = oExec.StdOut
'handle the results as they are written to and read from the StdOut object'
Dim s As String
Dim sLine As String
While Not oOutput.AtEndOfStream
sLine = oOutput.ReadLine
If sLine <> "" Then s = s & sLine & vbCrLf
Wend
ShellRun = s
End Function
As long as RScript.exe is in your PATH, you can then call from VBA:
Sub Test()
Dim ScriptPath As String
Dim StringOut As String
ScriptPath = "C:\...\test.R" 'Your Path Here
'Assign
StringOut = ShellRun("RScript " & ScriptPath)
'Print
Debug.Print StringOut
End Sub
Anything that your R script prints to console during session will be returned to VBA as a string

Windows Script Host fails

I am trying to run a R script from Excel using VBA. Ideally, I would use an .R (Rscript) name to invoke R and run the process, or if that won't go, then invoke Rscript.exe and execute the filename passed to it.
REXcel is no good because it requires a 32-bit version of Excel (and I am not working in 1989)
I have found what seems to be a perfect script at (http://shashiasrblog.blogspot.co.uk/2013/10/vba-front-end-for-r.html) which, after suitable localisation looks like this:
Sub RunRscript()
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = "C:\Users\Charles\SkyDrive\Documents\Development\G4H\Technical evaluation templates\Graphical analysis.R"
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
This fails with the message
Run Time Error '-2147024894 (80070002)':
Method 'Run' of object 'IWshShell3' failed.
Which tell me exactly nothing. I have tried Googling the error message but got nothing.
I have set the PATH variable to include the directory where R and Rscript live.
I suspect it is something straightforward, but there sems to be a lack of simple ways of executing R from Excel.
You need to add Rscript to your path, otherwise the shell doesn't know what program to send the file to. So modify the path to be
path = "rscript C:\Users\Charles\SkyDrive\Documents\Development\G4H\Technical evaluation templates\Graphical analysis.R"
You may have to provide the fill path to rscript depending on whether or not that directory is in your search path.
I am not sure if this is correct protocol (no doubt I shall receive some horrendous penalty), but thanks to Mr Flick and some poking about I have a solution:
Make sure that rscript.exe is in the system path.
Try to work out how many inverted commas are required to actually get Windows to understand that it is a directory.
Then:
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path As String
path = "rscript ""C:\Users\Charles\SkyDrive\Documents\Development\G4H\Technical evaluation templates\Graphical analysis.R"""
errorCode = shell.Run(path, style, waitTillComplete)
The horrible parsing of cmd when handling white space in directory names finally succumbed to a brute force attack!
I had the same problem. Change the code to include path for both Rscript.exe and R file. The following code worked for me:
Sub RunRscript()
'runs an external R code through Shell
'The location of the RScript is 'C:\R_code'
'The script name is 'hello.R'
Dim shell As Object
Set shell = VBA.CreateObject("WScript.Shell")
Dim waitTillComplete As Boolean: waitTillComplete = True
Dim style As Integer: style = 1
Dim errorCode As Integer
Dim path, p1, p2 As String
path = "RScript E:\R_Folder\VBA_R.R"
p1 = "E:\R-3.1.2\bin\x64"
p2 = "E:\R_Folder"
errorCode = shell.Run("""" & p1 & "\Rscript.exe"" /filename """ & p2 & "\VBA_R.R"" /delay 10000 /preview /quiet", style, waitTillComplete)
'errorCode = shell.Run(path, style, waitTillComplete)
End Sub

Resources