Running .exe using VBA - python

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

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

How to get the path of a ".lnk" file using tkinter.filedialog.askopenfilenames() in python 3.10? Or any other ways?

My work needs me to collect some file names and their generating time.
I am using the fileName = tkinter.filedialog.askopenfilenames() to realize the function, that the program pops up a window to ask for selecting files, then I can get the files' pathes and then use fileGeneratedTime = datetime.datetime.fromtimestamp(os.path.getmtime(fileName)) to get the files' generating time.
But now here comes the problem. When I want to get the path of a .lnk file, however, it returns the path of the file which the .lnk file is pointing to. It is OK to run the program on the origin computer that has the .lnk files, but when I copy the .lnk files to other computers, the program says FileNotFoundError.
So, is there any parameters that can make the fileName = tkinter.filedialog.askopenfilenames() returns the .lnk file itself's path (not the path of the file which the .lnk file points to)? Or is there any other ways to realize the same function?
Thanks for your answering!

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

Why does a python program continue to write to the directory in which it was originally located, after I move the file to another directory?

I have 2 directories. I had a python program located in dir_1 writing to a .txt file also in dir_1. I meant to create them in dir_2, but when I move them both to dir_2, the python program, instead of writing to the existing .txt file that is now with it in dir_2, creates a new .txt file in dir_1 and writes to it. How do I fix this? I'm very new to programming and python and googling didn't help me out, probably because I didn't know what exactly to search.
with open('guest_book.txt', 'w') as file:
while True:
name = input('Please enter your name: ')
if name == 'q':
break
else:
print(f"Hello, {name.title()}!\nYou have been added to the guest"
f"book")
file.write(f"{name.title()}\n")
Python writes to the file location you supply it with. If this file location is a relative path, then it will create files relative to the directory of the script. I.e. when you move the script then the .txt file will be created relative to the new directiory.
On the other hand, if you provide an absolute path, then it does not matter where the script is located / where you execute it from. Instead, it will create the file at that location always.
From the sounds of it, you are using an absolute path when you want a relative path.
So change from something like /home/bob/file.txt (Linux) or C:\\Users\Bob\file.txt (Win) to simply file.txt or even ./file.txt.
Update: Since you were using a relative location all along, the problem will lie with the context that you are executing the script from. Your code is not the issue here, it is how you are executing it.
As vlovero suggests, maybe your IDE is not executing the new file in its new location?
One way you can test this robustly is to navigate to dir_2 in a terminal and run
python your_program_name.py
This will execute the script in the dir_2 location.
Since you have not specified an absolute path, your program is then specifying a directory relative to the current working directory (if instead, for example, you had specified a path such as '../guest_book.txt', you would have been specifying a directory one level above the current working directory). So let's imagine your OS is Linux and the Python program resides in /my_home/programs:
cd /my_home/data # this is the current working directory
python ../programs/your_program.py
The current working directory when the program is executed is /home/my_home/data even though the program being executed resides in /my_home/programs, and thus the output file will be created in the /my_home/data directory. os.getcwd() can be called to tell you what the current working directory is.

Apple Automator process csv files and create new files

Is it possible to loop through a set of selected files, process each, and save the output as new files using Apple Automator?
I have a collection of .xls files, and I've gotten Automator to
- Ask for Finder Items
- Open Finder Items
- Convert Format of Excel Files #save each .xls file to a .csv
I've written a python script that accepts a filename as an argument, processes it, and saves it as p_filename in the directory the script's being run from. I'm trying to use Run Shell Script with the /usr/bin/python shell and my python script pasted in.
Some things don't translate too well, though, especially since I'm not sure how it deals with python's open('filename','w') command. It probably doesn't have permissions to create new files, or I'm entering the command incorrectly. I had the idea to instead output the processed file as text, capture it with Automator, and then save it to a new file.
To do so, I tried to use New Text File, but I can't get it to create a new text file for each file selected back in the beginning. Is it possible to loop through all the selected Finder Items?
Why do you want this done in the folder of the script? Or do you mean the folder of the files you are getting from the Finder items? In that case just get the path for each file passed into Python.
When you run open('filename','w') you should thus pass in a full pathname. Probably what's happening is you are actually writing to the root directory rather than where you think you are.
Assuming you are passing your files to the shell command in Automator as arguments then you might have the following:
import sys, os
args = sys.argv[1:]
for a in args:
p = os.path.dirname(a)
mypath = p + "/" + name
f = open(mypath, "w")

Categories

Resources