首页 > 解决方案 > 从 VBA 同步运行 shell 命令,同时显示和捕获输出

问题描述

我想从我使用 rscript.exe 的 VBA 运行 R 脚本。我还传递了这个脚本 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,并且获取输出的唯一方法是将 batchCommand 粘贴到 cmd 提示符中

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

因此,我希望将输出写入一个文本文件,我使用 powershell & tee找到了这个解决方案。

但是,我使用 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 
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" 

正如评论中所指出的,我不能再在 cmd 中输入这个 batchCommand,因为它试图解释 tee。

“'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 必须是 command 中的最后一个参数,因为在命令之后键入的任何字符都被解释为命令参数。

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

所以我再试一次:

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

谁能帮我完成这个最终要求(将输出写入日志文件)工作?

标签: vbaexcelpowershellcmd

解决方案


找到了解决方案。需要 ' 和 " 的混合物。批处理命令应如下所示:

?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)

推荐阅读