I would like to create a Excel VBA macro from python.
I already managed to add a module sheet via win32com, but I dont know how to write the code into the module. Here is the code I am using:
import win32com.client
xl = win32com.client.dynamic.Dispatch("Excel.Application")
xl.Visible=True
out_file = "workbook.xlsm"
xl.Workbooks.Open(out_file)
Book=xl.Application.Workbooks(1)
newModule=Book.Modules.Add()
Now: How do I write a string containing the macro into the new module sheet?
Related
I'm trying to write a python code that will run a macro in a excel workbook. I know the file name and name of the vba macro. I don't need to read any information into the python file I simple need to perform this function.
I ultimately want to run this python code periodically and I want it to call the same VBA function multiple times in a day.
import openpyxl
excel_document = openpyxl.load_workbook('python test.xlsm')
print type(excel_document)
I found this Code on Stackoverflow. Maybe it helps you.
Resource:
Running an Excel macro via Python?
import win32com.client
if os.path.exists("excelsheet.xlsm"):
xl = win32com.client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open(os.path.abspath("C:\Users\{Username}\Desktop\test.xlsm"), ReadOnly=0)
wb.Sheets('Sheet1').Select()
xl.Application.Run("test.xlsm!Module1.macroname")
## xl.Application.Save() # if you want to save then uncomment this line and change delete the ", ReadOnly=1" part from the open function.
xl.Application.Quit() # Comment this out if your excel script closes
del xl```
I have 2 files, lets say 't1.xlsx' and 't2.xlsx'.
What i want to do is to do the VLOOKUP fucntion inside the t1 file using the data from t2 file.
I try to paste
"sheet["O2"].value = "=VLOOKUP(C:C;'C:\\Users\\KKK\\Desktop\\sheets\\excellent\\
[t2.xlsx]baza'!$A$2:$AI$10480;25;0)"
where baza is a sheet name, but sadly when i try open the file it says it can not be open due to the error and offers me repairing tool.
rest of the code:
import openpyxl
wb = openpyxl.load_workbook('t1.xlsx')
sheets = wb.get_sheet_names()
sheet = wb.get_sheet_by_name('Sheet1')
[VLOOKUP STUFF FROM BEFORE]
wb.save("t1.xlsx")
With more complicated formulae you should always check the syntax in the XML because they are often stored differently than they appear in Excel. This is covered in the documentation. You might be okay simply using a comma as a separator but I suspect you'll also have change the path of the file and use a Python raw string (the r prefix).
I am trying to read a excel sheet using Win32com.client
import Win32com.client as win32
excel=win32.gencache.EnsureDispatch('Excel.Application')
filename='AssetList.xls'
book=excel.WorkBooks.Open(filename)
Throwing Error and saying file is already open.Cannot open two documents with the same name
pywintypes.com_error:()
Please suggest a method to overcome this situation .If someone open my excel sheet the script wont work.
I'm using VBA to save an excel worksheet as a CSV file. The macro saves it as a CSv and then opens it in excel. I have a python code that reads the file, by the user selecting it (using tkinter) to open.
Is there a way to modify my python code to detect an open csv file, so that I can skip the user select stage? I want it to return the filepath or read open csv file. This is the current version of my code, which works if the csv file is open in excel:
import numpy as np
from Tkinter import Tk
from tkFileDialog import askopenfilename
tk=Tk()
tk.withdraw()
filename = askopenfilename()
data = np.genfromtxt(filename, dtype=[('x',float),('y',float)],comments='"', delimiter=',',skip_header=1,missing_values=True)
tk.destroy()
x=data['x']
x = x[np.logical_not(np.isnan(x))]
y=data['y']
y = y[np.logical_not(np.isnan(y))]
print x
print y
Which OS? If it is Windows, take a look at Get name of active Excel workbook from Python. The code in the question itself may do what you're looking for:
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
print(xl.ActiveWorkbook.FullName)
As mentioned in that question's answer, this only prints the path to the most recently opened file, but in your case it sounds like the macro is opening the file, so perhaps it would work? Otherwise, take a look at the actual answer - it seems very complete.
I have an Excel macro that deletes a sheet, copies another sheet and renames it to the same name of the deleted sheet. This works fine when run from Excel, but when I run it by calling the macro from Python I get the following error message:
Run-time error '1004' - Cannot rename a sheet to the same name as
another sheet, a referenced object library or a workbook referenced by
VisualBasic.
The macro has code like the following:
Sheets("CC").Delete
ActiveWindow.View = xlPageBreakPreview
Sheets("FY").Copy After:=Sheets(Sheets.Count)
Sheets(Sheets.Count).Name = "CC"
and the debugger highlights the error on the last line where the sheet is renamed. I've also tried putting these calls directly in python but get the same error message.
Any suggestions are much appreciated!
Thanks.
I ran the code inside Excel VBA.
I am guessing that the following line is failing.
Sheets("CC").Delete
And that is the reason, you can't give the new sheet same name as existing (non-deleted) sheet.
Put Application.DisplayAlerts = False before Sheets("CC").Delete and Application.DisplayAlerts = True once you are finished with the code.
I haven't used python but it seems the library is swallowing that error for you and letting you go ahead to the next statement.
Hope that helps.
Behind the scenes, VB and VBA are maintaining references to COM objects for the application, worksheets etc. This is why you have the globals 'Application', 'Worksheets' etc. It is possible that VBA is still holding a reference to the worksheet, so Excel hasn't tidied it up properly.
Try not using these implicit globals and referencing the items in the object model explicitly. Alternatively you could do it directly in Python.
Here's a python script that will do something like what you want:
import win32com.client
xl = win32com.client.Dispatch ('Excel.Application')
xl.Visible = True
wb = xl.Workbooks.Add()
wb.Worksheets[0].Delete()
wb.Worksheets.Add()
wb.Worksheets[0].Name = 'Sheet1'