【问题标题】:Capture values returned by Python into a VBA Script将 Python 返回的值捕获到 VBA 脚本中
【发布时间】:2021-07-09 23:52:00
【问题描述】:

我的 vba 上有这段代码:

Sub RunPythonScript()

Dim objShell As Object
Dim PythonExe, PythonScript As String

Set objShell = VBA.CreateObject("Wscript.Shell")

PythonExe = """C:\Program Files\Python37\python.exe"""
PythonScriptPath = "C:\Users\pma\PycharmProjects\XRef\testing.py"

objShell.Run PythonExe & PythonScript

End Sub

我的 python 脚本返回一个数据框:

return df

如何在我的 VBA 中捕获它?我想玩弄返回的数据框

【问题讨论】:

  • stackoverflow.com/questions/39516875/… 展示了如何从StdOut 读取数据,但这无助于您传递数据帧。我不是 Python 用户,但我怀疑数据框在 VBA 环境中不可用。
  • 您正在运行两个独立的程序。您可以通过在 python 中打印并从 VBA 读取来传递数据。其他替代方法是打印到文件并从文件中读取或写入套接字并从中读取。

标签: python vba


【解决方案1】:

选项包括通过剪贴板或文件传输数据,正如@cup 建议的那样:

VBA 部分(带有选项选择):

Sub RunPythonScriptByFileOrClip()
    Dim objShell As Object
    Dim PythonExe As String, PythonScriptPath As String, Opt As String
    
    Set objShell = VBA.CreateObject("Wscript.Shell")
    
    PythonExe = """C:\Program Files\Python37\python.exe"""
    PythonScriptPath = "C:\Users\pma\PycharmProjects\XRef\testing.py"
    Filename = "C:\test\df.xlsx"
    Opt = "-byclip" ' or "" for byfile
    
    If Opt = "-byclip" Then
        objShell.Run Join(Array(PythonExe, PythonScriptPath, Opt), " "), 0, True  'Run(<Command>,<WindowStyle>,<WaitOnReturn>)
        ' create a new worksheet in ThisWorkbook for paste df
        On Error Resume Next
        Application.DisplayAlerts = False
        ThisWorkbook.Sheets("df").Delete    'delete old df sheet
        On Error GoTo 0
        Application.DisplayAlerts = True
        Set ws = ThisWorkbook.Worksheets.Add
        ws.Name = "df"
        ws.Paste ws.Range("A1")
        Set df = ws.UsedRange
    Else  ' via file
        objShell.Run Join(Array(PythonExe, PythonScriptPath, Filename), " "), 0, True  'Run(<Command>,<WindowStyle>,<WaitOnReturn>)
        Set wb = Workbooks.Open(Filename)
        Set df = wb.Sheets(1).UsedRange
    End If
    ' process the data in any way
    For Each cl In df
        Debug.Print cl.Text
    Next
End Sub

Python部分:

import pandas as pd
import sys

df = pd.DataFrame({'column1': [1, 3, 4, 5], 'column2': [9, 8, 7, 6]})
if len(sys.argv) == 2:
    if sys.argv[1] == '-byclip':
        df.to_clipboard()
    else:
        df.to_excel(sys.argv[1])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 2012-08-07
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多