【问题标题】:Call python script from vba with wsh使用 wsh 从 vba 调用 python 脚本
【发布时间】:2016-09-06 19:46:29
【问题描述】:

我需要从 vba 调用一个 python 脚本,使用 shell 可以正常工作。

Sub CallPythonScript()

        Call Shell("C:\Program Files (x86)\Python27\python.exe C:\Users\Markus\BrowseDirectory.py")

End Sub

但是当我尝试使用 wsh(由于等待功能)时,它就不再起作用了。

Sub CallPythonScript()

    Dim wsh As Object
        Set wsh = VBA.CreateObject("WScript.Shell")

    Dim myApp As String: myApp = "C:\Program Files (x86)\Python27\python.exe C:\Users\Markus\BrowseDirectory.py"
    Dim waitOnReturn As Boolean: waitOnReturn = True
    Dim windowStyle As Integer: windowStyle = 1

    wsh.Run """"" & myApp & """"", windowStyle, waitOnReturn

End Sub

但是,我在家中使用了相同的代码,一切正常,不同之处在于路径中没有任何空白。所以很自然地,这些空白肯定有问题。非常感谢您的帮助。

【问题讨论】:

  • 我怀疑它是否曾与该路径一起使用:路径中有空格。 wsh.Run 如何知道如何解析参数?在家里,C:\python27 肯定有 python。
  • 没错,这就是我所说的“路径中没有任何空白”的意思。

标签: python vba excel wsh


【解决方案1】:

除非你用引号保护目录,否则解释器不可能区分包含空格的目录和真正的参数。

一种变通方法,实际上是一个更好的解决方案,依赖于 Python 将 .py 扩展与安装的 Python 解释器相关联的事实。

只需执行此操作(就像您要启动 .bat 文件一样):

Dim myApp As String: myApp = "C:\Users\Markus\BrowseDirectory.py"

无论python安装在哪里,你的代码都可以工作(空格问题消失了)

excel 中的这个小测试对我有用并运行了 pycrust.py,它恰好在我的系统中 PATH

Sub foo()
  Dim wsh As Object
  Set wsh = VBA.CreateObject("WScript.Shell")

    Dim myApp As String: myApp = "pycrust.py"
    Dim waitOnReturn As Boolean: waitOnReturn = True
    Dim windowStyle As Integer: windowStyle = 1

    wsh.Run myApp, windowStyle, waitOnReturn

End Sub

(我不得不简化您的 wsh.Run 行,因为它不起作用,我怀疑您添加的 256 个引号没有任何好处)

【讨论】:

  • 感谢您的回答。可悲的是,这两个版本都不适合我。使用第一种方法我得到 error429 ActiveX 组件无法创建对象。第二种方法导致对象 iwshshell3 的错误方法运行失败。
【解决方案2】:

您是否确认该路径将您直接带到解释器?

试试这个,

Dim myApp As String: myApp = "C:\""Program Files (x86)""\Python27\python.exe C:\Users\Markus\BrowseDirectory.py"

【讨论】:

  • 是的,路径本身是正确的。问题是路径中的空格。遗憾的是,您的解决方案对我不起作用。
  • 嗯,应该的。这是另一种方法,"C:\" & chr(34) & "Program Files (x86)" & chr(34) & "\Python27\python.exe C:\Users\Markus\BrowseDirectory.py" 这行得通吗?
  • 另外,wsh.Run myApp, windowStyle, waitOnReturn 我的更改就足够了
【解决方案3】:

我的脚本适用于我的工作表和 Python(但我将工作表和 py 脚本放在同一个文件夹中):

Path = ActiveWorkbook.Path
Pth = """" & Path & "\pythonscript_name.py" & """"
Ph = """" & "C:\Python27\python.exe " & Pth & """"

Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
ErrorCode = wsh.Run(Ph, windowStyle, waitOnReturn)

【讨论】:

    【解决方案4】:

    我不知道这是否可以解决您的问题,但我在尝试使用 CX-Freeze(来自 VBA 和 wsh)启动“冻结”的 python 脚本时遇到了同样的问题。一切正常,直到我将 EXE 文件的文件夹名称更改为带空格的名称。直到我读了你的帖子和你提到的空格,我才明白这个问题。

    我在互联网上找到了一个函数(可能在 SO 上,我不记得了),它为我提供了 DOS 中文件夹的名称。如果像我一样,您必须传递一些文件夹名称的参数,然后重用该函数来为您提供 DOS 中的名称。

    这是在网上找到的函数:

    Public Function GetShortFileName(ByVal FullPath As String) As String
    
    'PURPOSE: Returns DOS File Name (8.3 Format) Give
    'FullPath for long file name
    
    'PARAMETERS: FullPath: Full Path of Original File
    
    'RETURNS: 8.3 FileName, or "" if FullPath doesn't
    '         exist or file fails for other reasons
    
    'EXAMPLE:
    '  GetShortFileName("C:\Nouveau dossier\Nouveau dossier\Nouveau 
    dossier\Nouveau dossier\Nouveau dossier\")
    
    
    Dim lAns As Long
    Dim sAns As String
    Dim iLen As Integer
    
    On Error Resume Next
    
    'this function doesn't work if the file doesn't exist
    If Dir(FullPath) = "" Then Exit Function
    
    sAns = Space(255)
    lAns = GetShortPathName(FullPath, sAns, 255)
    GetShortFileName = Left(sAns, lAns)
    
    End Function
    

    以下是您制作子的方法:

    Dim wsh As Object
    Set wsh = VBA.CreateObject("WScript.Shell")
    Dim waitOnReturn As Boolean: waitOnReturn = True
    Dim windowStyle As Integer: windowStyle = 1
    Dim program_folder_path
    Dim file_path
    
    program_folder_path = "C:\Program Files (x86)\Python27\"
    program_folder_path = CStr(GetShortFileName(program_folder_path))
    
    file_path = "C:\Users\Markus\BrowseDirectory.py"
    file_path = CStr(GetShortFileName(file_path))
    
    wsh.Run program_folder_path & "python.exe" & file_path, windowStyle,_
    waitOnReturn
    

    我希望这可以帮助,顺便说一句对不起我的英语不好......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-29
      • 1970-01-01
      • 2021-04-23
      • 2012-10-19
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多