Start python script from excel with input - python

I have a Python script (gui.py - a calculation program, written by somebody else). I try to run this from excel with input data from the same excel file. It works fine when I start the script as:
objShell.Run PythonExe & PythonScript3
In the python script I used the following to get f.ex data from H5 cell, works also fine:
import openpyxl
wb = openpyxl.load_workbook("01.xlsm")
ws = wb.active
mastNumber = ws['H5']
But I don't want to edit a lot in gui.py (have just simple changes) so I planned to use a 2nd script (caller.py) which gets the data from Excel, then I import this to gui.py and there I just use the variable from caller.py. It works also as long as I start gui.py directly. When I start it from Excel I get an error msg.
error msg
So as long as the flow is not Excel -> gui-py -> which imports caller to get data from same Excel file -everything works fine.
I am open to any solution for this problem or a completely new approach if there is better for somebody with limited programming skills.

Looking at the error, can you try putting complete path of the excel file at line wb = openpyxl.load_workbook("01.xlsm") instead of just 01.xlsm.

Related

How to refresh all pivot table of an excel file using Python xlwings [duplicate]

I am trying to refresh a pivot table in excel upon data written by XLWINGS.
As I don't know how to do it directly from XLWINGS, I tried to use VBA.
Let's split my process in 2 steps:
Step1
I launch the python code from vba (my module name is "PosRep", the python code writtes back a range of data in a specified sheet thanks to xlwings.
Sub launchPython()
RunPython ("import PosRep; PosRep")
End Sub
Step 2
But as I don't know in advance the size of my newly created Range in Excel, I want to select it, add a new Name (NamedRange) and refresh my pivot (already linked to the NamedRange).
Sub SelectRange()
Worksheets("GPODump").Range("A1").Select
'...
End Sub
Both Subs work independently well. But I cannot manage to make them work in a raw. The following code:
Sub Main()
launchPython
SelectRange
End Sub
produces a VBA error "Select method of Range class failed" on the statement:
Worksheets("GPODump").Range("A1").Select
I presume there is a conflict with the XLWINGS VBA module but I can't figure out what it can be...
Anyone's help would be more than welcome !
Thx
The problem came from the VBA code. The following code works fine:
Sheets("GPODump").Select
Sheets("GPODump").Range("A1").Select
Maybe it's too late but you can do it within xlwings - this is what worked for me:
import xlwings as xw
# open excel App
app_excel = xw.App(visible = False)
# open the excel file, select the tab and the PivotTable to refresh
wbook = xw.Book( 'YourFile.xlsx' )
wbook.sheets['Tab1'].select()
wbook.api.ActiveSheet.PivotTables('PivotTableName').PivotCache().refresh()
I was looking how to solve this for Mac, here is how I did to refresh all pivot tables and etc:
wb.api.active_sheet.refresh_all(wb.api)
Hopes that this saves someone else time. Took me a while to figure it out.

Running .exe to execute batch file written in Python (Novice Programmer)

I wrote a Python script to prompt users for a spreadsheet to rename photos automatically based on the column called "Rename_Code" in the spreadsheet. The column is extracted and saved as a batch file, called "Rename_Code.bat". Below is the script:
import pandas as pd from tkinter.filedialog
import askopenfilename
#prompt user to browser excel sheet and load the spreadsheet in python
xl = pd.ExcelFile(askopenfilename() , index_col=None)
# load a sheet into a dataframe called df1
df1 = xl.parse('Sheet1')
# assign "Rename Code" column as rename_col
rename_col = df1['Rename_Code']
# extract the column and write as a batch file
rename_col.to_csv('Rename_Code.bat', index=False)
from subprocess import Popen p = Popen("Rename_Code.bat", cwd=r"C:\Users\username\Documents\XXXXX") stdout, stderr = p.communicate()
What I am trying to do is convert this script (in .pyw format) into an .exe so that anyone can use it without having Python installed in their computers. I used py2exe to convert the script. However, it kicked an error when I double clicked on the .exe. It says "Failed to launch application".
I am wondering if there is something wrong with the script. Alternatively, is there a better way to execute this, perhaps with Window Services? If yes, how? I am a novice programmer, most of my learning in programming involves a lot of trial and error and research.
I truly appreciate your feedback and help!

VBScript kills program before text file is made

I made a vbscript to open an excel doc, then runs a python program that pulls data from the documents tables and prints it to a text file. The script is supposed to wait until the python program is done creating the text doc then close the excel doc, but for whatever reason my python program closes before it even has a chance to make that text doc.
I even changed the python code to just print a simple 'Hello World' into a new text document in case pulling data from excel was causing problems but the text document still wasn't created.
This is the script that i'm running:
Set xl = CreateObject("Excel.application")
xl.Application.Workbooks.Open "C:\Users\V\Documents\_PROGRAMS_\TEST.xlsx"
xl.Application.Visible = True
Dim oshell
Set oshell = WScript.CreateObject("WScript.Shell")
oshell.CurrentDirectory = "C:\Users\V\Documents\_PROGRAMS_\"
windowStyle = 1
waitUntilFinished = True
oshell.run "python table.py", windowStyle, waitUntilFinished
xl.Application.Quit
I don't think adding the python program is important since that isn't really the problem. Although I will say that I tried putting a delay in the python program to see if that would change anything (it didn't).
I though adding the two extra arguments to .run would make it wait until the process is finished but I guess I must be missing something?
I'm just starting to learn how to use vbscript so any explanations of code would be welcomed!
Thanks!
EDIT: So after more testing it seems that it does have something to do with accessing the excel document, as just printing 'Hello World' to a file did actually work and the file was created (I made it in the wrong directory by accident so I was looking in the wrong place). But trying it with the data from the excel document no file is created, the program just ends
So here's the python code I wrote:
#!/usr/bin/python27
import pandas as pd
table = pd.read_excel("TEST.xlsx") #Get excel doc
file = open("text.txt", "w") #Open new file
file.write(table.columns.values) #Print out column headers
file.write("Hello!")
file.close()

Python vba extract to get bin of macro

I am trying to add a vba_project to "Sheet1" of a workbook using python.
I am following XLSXWRITER documentation to get the bin of the VBA code from a different sheet which I would want to use in "Sheet1" of my new workbook.
I enter the below code in command prompt but I get the error: "'vba_extract.py' is not recognized as an internal or external command"
$ vba_extract.py Book1.xlsm
Extracted: vbaProject.bin
Can someone give me a step by step on how to extract the macro from old file as bin and then input into sheet1 of new workbook using python?
You have to tell the cmd you're running a python file.
Try this batch code:
cd C:\path\of\yourfile.py
python vba_extract.py Book1.xlsm
edit:
Added cd command, you have to be in the folder of the python file.
I figured this out today and just wanted to leave it here for any future people to use. This was so unbelievably frustrating to figure out how to do. If you are using the Pandas library, this is also relevant. Make sure to install xlsxwriter also.
1.Click on your windows start button and type 'cmd' and click on it to run the Command Prompt.
2.Once you have it open, you need to locate where the vba_extract.py file is. For me it was here:
C:\Users\yourusername\AppData\Local\Programs\Python\Python36-32\Scripts\vba_extract.py
3.Now, you need to get the path of the .xlsm file you want to take from. If you don't have a .xlsm file made. Make one. Here is an example:
C:\Users\yourusername\Desktop\excelfilename.xlsm
4.Now, back to the Command Prompt. This is exactly what you will type. You will take both items from steps 2 and 3 and combine then and hit enter. Here:
C:\Users\yourusername\AppData\Local\Programs\Python\Python36-32\Scripts\vba_extract.py C:\Users\yourusername\Desktop\excelfilename.xlsm
if it is successful, it will tell you this:
Extracted: vbaProject.bin
5.For this one I'm not sure. I assume that wherever your .xlsm file is where the .bin file will end up. For this example, it ended up on my desktop. It will have all the macros you created or had on the original .xlsm file.
C:\Users\yourusername\Desktop/vbaProject.bin
Here is an example of it being used in full code:
import pandas
import xlsxwriter
df_new = pd.read_csv('C:\\Users\\yourusername\\Desktop\\CSV1.csv')
writer = pd.ExcelWriter('C:\\Users\\yourusername\\Desktop\\CSV1.xlsx')
df_new.to_excel(writer, index = False, sheet_name = 'File Name', header = False)
pandaswb = writer.book
pandaswb.filename = 'C:\\Users\\yourusername\\Desktop\\newmacroexcelfile.xlsm')
pandaswb.add_vba_project(r'C:\Users\yourusername\Desktop/vbaProject.bin')
writer.save()

xlwings doesn't write data in file.xlsm when running through excel

I am trying to use xlwings for simple consolidation from several xls files.
For this, I have a all_files.xlsm file that contains a button with macros assigned to it. The macros looks like:
Sub check_data()
RunPython ("import python_code; python_code.consolidation()")
End Sub
In same folder I have a file python_code.py with function "consolidation" inside.
I also use Workbook.set_mock_caller() in order to have an opportunity to run a code through python interface. It looks like:
def consolidation(file_path):
*** smth to get the data I need ***
...
*** after I got data ***
Range('A1').table.clear_contents() #string1
Range('A1').value = data #string2
def main():
consolidation(file_path)
if __name__ == '__main__':
xl.Workbook.set_mock_caller(path_to_file)
main()
The problem is that when I am running the script through the button in excel file last two strings (string1 and string2) - Range('A1').table.clear_contents() and Range('A1').value = data doesn't work. Although the rest of the code works fine (however, it contains xlwing also). Moreover, if I run the script through the python interface using set mock caller, it works just fine, including string1 and string2 (marked in the code).
Any help and advices are really appreciated!
I found decision for my problem. For using xlwings in python you should import xlwings.bas in your excel file (see manual for xlwings). It turns out, that I imported it for this macros before I've updated xlwings. So I deleted this file and imported a new one. Everything works fine now.

Categories

Resources