I have tried several solutions to run python script out of VBA.
My current solution that still doesnt work
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim windowStyle As Integer: windowStyle = 1
Dim waitOnReturn As Boolean: waitOnReturn = True
wsh.Run "C:\Python33\python.exe C:\Users\***\Documents\Promo models\get_sku_data.py", windowStyle, waitOnReturn
Any ideas?
xlwings claims to make python from excel very easy:
Sub RandomNumbers()
RunPython ("import mymodule; mymodule.rand_numbers()")
End Sub
To make this run, just import the VBA module xlwings.bas in the VBA editor (Open the VBA editor with Alt-F11, then go to File > Import File... and import the xlwings.bas file. ). It can be found in the directory of your xlwings installation.
Finally I ended up with creation of .exe files instead of trying to call scripts itself.
So, I applied cx_Freeze, created .exe files and then called them as
Script_path1 = "C:\Users\" + Environ("Username") & "\Documents\Promo_models\get_sku_data\gui_changed.exe"
wsh.Run Script_path1, windowStyle, waitOnReturn
Here are a couple options to try.
RetVal = Shell("<full path to python.exe> " & "<full path to your python script>")
Or if the python script is in the same folder as the workbook, then you can try :
RetVal = Shell("<full path to python.exe> " & "ActiveWorkBook.Path & \<python script name>")
Related
Running the following snippet yields "System.IO.FileNotFoundException: File not found"
Sub Main()
Dim scriptPath As String = "D:\Programs\Tester.py"
Dim pythonPath As String = "D:\anaconda3\python.exe"
If IO.File.Exists(scriptPath) Then
Shell(pythonPath + " " + scriptPath)
End If
End Sub
I am at a loss as to why this happens, because there is no problem in finding the file for the If-statement, however, as soon as it has to get executed it "does not exist". My original code featured a python script running as a process (as below), however, for some reason this stopped working: it runs without any errors, the script just doesn't get executed. The paths are copied from each file's "Properties" so I know they are still correct.
...
Dim scriptPath As String = "D:\Programs\Tester.py"
Dim pythonExePath As String = "D:\anaconda3\python.exe"
Dim gzipProcess As New Process()
Dim gzipStartInfo As New ProcessStartInfo(pythonExePath, scriptPath)
gzipStartInfo.UseShellExecute = False
gzipProcess.StartInfo.CreateNoWindow = True
gzipProcess.StartInfo = gzipStartInfo
gzipProcess.Start()
...
If I manually open a shell I can simply run the script as "python scriptPath" and it executes normally.
Any suggestions on how to fix this?
I'm trying to call two Python UDFs in excel via xlwings, i saw the following error message:
Make sure that this workbook contains the xlwings module and you are trusting access to the VBA project object module(Options).
Macro setting is already enabled, the workbook also referenced to xlwings. The xlwings version in Anaconda is 0.20.0, i think this is the latest version, but i can only see "import Python UDFs" button under xlwings Add-in settings, nothing else, which is different from the Add-in settings i saw in some videos. I'm using Jupyter Notebook, my python code is saved in "M:\SolverFunction.ipynb". I also saved the code in .py extension with the same name in the same directory, not sure if i can just use .ipynb extension directly. Below is my function settings in VBA, can someone please check if everything is correct:
PYTHON_WIN = "C:\Program Files\Anaconda3\pythonw.exe"
PYTHON_MAC = ""
PYTHON_FROZEN = ThisWorkbook.Path & "\build\exe.win32-2.7"
PYTHONPATH = "M:\"
UDF_MODULES = "SolverFunction"
UDF_DEBUG_SERVER = False
LOG_FILE = ""
SHOW_LOG = True
OPTIMIZED_CONNECTION = False
when i run the macro Run_Python_Function, it shows SyntaxError:
Syntax Error in Macro
I need to call two python UDFs,don't really know how to fix this error, there is no error in the python code itself.
Another question: in the python code i use 'xw.Book' to call the existing sheet
wb = xw.Book(r'M:\SolverFunction.xlsm')
If the sheet is saved in another directory with another name, say "C:\Desktop\DVA Totem Submission\xyz.xlsm", except modifying the code
wb = xw.Book(r'C:\Desktop\DVA Totem Submission\xyz.xlsm')
do i need to change the function settings in VBA as well?
Thanks,
I am using Python and the win32com.client library to run a VBA macro. The macro requires a directory (which is a substring of the .xlsm path itself). How do I pass this directory/string to the VBA popup?
import os, os.path
import win32com.client
if os.path.exists('C:/test_folder/excel_file.xlsm'):
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open('C:/test_folder/excel_file.xlsm', ReadOnly=1)
xl.Application.Run('excel_file.xlsm!Sheet1.Macro1')
After this code is run, the folder explorer window pops up asking for a directory. How would I pass the directory to Excel?
This line of code will help you save the exact directory you want making it non dependent to the python path, and associates it to a variable, after that you can just pass on that string variable onto your vba popup. You can try making it global or just reusing it on the continuation of the code, after that you can just reference so you can put it in excel. I hope this helps.
Sub Selectingadirectory()
Dim fd As FileDialog
Dim ActionClicked As Boolean
Dim SelectedFolderPath As String
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
fd.title = "Chose your directory path"
fd.InitialFileName = Environ("UserProfile") & "\Desktop"
fd.AllowMultiSelect = False
ActionClicked = fd.Show
If ActionClicked Then
SelectedFolderPath = fd.SelectedItems(1)
Else
Msgbox "You didnt chose a folder"
Exit Sub
End If
End sub
EDIT: I made an error when posting below in saying that it worked when running from terminal (I must have tested earlier.) This problem was solved by using the python.exe program in the environment (env) folder pycharm installed instead of the stand alone installation I made originally.
EDIT #2: The problem is persisting again without having changed any of the VBA or python script. (still using the pycharm environment folder python.exe)
I have a VBA sub that creates a WScript.Shell object and then executes a python script which was working fine for the last few weeks. After continuing to build on the code in the python script (salesHist.py) the python script no longer runs correctly and produces an exit code "1". When running the script through pyCharm or console the script fully executes correctly with exit code 0.
I've tried some different variations of the code which are included below. Directories for python.exe and salesHist.py are both correct and do not contain any spaces (which I know is a common error.)
Also references added:
Visual Basic for Applications,
Microsoft Excel 16.0 Object Library,
OLE Automation,
Microsoft Office 16.0 Object Library,
Microsoft HTML Object Library,
Microsoft Scripting Runtime,
Microsoft XML, v3.0,
Windows Script Host Object Model
Sub RunPythonScript(pyScript As String)
'Declare varables
Dim objShell As Object
Dim PythonExe, PythonScript As String
Dim waitOnReturn As Boolean, windowStyle As Integer, retVal As Long
waitOnReturn = True
windowStyle = 0
'Create new object shell
Set objShell = VBA.CreateObject("WScript.Shell")
'Tried Set objShell CreateObject("WScript.Shell")
'Provide the file path to the Python Exe
PythonExe = "C:\Users\steve.levy\AppData\Local\Programs\Python\Python37-32\python.exe"
'PC1: C:\Users\Steven\AppData\Local\Programs\Python\Python37-32\python.exe
'PC2: C:\Users\steve.levy\AppData\Local\Programs\Python\Python37-32\python.exe
'make sure you use triple quotes if there is a space in the file path name. single quotes are ok if not
'Procide the file path to the Python Script
PythonScript = "C:\Users\steve.levy\Documents\elberon\api\" & pyScript
'PC1: C:\Users\Steven\Documents\api\
'PC2: C:\Users\steve.levy\Documents\elberon\api\
Debug.Print (PythonExe)
Debug.Print (PythonScript)
'Run the Python Script
'Tried: Call objShell.Run(PythonExe & " " & PythonScript, 0, True)
'Tried: retVal = objShell.Run(PythonExe & " " & PythonScript, 0, True)
retVal = objShell.Run("C:\Users\steve.levy\AppData\Local\Programs\Python\Python37-32\python.exe C:\Users\steve.levy\Documents\elberon\api\salesHist.py", 0, True)
If retVal = 0 Then
'Do Nothing
Else
MsgBox "Script could not run. Program exited with error code " & retVal & "."
End If
End Sub
Sub pyscr()
Call executePython.RunPythonScript("salesHist.py")
End Sub
Program exists and message box appears:
"Script could not run. Program exited with error code 1."
I'm trying to run a VBA module that uses a shell script to run an ipython notebook (using runipy) before going on to do other things, but my ipython notebook script requires inputs, which are setup using environment variables.
Here's the VBA I have so far:
rundate = Range("b1").Value
shellScript = "runipy C:\argstest.ipynb"
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Set wshSystemEnv = wsh.Environment("SYSTEM")
wshSystemEnv("CURRWK") = rundate
If I then run:
MsgBox (wshSystemEnv("CURRWK"))
The result is correct:
2015-04-17
However, if I continue on and exec my shellscript, it isn't recognizing this variable
Set WshShellExec = wsh.exec(shellScript)
Range("a1").Value = WshShellExec.StdErr.ReadAll
shows me that when python runs it gets a key error:
KeyError: 'CURRWK'
If I remove the VBA and run this straight from the command line, I would do it like this:
set CURRWK=2015-04-17
runipy C:\Python27\Programs\ipython\ACT\argstest.ipynb
How do I get the shell created in the VBA to create the new environment variable so the python script can see it when it executes?
Thanks!
Have you tried Process instead of SYSTEM? Your VBA may not have the rights to modify the system-level variables. ("But it can read it back after setting it," you say. True, but your script may have registry virtualization enabled.) Process most closely emulates the command line SET statement in that the change is only for the current process and child processes and is not persisted.