1

I have this code on my 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

My python script returns a dataframe:

return df

How do I capture this in my VBA? I want to play around with the returned data frame

2
  • stackoverflow.com/questions/39516875/… shows how to read from StdOut, but this would not help you pass a dataframe. I'm not a Python user but I suspect a dataframe would not be usable within a VBA environment. Commented Jul 7, 2021 at 20:40
  • You are running two separate programs. You can pass the data by printing in python and reading from VBA. Other alternatives are printing to and reading from a file or writing to a socket and reading from it. Commented Jul 7, 2021 at 22:01

1 Answer 1

1

Options include transferring data via the clipboard or via a file, as @cup suggested:

VBA part (with option selection):

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 part:

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])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.