Running python script using Outlook VBA - python

Im trying to run a python script using Outlook Vba. When I run the below code. A python icon appears in the taskbar for a second and disappears. When in fact it should open a dialogue box and prompt me to enter folder name. After which it should run the rest of the script as usual.
Please help me run this script from outlook as I regularly do by double clicking the .py file.
Sub runpythonscript()
Dim Path As String
Path = "python C:\Doc Management\Exstream_Reconciliation.py"
Shell(Path)
End Sub

VBA (nor Outlook) doesn't provide anything for debugging such cases. The best what you could do is to add log statements to the python script where you could output everything what happens in the code. Analyzing log files you will be able to figure the cause of the problem.

You have a space in the file name. It must be quoted.

Ok this is the solution for anyone looking
Sub RunPyFileFromMacroViaCmd()
Dim Path As String
Dim filepath As String
filepath = """C:\Doc Management\Exstream_Reconciliation.py"""
Path = "cmd /k" & filepath
Shell (Path)
End Sub

Related

Can't run Python from Excel (xlwings)

I'm quite new to xlwings and I'm runing code from VBA in order to excecute a python script that writes some text in Excel.
The problem is when I run the VBA code, it seems to excecute python but my excel sheet doesn't change.
However, if I run the python script from python, it works just fine, even if the Excel file is already open.
VBA code is the following:
Sub Botón1()
Dim obj As Object
Dim pyexe, pyscript As String
Set obj = VBA.CreateObject("Wscript.Shell")
pyexe = """C:\Users\xxx\AppData\Local\Programs\Python\Python36-32\python.exe"""
pyscript = "C:\Users\xxx\Documents\Prueba.py"
obj.Run pyexe & pyscript, 1, True
End Sub
And python code is the following:
import xlwings as xw
wb = xw.Book('Libro1.xlsm')
sht = wb.sheets['Hoja1']
sht.range('A1').value = 'Hi!'
Both files (Libro1.xlsm and Prueba.py) are saved inside the same folder.
When I run excel macro it opens the cmd prompt but nothing happens in Excel spreasheet.
I have not installed xlwings add in, but I believe it is not necessary to do it, in order to do what I'm trying to do.
Can you please help me find what could be wrong?
I was reading this article:
https://devblogs.microsoft.com/scripting/how-can-i-get-the-command-window-to-stay-open-after-running-a-command-line-tool/
And it explains using .run is equivalent to calling Cmd.exe.
If I open cmd I just need to write my python file name with .py extension to run it.
So I figured out "pyexe" is not necessary.
The solution:
Sub Botón1_Haga_clic_en()
Dim obj As Object
Set obj = CreateObject("Wscript.Shell")
obj.Run "C:\Users\xxx\Documents\Prueba.py", 1, True
End Sub

How to assign a Python script to a button in Outlook?

I have the below Python code:
import win32com.client as client
outlook = client.Dispatch('Outlook.Application')
namespace = outlook.GetNameSpace('MAPI')
account = namespace.Folders['email account']
inbox = account.Folders['Inbox']
print(inbox.Name)
print(inbox.Parent.Name)
print(inbox.Items.Count)
HMEmails = [message for message in inbox.Items if message.SenderEmailAddress.startswith('ics.notifier')]
for message in HMEmails:
print(message)
folder = inbox.Folders('ICS Reports')
for message in HMEmails:
message.Move(folder)
When run via the command prompt, this code returns the number of email items in the specified folder, the names of them, and also moves them to a separate folder if they meet the criteria.
I understand that I must use Visual Basic for Applications to use the code within the Outlook application, but what would the VBA code for that look like? And is there a way to then assign the above script function to a button within Outlook so that the function is applied after clicking?
EDIT:
It seems the VBA code to run the Python script is rather simple. Below is the code that I thought should work:
'Initialise function
Sub RunPythonScript()
'Provision of file path locations to Python Exe and script
PythonExe = "C:\Users\user\AppData\Local\Programs\Python\Python38\python.exe"
PythonScript = """C:\Users\user\OneDrive - laptop\Documents\A&I\Python\offAutomation.py"""
'Invoke the Python script
Shell (PythonExe & PythonScript)
End Sub
When I click "Run" I get an error
"file not found" error.
Both file locations are valid since I am able to access both by pasting them into my search bar.
Many thanks to Tim Williams for the help on this. In order to run an external Python script from Outlook using VBA see the following example:
'Initialise function
Sub RunPythonScript()
'Provision of file path locations to Python Exe and script
PythonExe = "C:\Users\user\AppData\Local\Programs\Python\Python38\python.exe"
PythonScript = """C:\Users\user\OneDrive - laptop\Documents\A&I\Python\offAutomation.py"""
'Invoke the Python script
Shell (PythonExe & " " & PythonScript)
End Sub
Please note, the triple quotation marks for the PythonScript variable are necessary since there are spaces present within the file path.
The Sub function has been defined at the start
In my case, two variables have been assigned file paths for Python.exe and my Python script
The Shell function at the end runs the variables file paths, but they needed to be split by a space next to the ampersand symbol - that is why it didn't run originally.
End Sub marks the end of the VBA code.

Python script execution directory changes when I execute outside of Console

TLDR: I want to change the working directory of my script to the script file's location(instead of system32) when i run it by double clicking on it.
I have a really annoying problem I couldn't solve. I am building a python script that will take 4 text files as input and create some graphs and an excel sheet using these text files. I am going to pass my script to a friend who will copy this script into different folders and execute the script in those folders by just double-clicking on the script. The problem I am facing is when I execute my code out of cmd everything works fine. But if I double click on it, the directory my code is working changes automatically, and my program can't find the required 4 text files. I am attaching the required parts of my code below and also attaching some screenshots.
ss1
ss2
def fileOpenCheckLoad(fname):
pl=list()
try:
fh=open(fname)
except:
print("ERROR:"+ fname +" is missing. Execution will terminate.")
x=input("Press enter to quit.")
quit()
test1=fh.readline()
test2=fh.readline()
if test1[6]!=fname[5] and test2!='t x y\n' :
print("ERROR: Check the contents of:"+ fname)
x=input("Press enter to quit.")
quit()
count=0
for lines in fh:
count=count+1
if count>2 :
nums=lines.split()
pl.append((float(nums[2]), float(nums[2])))
tbr=(pl,count-2)
return tbr
# main starts here.
cwd = os.getcwd()
print(cwd)
# In this part we open and load files into the memory. If there is an error we terminate.
(pl1, count1)=fileOpenCheckLoad('point1.txt')
(pl2, count2)=fileOpenCheckLoad('point2.txt')
(pl3, count3)=fileOpenCheckLoad('point3.txt')
(pl4, count4)=fileOpenCheckLoad('point4.txt')
Before calling os.getcwd(), insert this line:
os.chdir(os.path.dirname(os.path.abspath(__file__)))
Explanation
__file__ is a special variable in Python; as described here, "__file__ is the pathname of the file from which the module was loaded"
os.path.abspath returns the absolute path to the input file or directory (I included this because depending on how you load up a Python file, sometimes __file__ will be stored as a relative path, and absolute paths tend to be safer to work with)
os.path.dirname returns the name of the directory which contains the input file (because chdir will return an error if we give it the name of a file, so we need to give it the name of the directory which contains the file)
os.chdir changes the working directory

Running .exe using VBA

So I created an .exe file (tlsolver.exe) to run using VBA (TLSolver.xlsm). When I launch the .exe, it runs some calculations, spits out a csv file, and then I use VBA to copy that data onto my excel sheet.
This is the VBA code I am using:
Public Sub StartExeWithArgument()
Dim strProgramName As String
ActiveWorkbook.Save
strProgramName = "C:\Users\My.Name\Desktop\Python\Tagless\tlsolver.exe"
Call Shell("""" & strProgramName & """", vbNormalFocus)
End Sub
When I run the macro, the console window pops up as it should and then quickly closes. I managed to see this error before it closes:
IOError: [Errno 2] No such file or directory: 'TLSolver.xlsm'
I know that the .exe works perfectly fine when I doubleclick on the file regularly, so I am inclined to think that I am messing up something silly in the VBA.
Any help appreciated!
Edit: I know the sub is labeled as StartExeWithArgument, but there is no argument required, simply click and run.
The shell command is executing correctly. The exe launches and then looks for the .xlsm file in the current path. What is happening is that it is not able to find the TLSolver.xlsm in the current directory and hence the error IOError: [Errno 2] No such file or directory: 'TLSolver.xlsm'
Three suggestions in such a case.
Change the directory in VBA using ChDir to the directory where the excel file resides and then launch the exe OR
Place both files in the same directory. OR
Rewrite the python exe code (This falls out of my expertise so can't help you here) to prompt the user to select the excel file.
VBA PART (Suggestion 1)
Public Sub StartExeWithArgument()
Dim strProgramName As String
Dim xlFilePath As String
'~~> Path of the excel file. Change as applicable
xlFilePath = "C:\Temp"
ActiveWorkbook.Save
'~~> Change directory
ChDir xlFilePath
strProgramName = "C:\Users\My.Name\Desktop\Python\Tagless\tlsolver.exe"
Call Shell("""" & strProgramName & """", vbNormalFocus)
End Sub

Python3:Save File to Specified Location

I have a rather simple program that writes HTML code ready for use.
It works fine, except that if one were to run the program from the Python command line, as is the default, the HTML file that is created is created where python.exe is, not where the program I wrote is. And that's a problem.
Do you know a way of getting the .write() function to write a file to a specific location on the disc (e.g. C:\Users\User\Desktop)?
Extra cool-points if you know how to open a file browser window.
The first problem is probably that you are not including the full path when you open the file for writing. For details on opening a web browser, read this fine manual.
import os
target_dir = r"C:\full\path\to\where\you\want\it"
fullname = os.path.join(target_dir,filename)
with open(fullname,"w") as f:
f.write("<html>....</html>")
import webbrowser
url = "file://"+fullname.replace("\\","/")
webbrowser.open(url,True,True)
BTW: the code is the same in python 2.6.
I'll admit I don't know Python 3, so I may be wrong, but in Python 2, you can just check the __file__ variable in your module to get the name of the file it was loaded from. Just create your file in that same directory (preferably using os.path.dirname and os.path.join to remain platform-independent).

Categories

Resources