返回到 Word VBA Windows 中 VBA 宏调用的 Python 脚本的结果

Return to Word vba the result of a python script called by the vba macro in Windows

提问人:Marc B. Hankin 提问时间:11/9/2016 最后编辑:ashleedawgMarc B. Hankin 更新时间:1/10/2022 访问量:1374

问:

我知道如何在 Windows(7 或 10)的 MS Word 中使用 vba 来运行 python 脚本。下面是一个示例:

RegExpPatrn = "[RegExp search string]"
PythonScriptFullName = Chr(34) & "[PythonScriptFullname.py]" & Chr(34)
PyExe = "C:\Python27\python2.7.exe"
CmdLin = PyExe & " " & PythonScriptFullName & " " & RegExpPatrn 
Set objWshShell = CreateObject("WScript.Shell")
objWshShell.Run strCmdLin01, 1, True

但是我不知道如何将 Python 脚本的结果(例如,正则表达式文件搜索)返回到调用 Python 脚本的 vba 宏。

如果有人有任何建议,我将不胜感激。

我读过关于“管道”的文章,但我不明白该怎么做。

我已经阅读了有关使用环境变量的文章,但是我无法使用python创建在python脚本运行后能够检索的环境变量。

如果有人有任何建议,我将不胜感激。

马克

. .

**

2016 年 11 月 10 日添加了解决方案,感谢 user235218 和 Tim Williams:

** 以下是:

  1. 我的python脚本;

  2. 我的 vba sub 版本;和

  3. 我的 vba 函数版本。

这是我的 python 脚本:

print("This is my Python script's output")

这是我的 vba sub 版本:

    Sub subTestfnShellOutput()
    Dim strPythonPath As String
    Dim strPyScript As String
    Dim strCmd As String

    strPythonPath = "C:\Python27\python2.7.exe"
    strPyScript = "C:\Apps\UtilitiesByMarc\Test_2016-11-09_StackOverFlowSoution_aaa_.py"
    strCmd = strPythonPath & " " & strPyScript

    'Debug.Print fnShellOutput("python D:\temp\test.py") ''>> hello world
    MsgBox fnShellOutput(strCmd) ''>> hello world        
    End Sub 'subTestfnShellOutput

这是我的 vba 函数版本:

    Function fnShellOutput(cmd As String) As String
    ' https://stackoverflow.com/questions/39516875/return-result-from-python-to-vba

    Dim oShell As Object, oCmd As String
    Dim oExec As Object, oOutput As Object
    Dim arg As Variant
    Dim s As String, sLine As String

    Set oShell = CreateObject("WScript.Shell")
    Set oExec = oShell.Exec(cmd)
    Set oOutput = oExec.StdOut

    While Not oOutput.AtEndOfStream
        sLine = oOutput.ReadLine
        If sLine <> "" Then s = s & sLine & vbNewLine
    Wend

    """November 10, 2016 Addendum:  It works now that I replaced 'ShellOutput = s' with
     'fnShellOutput = s'"""
    fnShellOutput = s

    Set oOutput = Nothing
    Set oExec = Nothing
    Set oShell = Nothing    
    End Function 'fnShellOutput
蟒蛇 VBA MS-Word

评论

1赞 David Zemens 11/9/2016
最简单的实现可能是修改 python 脚本以在已知位置写入文本文件,然后让 VBA 查询该文件。但是,这在分布式环境中很难实现。执行此操作的正确方法是将 python 程序注册为具有可访问方法(基本上是 API)的 COM 服务器,然后 VBA 可以创建该对象的实例并调用其方法,这些方法直接返回给调用方 (VBA)。
0赞 Marc B. Hankin 11/10/2016
谢谢。在做一些研究以了解将 python 程序注册为 COM 服务器意味着什么时,我遇到了 Pyro4,它表面上是一个库,使您能够构建应用程序,其中对象可以通过网络相互通信,只需最少的编程工作。如果我不知道在哪里可以看到一个示例,显示如何将 python 程序注册为 COM 服务器,然后按照您的指示使用它,我稍后可以跟进您吗?
0赞 Tim Williams 11/10/2016
调用函数,但使用fnShellOutputShellOutput
0赞 Tim Williams 11/10/2016
如果该更改不能修复它,那么您需要准确解释运行版本时会发生什么。
0赞 Marc B. Hankin 11/10/2016
成功了!!!!!!非常感谢!!!!

答:

4赞 Tim Williams 11/9/2016 #1

如果您在 Python 脚本中使用,则打印的内容将被发送到 stdout。print()

使用对象运行脚本可以访问 stdout 内容。WScript.Shell

下面是一个非常基本的例子:

测试 python 脚本 test.py

print("hello world")

VBA:

Sub TestIt()
    Debug.Print ShellOutput("python D:\temp\test.py") ''>> hello world
End Sub

Function ShellOutput(cmd As String) As String

    Dim oShell As Object, oCmd As String
    Dim oExec As Object, oOutput As Object
    Dim arg As Variant
    Dim s As String, sLine As String

    Set oShell = CreateObject("WScript.Shell")
    Set oExec = oShell.Exec(cmd)
    Set oOutput = oExec.StdOut

    While Not oOutput.AtEndOfStream
        sLine = oOutput.ReadLine
        If sLine <> "" Then s = s & sLine & vbNewLine
    Wend

    ShellOutput = s

    Set oOutput = Nothing
    Set oExec = Nothing
    Set oShell = Nothing

End Function

改编自:从 Python 返回结果到 Vba

评论

0赞 Marc B. Hankin 11/10/2016
请看一下我今天添加的附录,以回应您的帖子。谢谢你的努力。他们非常感谢。马克