在WScript.Shell对象中调用Run时无法识别环境变量

时间:2018-07-24 23:11:54

标签: vba shell

如果我在命令行中运行命令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对象使用系统环境?还是至少使用其变量?

Cmd: enter image description here

VBA(版本1):

enter image description here

VBA(版本2):

enter image description here

2 个答案:

答案 0 :(得分:2)

  

EDIT 请参阅文章底部。

希望您会在我的(冗长的)尝试中找到一些用处...:-)


测试命令行准备情况

可以从Windows命令行按原样运行的任何命令(including an RScript)也可以通过the VBA Shell function来运行 Windows WScript.Shell method

问题是,您的cmd字符串已准备好命令行。可以通过敲 Windows Key + 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%


Windows的PATH环境变量

PATH不返回单个文件夹。 Windows应该检查这是文件夹列表,以查找一个试图运行的可执行文件。

  

在命令外壳中输入命令或程序进行系统调用以执行程序时,系统首先搜索当前工作目录,然后搜索路径,从左到右检查每个目录,查找与给定命令名称匹配的可执行文件名。

     

Windows系统目录(通常为C:\WINDOWS\system32)通常是路径中的第一个目录,然后是安装的软件包的许多(但不是全部)目录。

示例默认值为PATHfrom a fresh install of Windows 7):

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem

%path%, this includes%SystemRoot%`一样,在Windows 7上默认为字符串:

C:\Windows

检查环境变量

您可以验证PATH环境标签的值:

  • Windows Key + R
  • 键入cmd,然后按 Enter 。 (应打开一个命令行窗口。)
  • 键入或粘贴echo %path%,然后按 Enter

将显示Window PATH环境变量的内容。

您还可以在Windows中检查环境变量:

  • Windows Key 并键入env(进行搜索)
  • 单击Edit the system environment variables。 (有一个类似的选项“ ...为您的帐户” ,它与完全不同。)
  • 点击 <kbd>Environment Variables...</kbd>
    img
  

注意::尽管您从技术上说可以更改此窗口中的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,返回活动工作簿的保存位置(如果未保存,则返回一个空字符串)。

可能的解决方案: (如何在VBA中的当前路径中运行rScript

  • 如果您的 R 脚本和rscript.exe都在当前工作文件夹中 ,则只需一行VBA即可运行它:

    Shell "rscript.exe test.R", vbNormalFocus
    
  • 如果您要求VBA在恢复VBA之前先等待以完成Shell命令的执行,则可以仅执行以下一行:

    CreateObject("WScript.Shell").Run "rscript.exe test.R", vbNormalFocus, True
    

更多信息:

我通常会提出指向我用来验证答案的任何站点的链接,因此,这必须是我的研究最多的答案,因为我从未列出过该列表很长的时间,这次我省略了一些!



  

关于代码错误的另一个演示:

     
    

我在test.bat中有一个名为C:\WINDOWS的批处理文件。我的PATH环境变量包含C:\WINDOWS(以及其他内容)。

  
     

如果我转到根文件夹C:\中的命令提示符,然后键入test.bat

     

img1

     

...它可以正常运行(即使我的文件不在该文件夹中,因为c:\windows文件夹位于PATH变量之内。)

     
     

但是 ,如果我转到命令提示符并键入C:\test.bat

     

img2

     

...它起作用。它找不到文件,因为我指定了文件所在的文件夹

     

---在VBA中,如果我运行命令Shell "test.bat",1

     

img3

     

...它可以正常运行(即使我的文件不在该文件夹中,因为c:\windows文件夹位于PATH变量之内。)

     
     

但是 ,如果在VBA中运行命令Shell "c:\test.bat",1

     

img4

     

...它起作用。它找不到文件,因为我指定了一个* 不在其中的文件夹**。

     
     
    

VBA和Shell命令在被赋予相同信息时,都具有相同方式

  

答案 1 :(得分:0)

如果您最近修改了系统PATH变量,则必须重新启动运行VBA的Office应用程序。 VBA向WScript发送路径变量,并且仅在重新启动后重新读取它。重新启动后,它将从系统中重新读取PATH变量,并将新的正确路径发送到WScript。

我有同样的问题。我已经更新了系统PATH变量,但是WScript.Shell对象正在从Excel中传递路径变量,而不是从系统中读取。 Excel在启动时已读取路径,并且不知道它已更改。关闭Excel并重新打开后,WScript拥有更新的路径变量,并且脚本成功执行。