0

Python code does not run after executing. The code has to read the data frames from the Excel where I run VBA code to execute the python code. Im not sure this could be a reason since I have another totally different excel where I do exactly same running VBA code in excel file to run a python code, which reads the data in this excel file. I get the finished msgbox in less then a second but if I run a code in Pycharm it takes 2 min to finish.

Option Explicit
Sub RunPythonScript()

'Declare Variables
Dim objShell As Object
Dim PythonExe, PythonScript As String

'Create a new Object shell.
Set objShell = VBA.CreateObject("Wscript.Shell")

'Provide file path to Python.exe
'USE TRIPLE QUOTES WHEN FILE PATH CONTAINS SPACES.
PythonExe = """C:\Users\gobro7\AppData\Local\Programs\Python\Python39\python.exe"""
PythonScript = "C:\Users\gobro7\Wholesale - Documents\Report\VL.py"

'Run the Python Script
objShell.Run PythonExe & PythonScript

MsgBox "Finished"

End Sub

Path in python script

import pandas as pd
import numpy as np
import os

# Get the user
username = os.getlogin()

# search for directory
directory = r'C:/Users/' + username + '/Wholesale - Documents/Report/'
Greencolor
  • 501
  • 1
  • 5
  • 16
  • I think you need to add space between `PythonExe` and `PythonScript`. Having space in the path may also cause problem if not enclosed in quotes. Also you don't supply optional parameter to `bWaitOnReturn`, so it will return immediately. – buran Feb 08 '22 at 20:15
  • Could you explain the last part/ how to add it in my code so it will display msgbox after python script is done ? Im beginner in VBA sorry – Greencolor Feb 08 '22 at 20:21
  • Check https://stackoverflow.com/q/8902022/4046632 – buran Feb 08 '22 at 20:22
  • At which line should I add the space between pythonexe and pythonscript? – Greencolor Feb 08 '22 at 20:23
  • This is also good reference http://www.cpearson.com/excel/ShellAndWait.aspx – buran Feb 08 '22 at 20:23
  • when you concatenate the 2 strings there is no space between them. you can add space at the end of the first or the start of the second string. Also Enclose the second string in double quotes. You do it for the first one where not necessary, but not for the second one – buran Feb 08 '22 at 20:24
  • Im so sorry but I really dont get what you are reffering to. Would you mind to answer it with the code? – Greencolor Feb 08 '22 at 20:30

1 Answers1

2

Basically, try

PythonExe = """C:\Users\gobro7\AppData\Local\Programs\Python\Python39\python.exe """
PythonScript = """C:\Users\gobro7\Wholesale - Documents\Report\VL.py"""

'Run the Python Script
objShell.Run PythonExe & PythonScript, 0, True

Note the space at the end of PythonExe as well the triple double-quotes around PythonScript. The 0 will keep the shell window hidden, True will wait for the job to return.

EDIT: Today I was able to test on Windows/Excel. So I created a python script:

import pandas as pd
import time

print('start', str(time.time()))
df = pd.read_excel('Book1.xlsm')
print(df)
time.sleep(10) # just to waste some time like long running operation
print('end', str(time.time()))

and Excel file Book1.xlsm with following macro

Sub RunPythonScript()

'Declare Variables
Dim objShell As Object
Dim PythonExe, PythonScript, cmd As String

'Create a new Object shell.
Set objShell = VBA.CreateObject("Wscript.Shell")

'Provide file path to Python.exe
'USE TRIPLE QUOTES WHEN FILE PATH CONTAINS SPACES.
PythonExe = "C:\Users\SomeRealUser\sandbox\sbox\Scripts\python.exe "
PythonScript = """C:\Users\SomeRealUser\sandbox\py script\mypy.py"""
cmd = PythonExe & PythonScript
Debug.Print cmd
'Run the Python Script
objShell.Run cmd, 1, True

MsgBox "Finished"

End Sub

and some dummy data in Sheet1 and it worked as expected when I run RunPythonScript() macro.

Note:

  1. I use virtual environment named sbox to run the python, with pandas installed - it shouldn't matter or make difference as long as the path is correct and all dependencies are installed.
  2. SomeRealUser is replacement for my real user
  3. In objShell.Run cmd, 1, True I pass as second argument 1 to observe the terminal that is opened, but it works just fine with 0 (i.e. hidden terminal window)
  4. The path to file deliberately has space to mimic your conditions.
  5. All that said - in my opinion there are better ways to accomplish the task of runninf python code or even run the python script with Shell.run (see the link I shared to CPearson)
buran
  • 13,682
  • 10
  • 36
  • 61
  • 1
    If you find that the imports are not picking up, you may need to set up PYTHONPATH or add the path of the scripts to PATH. – cup Feb 08 '22 at 20:49
  • no, its still finishing in 1 sec. I modified data to see the result but there is no change. Python code is not executing – Greencolor Feb 08 '22 at 20:50
  • @cup how can i find if imports are picking it up? – Greencolor Feb 08 '22 at 20:54
  • If the python script runs in pycharm, there shouldn't be problem with the imports. Try with reading from excel file that is closed. – buran Feb 08 '22 at 20:56
  • Did you use the triple quotes for the python executable? You have single quotes in the original posted question even though your comment says use triple quotes – cup Feb 08 '22 at 21:38
  • Today I was able to test on Windows/Excel and it works just fine (see my edited answer). So, I really don't see what else we can help without more information. One thing I can suggest is to have a look at `xlwings` that allows to run python from excel and/or rethink your workflow from the start. – buran Feb 09 '22 at 09:33
  • Thanks for your help. Today I tried to to run it from different file and to close the main one but still same, it gives me msgbox in a second, and does not work. Not sure what Im doing wrong. Maybe the Path part – Greencolor Feb 09 '22 at 12:59
  • The script above works on open excel file from which I run the macro. – buran Feb 09 '22 at 13:04
  • Yes, but supper strange why mine is not working – Greencolor Feb 09 '22 at 13:08
  • One thing that comes to my mind - in the script how do you specify the path to file? i.e. is it absolute path or relative one? Note that if it is relative one, it is relative to your current working directory, not the python script or excel file path. – buran Feb 09 '22 at 13:12
  • python script or vba ? – Greencolor Feb 09 '22 at 13:18
  • In the python script. in the VBA macro there is no path to the excel file, right – buran Feb 09 '22 at 13:19
  • I have added the path from python script you can check in the original one. I had the VBA script with Dim user As String user = Environ("username") – Greencolor Feb 09 '22 at 13:36
  • but I changed it after as I thought it had a problem to find the user – Greencolor Feb 09 '22 at 13:36
  • Final suggestion - add Debug.Print like I did in my sample VBA. Get the exact command you pass to objShell. Open cmd and paste the command (without changing current working directory or anything). Run it and see if it execute the script as expected. You can add some debug prints in the python script as well in order to see that it really works. I bet there is some problem, probably path problem and there will be some traceback or it will not be able to find the excel file. – buran Feb 09 '22 at 13:44
  • Thanks, I just have copied the pythonscript path and tried to run it from cmd, and i got this error `FileNotFoundError: [Errno 2] No such file or directory: 'Run_report.xlsm'` . Run_report.xlsm is the file from where I run the VBA code. What could be the problem? VL.py file is in the same directory as Run_report.xlsm – Greencolor Feb 09 '22 at 15:28
  • apparently Python code is running but it stops when it reaches the line `df_1 = pd.read_excel('Run_report.xlsm', sheet_name= "weekly",header= None)`. As I mentioned above `Run_report.xlsm` is from where I run the VBA code and also python code is reading the same file to do some data manipulations – Greencolor Feb 09 '22 at 15:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241870/discussion-between-greencolor-and-buran). – Greencolor Feb 09 '22 at 15:32
  • The arguments , 0, True were exactly what was missing for me. It perfectly works and I just replaced the 0 (hide) by 1 (show) to see the Python execution, i.e. : ,1, True Thank you for such an easy solution (I was a bit afraid with all the others). – tibibou Aug 21 '23 at 19:29