VBA通过Shell调用Python脚本不执行及获取返回值问题求助
解决方案
一、Python脚本修复(这是脚本未执行的核心原因)
你现有Python脚本存在三个致命问题导致代码完全未运行:
- 入口判断错误:
if __name__ == "__CDAvsFA__"是错误写法,脚本直接被调用时__name__的固定值为__main__,该判断永远不成立,内部代码不会执行。 - 未接收VBA传入的PDF路径参数:你从VBA传递了PDF路径给Python,但脚本未做参数接收逻辑,
xFilepath属于未定义变量,就算入口正确也会直接报错。 - 缺少sys模块导入:读取命令行参数需要依赖sys模块。
修改后的完整Python代码如下:
import io import sys # 新增导入sys模块读取命令行参数 from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter from pdfminer.converter import TextConverter from pdfminer.layout import LAParams from pdfminer.pdfpage import PDFPage def convert_pdf_to_txt(path): rsrcmgr = PDFResourceManager() codec = 'utf-8' laparams = LAParams() with io.StringIO() as retstr: with TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams) as device: with open(path, 'rb') as fp: interpreter = PDFPageInterpreter(rsrcmgr, device) password = "" maxpages = 0 caching = True pagenos = set() for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password, caching=caching, check_extractable=True): interpreter.process_page(page) return retstr.getvalue() if __name__ == "__main__": # 修正入口判断 xFilepath = sys.argv[1] # 读取VBA传入的第一个参数(PDF路径) PDFtext = convert_pdf_to_txt(xFilepath) print(PDFtext, flush=True) # 加flush确保输出立刻刷新到标准流
二、VBA代码修复
现有VBA的Shell参数拼接存在路径识别风险:如果路径包含空格,Shell会把空格当成参数分隔符导致命令执行失败,需要给所有路径加双引号包裹。另外可以新增错误流读取逻辑,方便排查Python端的报错。
1. Shell命令拼接修正
把原来的ShellArg拼接逻辑替换为:
' 路径用双引号包裹,避免空格导致的识别错误 ShellArg = "python """ & sfilepath & pythonfilename & """ """ & xFilepath & """" ' 备注:如果提示找不到python命令,把上面的python替换为你本地python.exe的完整路径,例如: ' ShellArg = """C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\python.exe""" & " """ & sfilepath & pythonfilename & """ """ & xFilepath & """"
2. ShellRunPython函数优化(可选,方便排错)
新增标准错误流读取,Python的报错会输出到这里,避免你看不到错误信息:
Public Function ShellRunPython(sCmd As String) As String Dim oShell As Object Set oShell = CreateObject("WScript.Shell") Dim oExec As Object Set oExec = oShell.Exec(sCmd) ' 同时读取标准输出和标准错误 Dim sOut As String, sErr As String, sLine As String While Not oExec.StdOut.AtEndOfStream sLine = oExec.StdOut.ReadLine If sLine <> "" Then sOut = sOut & sLine & vbCrLf Wend While Not oExec.StdErr.AtEndOfStream sLine = oExec.StdErr.ReadLine If sLine <> "" Then sErr = sErr & sLine & vbCrLf Wend ' 有错误优先返回错误信息方便排查,正常则返回输出内容 If sErr <> "" Then Debug.Print "Python执行错误:" & sErr ShellRunPython = sErr Else ShellRunPython = sOut End If End Function
三、返回值逻辑说明
你原有返回值逻辑是正确的,修复以上问题后,str1 = ShellRunPython(ShellArg) 会自动将Python脚本print的PDFtext内容赋值给str1,无需额外修改。
内容的提问来源于stack exchange,提问作者Shri
相关产品推荐
相关产品推荐

