首页 > 解决方案 > 如何在 VBA 中使用 Shell.Run 而不是 Shell.Exec 捕获 shell 输出?

问题描述

我尝试执行以下操作:

我想使用此答案(解决方案 1)中描述的代码在 excel-VBA 和 Python 之间传递数据数组。这样做的原因是我找不到 VBA 的 scipy 方法,因此我这样做了。为了从 python 中捕获错误消息,我尝试实现类似这样的东西。

我的 VBA 代码如下所示:

Sub Usage2()
Dim outputarr() As Double
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")
    oCmd = "<fullpathtopython> " & """" & "<fullpathtoscript>" & """"
' Make the data available via GetData()'
Cache = Array(4, 6, 8, 9)

Set oExec = oShell.Exec(oCmd)
Set oOutput = oExec.StdOut

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

Debug.Print s
' Handle the returned data '
Debug.Assert Cache(3) = 8

Set oOutput = Nothing: Set oExec = Nothing
Set oShell = Nothing
End Sub

我的 python 脚本如下所示:

import win32com.client
import numpy as np
import os
import matplotlib.pyplot as plt
import win32com.client
from scipy.interpolate import LSQUnivariateSpline, UnivariateSpline

print "Hello, User!"

# get the running instance of Excel
app = win32com.client.GetObject(Class="Excel.Application")

# get some data from Excel
data = app.run("GetData") # this OR

ssc=np.array(data) # this probably makes an error
print ssc

#do some fitting ...

# return some data to excel
app.run("SetData", sscnew)

这个想法很简单:

这个 VBA 代码的问题是,Python.exe 被打开但程序没有被执行。它看起来像这样:

在此处输入图像描述

打开外壳并闪烁光标。'Hello, User' 不会被打印,因此程序不会被执行,因为这通常会在程序中发生任何错误之前运行。如果我关闭此窗口,“您好,用户!” 以 VBA 打印,但仅此而已。

具体问题:如何通过此 VBA-Python 接口输入和输出数组并获取错误消息以在 VBA-shell 中打印它们?

标签: pythonexcelvbashell

解决方案


  1. 一种选择是处理“东西”pandas并另存为csv,然后作为数组拉入 VBA ,甚至在将最终结果拉入 VBA 以进行格式化、发送电子邮件或需要 VBA 的任何内容之前,在 python 中执行所有操作。

  2. 关于错误,有几乎相同的问题并且能够解决感谢@MichaelButscher链接。基本上你需要使用错误重定向,如

    import sys path_err = r'\\yourpath\test\err.txt' path_out = r'\\yourpath\test\out.txt' sys.stderr = open(path_err, 'w') sys.stdout = open(path_out, 'w') path = r'\\yourpath\test\test1.txt' with open (path, "w") as f: f.write("test1") raise IndexError

跟踪致命错误 (err.txt) 或预期输出 (out.txt)。

我希望这有帮助


推荐阅读