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

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.

Related

Running python script using Outlook VBA

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

Simple way of calling a Machine Learning Python script from Excel with out using add-ins

I am stuck in a major pickle where I have some automation in VBA in Excel and need to pass a list of words to a Python script that is running a machine learning algorithm (where it classifies a request). This script will provide a string output (request category) that I need to receive in VBA again.
I have walked through countless methods of using pyxll or xlwings but unfortunately, these will not work for me as the excel file and python file will be in SharePoint being used by different members and I am sure all of them will not be having these add-ins installed.
I found a method of passing the argument (list of words) to a test Python script using command line. The test Python script is able to receive it. Here is the code sample
import sys
script_name = sys.argv[0]
text= sys.argv[1]
print('text - ',sys.argv)
But when I try to use the machine learning script, let's say, to read and export a dataset then it does not work.
My ultimate goal is to run 2 python function:
a function to train my classifier
a function that takes this list of words from VBA, runs the predictive algo and gives back the output (a string).
Can someone maybe help me with it? This is the first time I am working with something cross-platform. If it helps my ML algo is running perfectly well in the Python environment, it is the connection with VBA that needs to be sorted out.
FOR EXAMPLE:
I wrote a test script to see if I can pass my request to Python script and then the python script loads a dataset (to see if this functionality is working or not) and creates a file and writes something in it.
Here is the VBA code:
Sub SampleCall()
'declare var
Dim objShell As Object
Dim PythonExe, PythonScript As String
Dim PythonArg As String, oCmd As String
'create a new shell obj
Set objShell = VBA.CreateObject("Wscript.Shell")
'provide the file path to the python exe
PythonExe = """C:\Users\I547565\AppData\Local\Microsoft\WindowsApps\python.exe"""
'provide file path to python script
PythonScript = """C:\Users\I547565\SAP SE\Headcount Control Tower for Services - Headcount Control Tower\Control Tower - Automation\Resources\Artificial Intelligence\rough.py"""
PythonArg = "I love Europe"
MsgBox PythonArg
objShell.Run PythonExe & Chr$(32) & PythonScript & Chr$(32) & PythonArg
End Sub
ANd here is the python script:
import sys
script_name = sys.argv[0]
text= sys.argv[1]
print('text - ',sys.argv)
input('press enter to continue...')
from pathlib import Path
sysPath = str(Path.home())
rawDataPath = sysPath + "\folder\XRdata.xlsx"
import pandas as pd
df = pd.read_excel('XRdata.xlsx', sheet_name='data')
print(df.head())
f= open("output.txt","w+")
f.write('category')
f.close()
input('press enter to close...')
If I run the python script independently, i get a file named output.txt in my folder. But when I run this script from VBA, I am able to see the "I love Europe" on the console but the rest of the code does not give me the output that is the txt file is not generated.
Please help before I rip my hair out!!!

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 do I reference a directory in Python so it works on multiple computers?

I created a Python script that I want to use on different computers. I'm using os and pyautogui modules since for pyautogui I have multiple screenshots stored in the folder where py python script is located, also I have a .txt file from which I grab information relevant to the script and should be different on each of those computers.
This is the reference in the script:
os.chdir(r'C:\Users\myusername\Desktop\Script')
p.FAILSAFE = False
# extracts login and password from a txt file, for each user
credentials = open("login.txt", "r")
for line in credentials:
pieces = line.split(":")
email = pieces[0]
password = pieces[1]
How do I make it accustom to any computer where the script is located and will it work with pyinstaller after I converted the .py file into .exe. Thanks!
You can create a directory and point to it, the code will be:
directory_path = os.path.join(os.environ['USERPROFILE'],'Desktop','Script')
if not os.path.isdir(directory_path): os.mkdir(directory_path)
os.environ['USERPROFILE'] gets the user directory for each user in each machine.
You can use os.path.expanduser to reference user home directory. This will work in Unix and Windows.

Run Python script via VBA and give name and path of active workbook?

EDIT: This is the same question but I rewrote it, so it is more legible.
I already tried this post: How to call python script on excel vba?
And this post: Run and execute a python script from VBA
And this post: How can I call python program from VBA?
But none of the answers works for me and I have no idea what I'm doing wrong. Problem 1: I want to run a pythonscript from VBA excel. excel file doesn't have a home place (can be on any desktop). the code I (want to) use:
Dim Ret_Val
Ret_Val = Shell("C:\python27\python.exe \\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\DescriptionToDatabase.py")
The pythonfile has always the same path on the server. I cannot see wat is wrong here? All I get is a black python screen.
In the python file I call the workbook and the correct sheet:
book = xlrd.open_workbook("//10.31.13.22/SharedDocs/3 - Technical/1 - Projects/0 - Internal/RPA 138 - Engineering software/testchipdescription/upload to database/testchipdescription-template-10-11.xltm")
sheet = book.sheet_by_name("Database")
At the moment the excel workbook path is hardcoded in python. This will bring me back to problem 2: Can I pass the name and path of the excel workbook somehow to my pythonscript?
EDIT:
I tried the shell()code in command prompt.
The same as in VBA:
"C:\python27\python.exe \\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\DescriptionToDatabase.py"
It doesn't work. 'The system cannot find the path specified'.
I tried this one:
C:\python27\python.exe "\\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\DescriptionToDatabase.py"
And it works! So the cmd needs "" to handle the spaces in the path. But I can't add them in VBA because I cannot place 2 "" otherwise it errors.
Yes, I found a solution for problem 1:
Dim excelToPython As String
excelToPython = """C:\python27\python.exe"" ""\\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\DescriptionToDatabase.py"""
Debug.Print excelToPython
Call Shell(excelToPython)
Thanks to 'Allan Browne' (https://bytes.com/topic/access/answers/520558-problem-shell-space-file-name)
EDIT:
Finally I have found a workaround for problem 2. I still don't have the real solution to give the name and the path of the active workbook to my python script with the shell command.
But I write the path and name of my active workbook in a txtfile in the same folder as my python script. And then I get this information with my pythonscript et voila.. It works! Well it does what I want, but it's not a clean solution. If someone knows the correct solution, please feel free to share it :o)
my workaround solution:
code in vba-excel:
'via pythonscript'
Dim excelToPython As String
Dim myFileTxt As String
Dim fileTxtPath As String
'first give the name and path of active workbook to a txtfile in the same folder as ThemeColor pythonscript'
fileTxtPath = "\\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\actWBdb.txt"
myFile = FreeFile
Open fileTxtPath For Output As myFile
nameWB = ActiveWorkbook.name
pathWB = ActiveWorkbook.path
Print #myFile, nameWB
Print #myFile, pathWB
Close myFile
'run the python file'
excelToPython = """C:\python27\python.exe"" ""\\10.31.13.22\SharedDocs\3 - Technical\13 - Reports & Templates\13 - Description\DescriptionToDatabase.py"""
Call Shell(excelToPython)
code in python:
filepath ='//10.31.13.22/SharedDocs/3 - Technical/13 - Reports & Templates/13 - Description/actWBdb.txt'
lines = open(filepath).read().splitlines()
nameWorkbook = lines[0]
pathWorkbook = lines[1]
book = xlrd.open_workbook(pathWorkbook + '/' + nameWorkbook)
sheet = book.sheet_by_name("Database")
I was wondering if it is possible to give the name and the path of the active excel workbook to a python script I call from this active workbook?
Yes. You can pass argument(s) to SHELL function from VBA, and then you would need to modify your python script to accept the argument(s) and do something with it/them.
Python Read from Stdin with Arguments
Python read from command line arguments or stdin

Categories

Resources