Use VBA to call R code - r

I am working on a project that I need to use VBA as front end to call R as back end. Apparently, there is no bug warning but I do not get my output.
Based on VBA, I ask R to read an external csv file and then write a table csv as output. But it does not do the job.
Here is my code VBA and R.
VBA####
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 As String
path = "RScript ""I:\des\Perso\Xiaofei\try.R"""
errorCode = shell.Run(path, style, waitTillComplete)
End Sub
R#####
a <- read.table("German_ZCY_frombloomberg.csv",sep = ",",header = TRUE)
a <- data.frame(a)
write.table(a,"I:/des/Perso/Xiaofei/hello.csv", quote = FALSE, row.names =FALSE, col.names = TRUE, sep = ";")
I do not know where is the problem since no warning happend. But I can not see the csv file "hello.csv" created.
On the other hand, if I use another R code to simply write a phrase into a text file with the following code, it works very well(VBA is able to let R do the job)
R##
sink('I:/des/Perso/Xiaofei/hello.txt',append=F,type="output")
cat('Hello World')
var1<-5^3
var2<-7^3
cat('\nThe result of adding',var1,'to',var2,'is',var1+var2)
sink(NULL)
Could you please help me with this problem? Thank you very much,
Best regards,
Xiaofei,

Related

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"

VBA to R through Command Prompt Shell

I am trying to build a script in VBA that will be executed in R. I have already been able to execute R scripts via VBA's shell command, but been unable to do so when I add arguments to the code.
Following is my VBA code to execute 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
Dim var1
Dim var2
Dim var3
var1 = Sheets("Command").Range("ticker").Value
var2 = Sheets("Command").Range("type").Value
var3 = Sheets("Command").Range("period").Value
path = "Rscript C:\Documents\RProjects\FA.R " & var1 & " " & var2 & " " & var3
errorCode = shell.Run(path, style, waitTillComplete)
Following is the code I am running in R:
setwd("C:/Documents/RProjects/WorkingLibrary")
library(quantmod)
args = commandArgs(trailingOnly=T)
var1 = as.character(args[1])
var2 = as.character(args[2])
var3 = as.character(args[3])
x = getFinancials(var1)
Data = viewFinancials(get(x), type=var2, period=var3)
write.csv(Data,'TestData.csv')
I know this is failing because the csv file is not saving down, therefore there is no data being pulled by R. If I pass no variables and just have excel run an R script that prints say, "Hello World!" and saves the csv, that works. But when I add the variable arguments it fails. If I hard code the variables in the R script, the csv will work, therefore I know the R code is sound, but not picking up on the arguments when passed via command line.
I do not know if the problem is on the VBA end or the R end. All I can identify is that the problem is in either:
1) the passing of the arguments to the command line
2) the accepting of the argument in R
3) a combination of both.
Any ideas? Thanks.
I am an idiot. I had my path wrong. This code works perfectly and passes the variables like a dream. If anyone would like to reference or use this code for a similar project, you are free to do so. Just ensure you have the right file path :P

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