It may be more convenient to run a Python script from the AWR Design Environment (AWRDE) rather than an integrated design environment (IDE). The AWRDE scripting environment allows the ability to execute other applications using the Windows Shell object. WScript is the interface VBA uses to access the Windows Shell object. Python.exe is one example of an application that VBA can access through Window Shell.
Running Python using the Windows Shell method is very similar to accessing Python using a command line through either a WIndows command window or Powershell. Using command line, arguments to Python are passed as parameters in the command line itself. Returns from the Python script are print statements to standard output (StdOut) which is the command or Powershell windows. From this perspective, interfacing to Python from the AWRDE VBA environment requires that pass parameters are part of the Python command line instruction and returns from the Python script entail reading the StdOut print statements that the Python script generates.
Example 1: Python script with no pass parameters
This simple example requires no pass parameters to the Python script, nor are there any returns from the Python script to be read back. The VBA code to launch a Python script called msg_box.py is show here:
' Code Module Sub Main Dim oShell, oExec As Object Dim DirPath As String Dim Dir_n_File As String Dim Exec_cmd As String Debug.Clear ' DirPath = "C:\PythonDirectory\" 'Directory where python script exists Dir_n_File = DirPath & "msg_box.py" 'concatenate python script Exec_cmd = "py " & Dir_n_File 'concatenate py with the scripts director and file name. py is a shortcut to Python.exe ' Set oShell = CreateObject("WScript.Shell") 'set shell object Set oExec = oShell.Exec(Exec_cmd) 'execute shell object ' Do While oExec.Status = 0 'loop until python script is complete Wait(1) Loop ' End Sub
The Python script is shown here:
#msg_box.py from tkinter import messagebox #import tkinter module (part of standard Python install) messagebox.showinfo("Message", "Python script launched from VBA script") #Open a message dialog box
Running the VBA script generates a message box:
Example 2: Python script with pass parameters
This example passes two complex numbers to Python with options for add, subtract, multiply or divide. Arguments passed to a Python script must be string type, so first the numbers must be converted to strings. Complex numbers cannot be passed to the Python script, so the real and imaginary parts are passed individually.
' Code Module Sub Main Dim oShell, oExec As Object Dim Return_str As String Dim arg As String Dim DirPath As String Dim Dir_n_File As String Dim Exec_cmd As String Dim arg1, arg2 As String Debug.Clear ' a_real = 1 'Real part of a a_imag = 3 'Imaginary part of a b_real = 4 'Real part of b b_imag = 7 'Imaginary part of b operation = "add" 'add | subtract | multiply | divide ' arg = Str(a_real) & " " & Str(a_imag) & " " & Str(b_real) & " " & Str(b_imag) & " " & operation 'argument for the Python command line ' DirPath = "C:\PythonDirectory\" 'Directory where python script exists Dir_n_File = DirPath & "complex_math.py" 'concatenate python script Exec_cmd = "py " & Dir_n_File & " " & arg 'concatenate py with the scripts director and file name and argument. py is a shortcut to Python.exe ' Set oShell = CreateObject("WScript.Shell") 'set shell object Set oExec = oShell.Exec(Exec_cmd) 'execute shell object ' Do While Not oExec.StdOut.AtEndOfStream 'read back print statement from python script Return_str = oExec.StdOut.ReadLine Debug.Print Return_str Loop ' Do While oExec.Status = 0 'loop until python script is complete Wait(0.1) Loop End Sub
The complex_math.py script is shown here
#complex_math.py import sys def main(argv):#-------------------------------------------------------- try: a_real = float(argv[1]) #Real part of a a_imag = float(argv[2]) #Imaginary part of a b_real = float(argv[3]) #Real part of b b_imag = float(argv[4]) #Imaginary part of b operation_str = argv[5] except: print('Invalid arguments') #end try a = complex(a_real, a_imag) #create complex variable for a b = complex(b_real, b_imag) #create complex variable for b # if operation_str == 'add': #complex math operation c = a + b elif operation_str == 'subtract': c = a - b elif operation_str == 'multiply': c = a * b elif operation_str == 'divide': c = a / b else: print('Invalid operation parameter') sys.exit() #end if print(c.real, c.imag) #Print the resulting real and imaginary parts # if __name__ == '__main__':#--------------------------------------------- main(sys.argv) #end if
A function main must be defined. Arguments are in the form of a list with index 0 being the title of the Python script and the next indices being the passed parameters. The results of the complex math are printed out and in the VBA script, the printed results are read in.
Example 3: Suppressing Command Window
Running Python scripts without pass parameters or the need to read Python script print statements, that is to only launch the Python script, an alternate shell method to the .Exec method is the .Run. The advantage of the .Run method is that the Windows command window can be suppressed. Here is an example of running the msg_box.py script with the command window supressed:
' Code Module Sub Main Dim oShell As Object Dim DirPath As String Dim Dir_n_File As String Dim Run_cmd As String Debug.Clear ' DirPath = "C:\PythonDirectory\" 'Directory where python script exists Dir_n_File = DirPath & "msg_box.py" 'concatenate python script Run_cmd = "py " & Dir_n_File 'concatenate py with the scripts director and file name. py is a shortcut to Python.exe ' Set oShell = CreateObject("WScript.Shell") 'set shell object oShell.Run(Run_cmd, 0, True) 'run shell object. Parameter 0 is for command window suppression. True parameters tells the VBA ' script to wait for the Python script to complete End Sub