从VBA启动R脚本时保持Shell/cmd打开

从VBA启动R脚本时保持Shell/cmd打开,r,excel,vba,R,Excel,Vba,我有一个R脚本,它通过链接到VBA脚本的按钮从Excel工作簿运行 问题是,每当R脚本遇到错误时(比如它没有找到它应该读取的文件之一),运行R脚本的Shell/cmd窗口就会立即关闭。问题是你看不到任何关于它失败原因的线索。然后,我必须通过修改代码并在RStudio中运行来手动调试它,以查找错误——通常我必须为不了解R的其他人这样做 我使用的VBA代码是从我在这里找到的一篇SO文章中复制和修改的。我不是很精通VBA,也不理解很多代码,所以我正在寻找一个简单的解决方案。我的VBA代码如下: 选项显

我有一个R脚本,它通过链接到VBA脚本的按钮从Excel工作簿运行

问题是,每当R脚本遇到错误时(比如它没有找到它应该读取的文件之一),运行R脚本的Shell/cmd窗口就会立即关闭。问题是你看不到任何关于它失败原因的线索。然后,我必须通过修改代码并在RStudio中运行来手动调试它,以查找错误——通常我必须为不了解R的其他人这样做

我使用的VBA代码是从我在这里找到的一篇SO文章中复制和修改的。我不是很精通VBA,也不理解很多代码,所以我正在寻找一个简单的解决方案。我的VBA代码如下:

选项显式
公共子RunRscript()
活动工作簿。保存
作为对象的暗壳
Set shell=VBA.CreateObject(“WScript.shell”)
将waitTillComplete设置为布尔值:waitTillComplete=True
将样式设置为整数:样式=1
将脚本路径设置为字符串
scriptPath=范围(“F5”)。值
变暗参数为字符串
参数=范围(“F3”)。值
将路径设置为字符串
path=“”C:\Program Files\R\R-3.4.2\bin\Rscript.exe=“”&脚本路径和“”
&参数&“”
活动工作簿。保存
将错误代码设置为整数
errorcode=shell.Run(路径、样式、完成)
活动工作簿。保存
端接头
scriptPath
指向R脚本的路径,
argument
是我传递给R脚本的参数

我曾尝试传递常用参数以保持cmd窗口打开,但我没有设法找到答案。正如前面提到的,我不太理解VBA语法,“path”变量非常复杂,因为这些无休止的双引号。

基于此评论:

@弗里曼,R脚本的输出实际上是一系列Excel工作簿,它打开,打印数据,然后保存。它读取一个列表,其中包含所有需要读取的文件的路径,作为输入,以生成在excel中打印所需的输出数据。有时,该列表中的一条路径是错误的,因此程序中途停止,用户也不知道为什么。(原因也可能是其他原因)。如果我能将shell/cmd中生成的文本自动传递到notepad/textpad文件,至少这样用户就可以打开并检查了

听起来最好的办法可能是让
R
脚本在尝试进行处理之前验证路径/文件。我几乎不熟悉
R
,但据我所知,应该有一个库,允许您测试路径和/或该路径上的文件是否存在。如果它不存在,脚本只需在它应该创建/更新的文件中放入一条错误消息,表明它找不到请求的路径/文件,或者它可以将该消息写入错误日志,在处理完成时,VBA代码可以打开该日志。

基于此注释:

@弗里曼,R脚本的输出实际上是一系列Excel工作簿,它打开,打印数据,然后保存。它读取一个列表,其中包含所有需要读取的文件的路径,作为输入,以生成在excel中打印所需的输出数据。有时,该列表中的一条路径是错误的,因此程序中途停止,用户也不知道为什么。(原因也可能是其他原因)。如果我能将shell/cmd中生成的文本自动传递到notepad/textpad文件,至少这样用户就可以打开并检查了

听起来最好的办法可能是让
R
脚本在尝试进行处理之前验证路径/文件。我几乎不熟悉
R
,但据我所知,应该有一个库,允许您测试路径和/或该路径上的文件是否存在。如果它不存在,脚本只需在它应该创建/更新的文件中放入一条错误消息,表明它找不到请求的路径/文件,或者它可以将该消息写入错误日志,在处理完成时,VBA代码可以打开该日志。

您可以使用

errorcode = shell.Run("cmd /k " & path, style, waitTillComplete)
而不是

errorcode = shell.Run(path, style, waitTillComplete)
我们打开了命令行工具的一个新实例,因此可以使用它的参数。参数/kk使cmd窗口保持打开状态(使用/c切换至close)。在cmd参数之后,我们添加要执行的脚本

但是有一个问题:如果关闭cmd窗口,VBA会抛出溢出错误。我使用Excel工作表中的标志在调试模式和正常模式之间切换:

debugging = Range("N5").Value 'True/False
If debugging Then
    errorCode = shell.Run("cmd /k " & path, style, waitTillComplete)
Else
    errorCode = shell.Run(path, style, waitTillComplete)
End If
如果脚本失败,我将在Excel工作表的单元格中将调试模式设置为True,然后重新运行该脚本。

您可以使用

errorcode = shell.Run("cmd /k " & path, style, waitTillComplete)
而不是

errorcode = shell.Run(path, style, waitTillComplete)
我们打开了命令行工具的一个新实例,因此可以使用它的参数。参数/kk使cmd窗口保持打开状态(使用/c切换至close)。在cmd参数之后,我们添加要执行的脚本

但是有一个问题:如果关闭cmd窗口,VBA会抛出溢出错误。我使用Excel工作表中的标志在调试模式和正常模式之间切换:

debugging = Range("N5").Value 'True/False
If debugging Then
    errorCode = shell.Run("cmd /k " & path, style, waitTillComplete)
Else
    errorCode = shell.Run(path, style, waitTillComplete)
End If

如果脚本失败,我会在Excel工作表的一个单元格中将调试模式设置为True,然后重新运行该脚本。

如果您只需要捕获外壳命令的输出,您可以使用
Exec
而不是
Run
,这样您就可以访问控制台输出。另外,将
var2
传递给
R
脚本作为第一个参数,然后将
var1
作为脚本的第二个参数,这会让人感到困惑。您可能需要考虑重命名反映它们所持有的数据的变量(也许<代码> Script路径< /COD>和<代码>参数< /代码>