Trying to call a python script on Vba and I am a newb. I tried converting the main script to an exe using py2exe and then calling it from VBA (shell) but the main script calls other scripts therefore it becomes complicated and I messed it up (my exe is not functional). Besides, the the main script is a large file and I do not want to revise it a lot.
Bottomline, is there a way to call the main script from excel vba, without converting the script to an exe file.
So far, I tried:
RetVal = Shell("C:\python27\python.exe " & "import " & "C:\\" & "MainScriptFile")
It starts python.exe but does nothing else. Then I tried:
RetVal = Shell("C:\Windows\System32\cmd.exe " & "python " & "C:\\Python27\\hello.py")
It starts command prompt but does not even start python.
P.S. I checked all the related questions in the forum, they do not solve my prob.
Try this:
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>")
All details within <> are to be given. <> - indicates changeable fields
I guess this should work. But then again, if your script is going to call other files which are in different folders, it can cause errors unless your script has properly handled it. Hope it helps.
I just came across this old post. Nothing listed above actually worked for me. I tested the script below, and it worked fine on my system. Sharing here, for the benefit of others who come to this spot after me.
Sub RunPython()
Dim objShell As Object
Dim PythonExe, PythonScript As String
Set objShell = VBA.CreateObject("Wscript.Shell")
PythonExe = """C:\your_path\Python\Python38\python.exe"""
PythonScript = "C:\your_path\from_vba.py"
objShell.Run PythonExe & PythonScript
End Sub
There are a couple of ways to solve this problem
Pyinx - a pretty lightweight tool that allows you to call Python from withing the excel process space
http://code.google.com/p/pyinex/
I've used this one a few years ago (back when it was being actively developed) and it worked quite well
If you don't mind paying, this looks pretty good
https://datanitro.com/product.html
I've never used it though
Though if you are already writting in Python, maybe you could drop excel entirely and do everything in pure python? It's a lot easier to maintain one code base (python) rather than 2 (python + whatever excel overlay you have).
If you really have to output your data into excel there are even some pretty good tools for that in Python. If that may work better let me know and I'll get the links.
To those who are stuck wondering why a window flashes and goes away without doing anything the python script is meant to do after calling the shell command from VBA:
In my program
Sub runpython()
Dim Ret_Val
args = """F:\my folder\helloworld.py"""
Ret_Val = Shell("C:\Users\username\AppData\Local\Programs\Python\Python36\python.exe " & " " & args, vbNormalFocus)
If Ret_Val = 0 Then
MsgBox "Couldn't run python script!", vbOKOnly
End If
End Sub
In the line args = """F:\my folder\helloworld.py""", I had to use triple quotes for this to work. If I use just regular quotes like: args = "F:\my folder\helloworld.py" the program would not work. The reason for this is that there is a space in the path (my folder). If there is a space in the path, in VBA, you need to use triple quotes.
This code will works:
your_path= ActiveWorkbook.Path & "\your_python_file.py"
Shell "RunDll32.Exe Url.Dll,FileProtocolHandler " & your_path, vbNormalFocus
ActiveWorkbook.Path return the current directory of the workbook. The shell command open the file through the shell of Windows.
You can also try ExcelPython which allows you to manipulate Python object and call code from VBA.
Try this:
retVal = Shell("python.exe <full path to your python script>", vbNormalFocus)
replace <full path to your python script> with the full path
To those who are stuck wondering why a window flashes and goes away without doing anything, the problem may related to the RELATIVE path in your Python script. e.g. you used ".\". Even the Python script and Excel Workbook is in the same directory, the Current Directory may still be different. If you don't want to modify your code to change it to an absolute path. Just change your current Excel directory before you run the python script by:
ChDir ActiveWorkbook.Path
I'm just giving a example here. If the flash do appear, one of the first issues to check is the Current Working Directory.
ChDir "" was the solution for me. I use vba from WORD to launch a python3 script.
In my case, as I have my script in a different directory than my ms access document and, in that script I import variables from other scripts, I had to change the directory first. Then I can use correctly the shell function.
ChDir "C:\Users\directory_where_the_script_is"
Call Shell("C:\Users\...\python.exe " & "your_script_name.py", 1)
for me this not working
RetVal = Shell(" " & ActiveWorkBook.Path & "<python script name>")
for me this :
RetVal = Shell("python3" & " " & "C:\a\b\c\xyz.py")
I think above answers have a catastrophic problem:
after running the macro,cmd window would close automatically, instantly. In case output is not as expected you would have absolutely zero debug information.
Finally I found a better way in which case, cmd window remains open and shows all the information (print of python) and error log.
code as below:
Sub RunPythonScript()
cwd = ActiveWorkbook.Path 'current working directory
workbookName = ActiveWorkbook.Name
pythonScriptName = "main.py"
workbookNameWithPath = cwd & "\" & workbookName
pythonScriptNameWithPath = cwd & "\" & pythonScriptName
pythonExePath = "C:\Users\USERNAME\AppData\Local\Programs\Python\Python39\python.exe" ' change path as output of "where python"
Shell "cmd.exe /k """"" & pythonExePath & """ """ & pythonScriptNameWithPath & """""", vbNormalFocus
End Sub
Related
I am creating a code editor, and I am trying to create a run feature. Right now I see that the problems come when I encounter a folder with a space in its name. It works on the command line, but not with os.system().
def run(event):
if open_status_name != False:
directory_split = open_status_name.split("/")
for directory in directory_split:
if directory_split.index(directory) > 2:
true_directory = directory.replace(" ", "\s")
print(true_directory)
data = os.system("cd " + directory.replace(" ", "\s"))
print(data)
I tried to replace the space with the regex character "\s" but that also didn't work.
os.system runs the command in a shell. You'd have to add quotes to get the value though: os.system(f'cd "{directory}"'). But the cd would only be valid for that subshell for the brief time it exists - it would not change the directory of your python program. Use os.chdir(directory) instead.
Note - os.chdir can be risky as any relative paths you have in your code suddenly become invalid once you've done that. It may be better to manage your editor's "current path" on your own.
I have read all online questions on this problem and none of them seem to be working for me. I want to write a code in VBA such that when a button is pressed, my code in Python automatically starts running.
I am getting a file not found error when I run the code but I have checked the path and I know it is correct.
The code I am trying is:
Sub MyMacro()
Shell("C:/Users/RGilsburg/New folder/pythonw.exe" & "F:/Asset/Global/Port/untitled1.py")
End Sub
Can anyone tell me where the error is?
The shell command should work, however, you have some issues with the command to be executed:
You need to put a blank between the Python command and the python file.
Use the backslash, not the slash if you are on windows
If a file contains a blank, you have to put it in Double quotes ". When you want to have a quote character in a string in VBA, you have to double it.
Basically, the parameter to Shell should be the same as you would enter it on a command prompt. To check this, write the command into a string variable and write this to the immediate window (Ctrl+G). Copy it from there and paste it into a CMD-window.
Try
Dim python as string, script as string, cmd As String
python = """C:\Users\RGilsburg\New folder\pythonw.exe"""
script = "F:\Asset\Global\Port\untitled1.py"
cmd = python & " " & script
Debug.print cmd
Shell cmd
this may be a bit ignorant of me since i know nothing of python and little of vba but did you add python as a reference in the vba editor.
if not
go to the tools dropdown in the vba editor select references and see if you can find python.
I am trying to build a program that mimics the 'run' feature of Windows in a Windows environment. Now I know that sounds a bit silly, but we are on 'limited' computers, and the cmd is completely locked so we don't have any choice but to build our own program files for our needs.
Specifically, what I am trying to do is a little utility that will ask for the drive, subject, and course number, and based on that open the full path.
i.e. W Python 47 -> w://courses/subjects/python/classes/47 - Arrays & Pointers
I have done most of the work in Python and reached the last stage where I need to get the full path based only on the number with the code being something like:
os.system(start 'drive + '://courses/subjects/' + subject + '/classes/' + class')
Where drive, subject, and class are variables that hold the data of the current path.
The problem is that when there is a space in the file path, Windows can't find it, and produces an error.
The simple solution would be to put double quotes, but for some reason double quotes on the start command is considered as a cmd command which is blocked..
Any ideas on a workaround, or maybe Python is not the way to go, and so any ideas on a different language, that would be easier. (I have basic knowledge in C++, Python, Java)
p.s. This is not the exact code, that I am using, I will post that tomorrow.
The first argument after start is the name of the newly created command prompt window, and the second and third should be the path to the application and its parameters, respectively.
start "" "c:\path with spaces\app.exe" param1 "param with spaces"
If you want to use os.system, you could try:
norm_path = os.path.normpath("{0}://courses/subjects/{1}/classes/{2}".format (drive, subject, class_name))
os.system('start "" "' + norm_path + '"')
But I would probably use os.startfile:
norm_path = os.path.normpath("{0}://courses/subjects/{1}/classes/{2}".format (drive, subject, class_name))
os.startfile( norm_path )
Please note: you should not use a variable named class.
I've got a problem with some VB scripting - it doesn't seem like it should be terribly difficult to solve, but even after trudging through many a page of Google I have yet to find a solution.
[The problem]
Here is my python file (test.py), simplified to just show the problem:
f = open("testing.txt", 'w')
f.write("oh hai\n")
f.close()
Of course, when run directly from the command line, this generates the file as you'd expect.
However, when run in a simple .vbs script (WARNING: My vbs skills are lacking. This is probably why I am having a problem. So far I haven't had many issues, apart from hating life from using XP to code when I'm used to using vim)
Set WshShell = WScript.CreateObject("WScript.Shell")
cmd = "C:\Python27\python test.py"
WshShell.Run cmd
no output file is generated! At all! It's infuriating, as when I input that exact command ("C:\Python27\python test.py") into the run program from the start menu, it works!
[System info]
At work, so they're on Windows XP. Everything else is pretty standard, or so I'm lead to believe.
EDIT: Changed "C:\Python27\testing.py" to just "testing.py". This was left over from when I was trying to solve it, and thought maybe it was putting the files somewhere outside of the destination folder.
First, your Python script looks suspicious, I doubt the backslashes work in a simple string. At least, in my test, it didn't work, I just replaced them with forward slashes.
Next, you can see the error message by prepending cmd with cmd /k, the run window remains on screen. You can see the .py file isn't found, because it isn't in the current directory. You have to specify an absolute path to this file, perhaps by getting the current path from the script.
[EDIT] I finally got a working code (my VBS is a bit rusty...)
Dim wshShell, fso, loc, cmd
Set fso = CreateObject("Scripting.FileSystemObject")
loc = fso.GetAbsolutePathName(".")
WScript.Echo loc
'~ cmd = "%ComSpec% /k C:\Languages\Python\python.exe " + loc + "\test.py"
cmd = "C:\Languages\Python\python.exe " + loc + "\test.py"
WScript.Echo cmd
Set wshShell = CreateObject("WScript.Shell")
wshShell.Run cmd
You can also check the arguments if a path is provided:
if WScript.Arguments.Count = 0 then
loc = fso.GetAbsolutePathName(".")
else
loc = WScript.Arguments(0)
end if
Such script is better run with cscript instead of default wscript.
Try
f = open("C:\\Python27\\testing.txt", 'w')
instead of your first line.
I am making a vb text editor that can run scripting code. I have successfully gotten it to run the code and show up but I would like to be able to have the output from the the code redirected to a file without having to do anything to the python code. Is that possible?
This is the code I'm using to try it but it does not write anything to the file:
Shell(compiler & " """ & fileName & " "" > C:\output.txt")
the compiler is the location of python.exe in the python install folder and the file name is the file I'm running.
The problem could also be in the way I am trying to do it with the shell command.
After some more research into the the matter I found a way to make it work.
Here is the working code:
Shell("cmd.exe /c " & compiler & " """ & fileName & " "" > ""C:\output.txt"" ", vbNormalFocus)
So I am actually running the line through the command prompt which is being called by the shell function. My assumption was that shell function was using the command prompt to execute the string argument but I guess I was wrong. Also, just to note, the output file name is also surrounded by quotes which is different than my original post.