从VBA同步运行shell命令,同时显示和捕获输出

时间:2018-09-28 10:20:03

标签: vba excel-vba powershell cmd

我想从VBA运行R脚本,为此我使用rscript.exe。我还传递了此脚本2个参数。执行应该同步,并且输出都应实时显示 并存储在日志文件中。

到目前为止,我已经能够创建命令,使用cpearson shellAndwait模块以同步方式从VBA运行它(VBA在继续执行之前先等待shell命令执行),并在不错的cmd提示符下显示输出窗口。

batchCommand =   Chr(34) & r_location & Chr(34) & _
                 " --verbose " & _
                 Chr(34) & fp_rscript & Chr(34) & _
                 " " & Chr(34) & arg1 & Chr(34) & _
                 " " & Chr(34) & arg2 & Chr(34)  
errorcode = ShellAndWait (batchCommand, 0, vbMaximizedFocus, AbandonWait)

但是,如果我的R脚本失败,错误代码仍为0,唯一获得输出的方法是将cmdCommand粘贴到cmd提示符下

添加cmd / K并将所有内容包装在第二组“中”是不可行的,因为shellandwait将等待用户手动关闭cmd提示符。

因此,我希望使用powershell&tee将输出写入到我发现了此solution的文本文件中。

但是,我使用powershell的新batchCommand失败。

batchCommand =   "powershell.exe " & _
                    Chr(34) & r_location & Chr(34) & _
                   " --verbose " & _
                   Chr(34) & fp_rscript & Chr(34) & _
                   " " & Chr(34) & fp_rscript & Chr(34) & _
                   " " & Chr(34) & arg2 & Chr(34) & _
                   " | tee " & Chr(34) & logfile & Chr(34)

batchCommand看起来像这样:

?batchCommand 
powershell.exe "C:\Users\...\bin\RScript.exe" --verbose "E:\...\stage_2\antares_model_builder_stage_2.R" "E:\...\stage_2\antares_model_builder_stage_2.R" "E:\...\2018-09-28-1232 srv6_19-20_basecase" | tee "E:\...\2018-09-28-1232 srv6_19-20_basecase\s2_rscript_logfile.txt" 

如注释中所述,由于它试图解释tee,我无法再在cmd中输入此batchCommand。

  

“'tee'不被识别为内部或外部命令,可操作程序或批处理文件。”

将命令粘贴到powershell中可以得到:

  

致命错误:无法打开文件'E:\ SRV6 \ vanilla_hybrid \ 030':没有此类文件或目录

因此,它与路径中的空格有关。在powershell.exe之后添加“”所有参数将产生相同的错误。 但是,使用'&'可以:

& "C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe" --verbose "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase"

现在的问题变成了如何将此字符串作为参数传递给powershell -command?帮助文件说明

  

如果Command的值为字符串,则Command必须为最后一个   该命令中的参数,因为在   命令被解释为命令参数。

     

要编写运行Windows PowerShell命令的字符串,请使用   格式:       “&{}”,引号表示字符串,invoke运算符(&)导致命令被执行。

所以我再试一次:

powershell -command "& {"C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe" --verbose "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R" "E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase"}"
Fatal error: cannot open file 'E:\SRV6\vanilla_hybrid\030': No such file or directory

有人可以帮助我获得此最终要求(将输出写入日志文件)吗?

1 个答案:

答案 0 :(得分:0)

找到了解决方案。需要混合使用'和'。 batchcommand应该看起来像这样:

?batchCommand
powershell.exe -command "& 'C:\Users\hgd253\appdata\Local\Microsoft\AppV\Client\Integration\5A67571D-6F50-4EAD-BB33-A0D712D7FC6A\Root\R\R-3.3.3\bin\RScript.exe' --verbose 'E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R' 'E:\SRV6\vanilla_hybrid\030 scripts\libraries\stage_2\antares_model_builder_stage_2.R' 'E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase' | tee 'E:\SRV6\vanilla_hybrid\100 input buffer\2018-09-28-1337 srv6_19-20_basecase\s2_rscript_logfile.txt'"

VBA代码因此变为:

batchCommand = "powershell.exe -command " & _
               Chr(34) & "& " & _
               Chr(39) & r_location & Chr(39) & _
               " --verbose " & _
               Chr(39) & fp_rscript & Chr(39) & _
               " " & Chr(39) & fp_rscript & Chr(39) & _
               " " & Chr(39) & arg2 & Chr(39) & _
               " | tee " & _
               Chr(39) & logfile & Chr(39) & Chr(34)