如果我在命令行中运行命令Rscript "C:/TEMP/test.R"
,则它将正常运行,并且脚本将按预期运行。一旦尝试在VBA代码中运行它,它就不会将Rscript识别为有效命令。
Dim shell_obj As Object
Set shell_obj = VBA.CreateObject("WScript.Shell")
Dim errorCode As Integer
errorCode = shell_obj.Run("Rscript ""C:/TEMP/test.R""", 1, True)
当我查看WScript.Shell使用的PATH变量时,我发现它不包含其中包含Rscript路径的系统变量。
Dim shell_obj As Object
Dim wshSystemEnv As Object
Set shell_obj = VBA.CreateObject("WScript.Shell")
' This one does not include the path to the Rscript'
Debug.Print shell_obj.ExpandEnvironmentStrings("%PATH%")
Set wshSystemEnv = shell_obj.Environment("SYSTEM")
' This one includes the path to the Rscript'
Debug.Print wshSystemEnv("PATH")
是否可以强制WScript.Shell对象使用系统环境?还是至少使用其变量?
VBA(版本1):
VBA(版本2):
答案 0 :(得分:2)
EDIT :请参阅文章底部。
希望您会在我的(冗长的)尝试中找到一些用处...:-)
可以从Windows命令行按原样运行的任何命令(including an RScript
)也可以通过the VBA Shell
function来运行 或Windows WScript.Shell
method。
问题是,您的cmd
字符串未已准备好命令行。可以通过敲 + R 并粘贴cmd
字符串变量的内容来确认:
Rscript "**path**/test.R"
我目前尚未安装rscript.exe
,但我怀疑如果尝试在 Run 窗口或命令行中手动运行命令,将会收到错误消息。如果它不在那里运行,显然不会在VBA Shell 中运行。
据我了解,双星号是您使用Java notation的方式,而 R 中是same as a ^
caret character,用于计算指数。 / p>
要在 VBA 中返回Windows PATH
environment variable,请使用VBA's Environ
function。
要插入值环境变量inline at the command line,请用%
百分号%
符号将其包围,例如%path%
PATH
环境变量 PATH
不返回单个文件夹。 Windows应该检查这是文件夹列表,以查找一个试图运行的可执行文件。
在命令外壳中输入命令或程序进行系统调用以执行程序时,系统首先搜索当前工作目录,然后搜索路径,从左到右检查每个目录,查找与给定命令名称匹配的可执行文件名。
Windows系统目录(通常为
C:\WINDOWS\system32
)通常是路径中的第一个目录,然后是安装的软件包的许多(但不是全部)目录。
示例默认值为PATH
(from a fresh install of Windows 7):
%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
与%path%, this includes
%SystemRoot%`一样,在Windows 7上默认为字符串:
C:\Windows
您可以验证PATH
环境标签的值:
cmd
,然后按 Enter 。 (应打开一个命令行窗口。)echo %path%
,然后按 Enter 。将显示Window PATH
环境变量的内容。
您还可以在Windows中检查环境变量:
注意::尽管您从技术上说可以更改此窗口中的
PATH
,但我不会建议这样做,尤其是对于PATH
,因为它分为系统和用户文件夹,并且Windows在某些区域喜欢某些文件夹,并且某些更改要等到重新启动后才能生效,而其他更改才生效。 等等等等,相信我:在命令行中这样做更容易。
因此,基于所有这些,看来您要运行的命令是:
Rscript "C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem/test.R"
...显然不起作用。
我只能推测您要完成的工作。
我怀疑您不打算返回整个PATH
变量,而是只对 当前工作文件夹 感兴趣。
如果是这样,您根本不需要指定文件夹。 Shell
已经在“当前”文件夹中执行了命令。
您可以使用directory or folder来检查哪个VBA CurDir()
function是最新的一种方式,例如:
Debug.Print CurDir()
可以使用the ChDir
statement来更改CurDir
的值。
请注意,CurDur()
命令经常与类似的功能混淆,例如:
Application.Path
,它返回Excel应用程序的路径,或者ActiveWorkbook.Path
,返回活动工作簿的保存位置(如果未保存,则返回一个空字符串)。 rScript
) 如果您的 R 脚本和rscript.exe
都在当前工作文件夹中 ,则只需一行VBA即可运行它:>
Shell "rscript.exe test.R", vbNormalFocus
如果您要求VBA在恢复VBA之前先等待以完成Shell命令的执行,则可以仅执行以下一行:
CreateObject("WScript.Shell").Run "rscript.exe test.R", vbNormalFocus, True
我通常会提出指向我用来验证答案的任何站点的链接,因此,这必须是我的研究最多的答案,因为我从未列出过该列表很长的时间,这次我省略了一些!
Shell
Function (VBA) Environ
Function (VBA) R.exe
, Rcmd.exe
, Rscript.exe
and Rterm.exe
: what's the difference? PATH
variable in Windows 10 PATH
for Windows 7 CurDir()
Function (VBA) ChDir()
Statement (VBA) Application.Path
(Excel/VBA) ActiveWorkbook.Path
(Excel/VBA) Shell
command to complete wscript.shell
and shell.application
关于代码错误的另一个演示:
我在
test.bat
中有一个名为C:\WINDOWS
的批处理文件。我的PATH
环境变量包含C:\WINDOWS
(以及其他内容)。如果我转到根文件夹
C:\
中的命令提示符,然后键入test.bat
:...它可以正常运行(即使我的文件不在该文件夹中,因为
c:\windows
文件夹位于PATH
变量之内。)
但是 ,如果我转到命令提示符并键入
C:\test.bat
:...它不起作用。它找不到文件,因为我指定了文件所在的文件夹 。
---在VBA中,如果我运行命令
Shell "test.bat",1
:...它可以正常运行(即使我的文件不在该文件夹中,因为
c:\windows
文件夹位于PATH
变量之内。)
但是 ,如果在VBA中运行命令
Shell "c:\test.bat",1
:...它不起作用。它找不到文件,因为我指定了一个* 不在其中的文件夹**。
VBA和
Shell
命令在被赋予相同信息时,都具有相同方式 。
答案 1 :(得分:0)
如果您最近修改了系统PATH变量,则必须重新启动运行VBA的Office应用程序。 VBA向WScript发送路径变量,并且仅在重新启动后重新读取它。重新启动后,它将从系统中重新读取PATH变量,并将新的正确路径发送到WScript。
我有同样的问题。我已经更新了系统PATH变量,但是WScript.Shell对象正在从Excel中传递路径变量,而不是从系统中读取。 Excel在启动时已读取路径,并且不知道它已更改。关闭Excel并重新打开后,WScript拥有更新的路径变量,并且脚本成功执行。