【问题标题】:Returning result of an external script to VBA将外部脚本的结果返回到 VBA
【发布时间】:2016-01-31 01:53:18
【问题描述】:

我正在将我们在 MS Word for Windows 中工作的宏移植到 OSX。该宏允许用户在 Word 中使用 LaTeX 生成方程式,并且必须向服务器发出 POST 请求并返回结果。这在带有 Microsoft.XMLHTTP 对象的 Windows 中可以正常工作,但在 OSX 中似乎没有等效项。

为了解决这个问题,我创建了一个 Python 脚本,它使用 urlliburllib2 来处理请求,并允许我使用 argparse 将我的 LaTeX 字符串和网址作为输入参数发送。该脚本执行我需要的操作,并将 Web 查询的结果作为字符串返回。

我在 VBA 中需要这个字符串。

我当前的 VBA 调用类似于以下内容,其中 pyPathgetURLpath 是静态的,Latex_StrFont_Size 是由用户输入生成的,WebAdd 是正在运行的服务器的地址我们的服务器端脚本。

sCmd = """" & pyPath & "python"" """ & getURLpath & "getURL.py"" --formula """ & _
       Latex_Str & """ --fontsize " & Font_Size & " """ & WebAdd & """"
sResult = Shell(sCmd, vbNormalFocus)

问题是Shell 命令只返回你正在调用的进程的双值PID。我需要从我的 Python 脚本返回的实际字符串。我可以修改 Python 脚本以根据需要返回此脚本,但如何将其输入 VBA?

有人知道我如何将这个结果输入到我的 VBA 环境中吗?

【问题讨论】:

  • 我一直在努力实现这一点。我仍然遇到错误,但我认为从长远来看这可能会完成工作。如果我无法弄清楚是什么导致了我的错误,我会尽快在这里发布更多信息。谢谢!

标签: python macos vba ms-word


【解决方案1】:

从问题中提取的答案:

我搞定了!
我能够使用 result = MacScript(command) 函数调用我的 Python 脚本,其中我将 command 定义如下:

command = "do shell script """ & pyPath & "python " & getURLpath & "getURL.py --formula '" _
          & Latex_Str & "' --fontsize " & Font_Size & " " & WebAdd & """"

我的 Python 脚本名为 getURL.py,它根据用户定义的可选参数 --formula--fontsize 处理对服务器的请求,并分别以 Latex_StrFont_Size 存储在 VBA 中,以及服务器的网址WebAdd。我还在我的 Python 脚本中添加了一些功能来处理传递代理设置。上面通过MacScript传递的命令返回的是Python脚本的stdout,也就是服务器的返回。 Python脚本如下:

# Import the required libraries
from urllib import urlencode
from urllib2 import Request, urlopen, URLError, ProxyHandler, build_opener, install_opener
import argparse

# Set up our argument parser
parser = argparse.ArgumentParser(description='Sends LaTeX string to web server and returns meta data used by LaTeX in Word project')
parser.add_argument('webAddr', type=str, help='Web address of LaTeX in Word server')
parser.add_argument('--formula', metavar='FRML', type=str, help='A LaTeX formula string')
parser.add_argument('--fontsize', metavar='SIZE', type=int, default=10, help='Integer representing font size (can be 10, 11, or 12. Default 10)')
parser.add_argument('--proxServ', metavar='SERV', type=str, help='Web address of proxy server, i.e. http://proxy.server.com:80')
parser.add_argument('--proxType', metavar='TYPE', type=str, default='http', help='Type of proxy server, i.e. http')

# Get the arguments from the parser
args = parser.parse_args()

# Define formula string if input
if args.formula:
    values = {'formula': str(args.fontsize) + '.' + args.formula}   # generate formula from args
else:
    values = {}

# Define proxy settings if proxy server is input.
if args.proxServ:       # set up the proxy server support
    proxySupport = ProxyHandler({args.proxType: args.proxServ})
    opener = build_opener(proxySupport)
    install_opener(opener)

# Set up the data object
data = urlencode(values)
data = data.encode('utf-8')

# Send request to the server and receive response, with error handling!
try:
    req = Request(args.webAddr, data)

    # Read the response and print to a file
    response = urlopen(req)
    print response.read()

except URLError, e:
    if hasattr(e, 'reason'):    # URL error case
        # a tuple containing error code and text error message
        print 'Error: Failed to reach a server.'
        print 'Reason: ', e.reason
    elif hasattr(e, 'code'):    # HTTP error case
        # HTTP error code, see section 10 of RFC 2616 for details
        print 'Error: The server could not fulfill the request.'
        print 'Error code: ', e.code
        # print e.read()

如果有人好奇,在我修复几个额外的错误并对其进行测试后,完整的代码将在project page 上提供。 (工作的)Windows 版本已经在那里了。

【讨论】:

    猜你喜欢
    • 2015-05-29
    • 2022-01-12
    • 2018-09-05
    • 2020-04-30
    • 1970-01-01
    • 2017-01-23
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多