I'm trying to open password protected excel workbooks and found the code I've posted below on this page but when I try to impliment it I'm getting a sytaxError and an indentationEorror
xlpassword.py
import xlwings as xw
from autoit.autoit import AutoItError
import autoit
import threading
class _WB(object):
def __init__(self, path, password=None):
self.path = path
self.password = password
self.name = path
#staticmethod
def _handlepassword(password):#this line is giving the error
if password:
autoit.win_wait_active("[TITLE:Excel]", 5)
autoit.send(password)
autoit.send("{ENTER}")
def op(self):
try: # If already opened
autoit.win_activate("%s - Excel"%self.name)
self.book = xw.Book(self.path)
except AutoItError: # Else
t = threading.Thread(target=self._handlepassword, args=(self.password,))
t.start()
self.book = xw.Book(self.path)
t.join()
finally:
return self
def _wait(self):
autoit.win_wait_active("%s - Excel"%self.name, 1)
def close(self):
self._wait()
self.book.close()
autoit.win_close("Excel")
when I get to the def _handlepassword line I get the output
SyntaxError: unexpected EOF while parsing (<string>, line 1)
IndentationError: unexpected indent (<string>, line 1)
Which means when I import xlpassword.py into another python script, that new script fails to run
test_run.py
import pandas as pd
from xlpassword import * #I know this isn't best practice
PATH = "C:\\Path\\to\\my\\file.xlsx"
print(PATH)
wb = _WB(path=PATH, password='MyP8ssw0rd')
I'm using python 3.8.1 on a windows 10 machine, and I have tried to run the code in spyder, sublime, and Rstudio (I normally work in Rstudio but I thought that might be what's causing the problem.)
I have read up on classes, class methods, and static methods and I can't see what I'm doing wrong here so if anyone could provide assistance it would help a lot.
Since v0.16.1, xlwings supports opening of password protected workbooks out of the box:
import xlwings as xw
wb = xw.Book(password='mypassword')
See also the API Reference: https://docs.xlwings.org/en/stable/api.html#xlwings.Book
I would like to quit my Excel application from my Python code. My Python code opens an excel book, runs a macro, then closes the book. However, the Excel application is still running. How can I quit Excel?
This is the error I get from Python IDLE:
(-2147417848, 'The object invoked has disconnected from its clients.', None, None)
Here is my Python Code:
import xl
report = xl.Workbook(r"C:\Desktop\Reader.xlsm")
print(report)
report.xlWorkbook.Application.Run('Reader')
report.xlWorkbook.Close(SaveChanges=False)
report.xlWorkbook.Application.Quit()
print("The job is done")
Here is my Excel macro:
Public Sub Reader()
MsgBox ("Hello World")
End Sub
The comment from dwirony is a workaround that is definitely usable. However you really want to go the right way about this or you may end up with a hanged excel process and memory leaks.
In my opinion the correct way would be:
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
report = xl.Workbooks.Open("C:\Desktop\Reader.xlsm")
xl.Application.Run('Reader')
report.Close False
xl.Application.Quit()
xl = None
del xl
print("The job is done")
Thanks, it helped when I had an issue with xlwings!
I have connected your answer with this article: com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147024809), None)
The above solution is for python 2. For python 3 it would look like:
import win32com.client
xl = win32com.client.Dispatch("Excel.Application")
filepath = *INSERTFILEPATHHERE* #for example "C:\Desktop\Reader.xlsm"
report = xl.Workbooks.Open(filepath)
xl.Application.Run('Reader')
report.close() #empty brackets
xl.Application.quit()
xl = None
del xl
print("The job is done")
You may also use xlwings or openpyxl instead of win32com to process your files.
I have an issue connecting to Lotus Notes from Python using win32com.client.
I am using the following code:
import win32com.client
import csv # imports the csv module
import sys # imports the sys module
import re
notesServer = "AALMBX01/Server/..."
notesPass = "PASS"
#Connect to notes database on server
notesSession = win32com.client.Dispatch('Lotus.NotesSession')
notesSession.Initialize(notesPass)
db_name = 'mail\iizs.nsf'
db = notesSession.getDatabase(notesServer, db_name)
view = db.GetView("($All)")
doc = view.getFirstDocument()
And I get the following error:
(-2147352567, 'Exception occurred.', (0, u'NotesSession', u'Notes
error: Wrong Password. (Passwords are case sensitive - be sure to use
correct upper and lower case.)'
Also tried leaving password blank and disabling 'request password for LN applications' in the interface. With a blank password, I am getting the following error message:
(-2147352567, 'Exception occurred.', (0, u'NotesDatabase', u'Database
AALMBX01/Server/...!!mail\iizs.nsf has not been opened yet'
I have tried the following:
Using lnlib and get_session function.
Checking that notus.ini file is in place (C:\Users\iizs\NotesData in my case) and includes the reference to userid (tried adding the full path to userid file, which is located in C:\Users\iizs\NotesData\data).
Adding a value to HKEY_CURRENT_USER\Software\Lotus\Notes(optional-version)\NotesIniPath
Added the folder containing notes.ini file (C:\Users\iizs\NotesData) and user.id file (C:\Users\iizs\NotesData\data) to the PATH environment variable.
The error is still the same. Tried copying user.id to one of system folders too (system32) - did not help either.
Any suggestions?
import win32com.client
import pywintypes
from win32com.client import Dispatch
from win32com.client import constants
notesSession = Dispatch('Lotus.NotesSession')
dir(constants)
dir(notesSession)
Password = 'S3cretP455w0rd'
Server = 'yourserver/yourapp' # yourserver = '' if local
scPath = 'view.nsf'
notesSession.Initialize(Password)
HTH!!
Also, one 'gotcha' that happened for me was network drives - if your NOTES.INI file contains a network path, try deleting and adding it in the Python code:
[code]
import os
os.system('net use w: /delete')
os.system('net use w: \\\\apps\\NotesFolder')
[/code]
I am trying to run an excel macro via python (v2.7). The macro function runs fine, but when I try to save the workbook, it errors out saying TypeError: 'bool' object is not callable.
Here is the relevant code:
def run_vba(xlpath, fn):
xlapp = win32com.client.Dispatch('Excel.Application')
wbook = xlapp.Workbooks.Open(xlpath)
parent, xl = os.path.split(xlpath)
log = logging.getLogger()
log.info("Running fn %s at %s" % (fn, xl))
xlapp.run("'%s'!%s" % (xl, fn))
log.info('Ran macro, now saving...')
wbook.Save() # <--- fails here
log.info('Saved, now closing...')
wbook.Close()
xlapp.quit()
I am new to windows programming in python, so would like some help on this error and how to debug and root cause.
I'm trying to run a macro via python but I'm not sure how to get it working...
I've got the following code so far, but it's not working.
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename="C:\test.xlsm",ReadOnly=1)
xl.Application.Run("macrohere")
xl.Workbooks(1).Close(SaveChanges=0)
xl.Application.Quit()
xl=0
I get the following traceback:
Traceback (most recent call last):
File "C:\test.py", line 4, in <module>
xl.Application.Run("macrohere")
File "<COMObject <unknown>>", line 14, in Run
File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 282, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
com_error: (-2147352567, 'Exception occurred.', (0, u'Microsoft Excel', u"Cannot run the macro 'macrohere'. The macro may not be available in this workbook or all macros may be disabled.", u'xlmain11.chm', 0, -2146827284), None)
EDIT
import win32com.client
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(Filename="C:\test.xlsm",ReadOnly=1)
try:
xl.Application.Run("test.xlsm!testmacro.testmacro")
# It does run like this... but we get the following error:
# Traceback (most recent call last):
# File "C:\test.py", line 7, in <module>
# xl.Workbooks(1).Close(SaveChanges=0)
# File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 192, in __call__
# return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
# com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352565), None)
except:
# Except isn't catching the above error... :(
xl.Workbooks(1).Close(SaveChanges=0)
xl.Application.Quit()
xl=0
I would expect the error is to do with the macro you're calling, try the following bit of code:
Code
import os, os.path
import win32com.client
if os.path.exists("excelsheet.xlsm"):
xl=win32com.client.Dispatch("Excel.Application")
xl.Workbooks.Open(os.path.abspath("excelsheet.xlsm"), ReadOnly=1)
xl.Application.Run("excelsheet.xlsm!modulename.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 did some modification to the SMNALLY's code so it can run in Python 3.5.2. This is my result:
#Import the following library to make use of the DispatchEx to run the macro
import win32com.client as wincl
def runMacro():
if os.path.exists("C:\\Users\\Dev\\Desktop\\Development\\completed_apps\\My_Macr_Generates_Data.xlsm"):
# DispatchEx is required in the newest versions of Python.
excel_macro = wincl.DispatchEx("Excel.application")
excel_path = os.path.expanduser("C:\\Users\\Dev\\Desktop\\Development\\completed_apps\\My_Macr_Generates_Data.xlsm")
workbook = excel_macro.Workbooks.Open(Filename = excel_path, ReadOnly =1)
excel_macro.Application.Run\
("ThisWorkbook.Template2G")
#Save the results in case you have generated data
workbook.Save()
excel_macro.Application.Quit()
del excel_macro
Just a quick note with a xlsm with spaces.
file = 'file with spaces.xlsm'
excel_macro.Application.Run('\'' + file + '\'' + "!Module1.Macro1")
I suspect you haven't authorize your Excel installation to run macro from an automated Excel. It is a security protection by default at installation. To change this:
File > Options > Trust Center
Click on Trust Center Settings... button
Macro Settings > Check Enable all macros
Hmm i was having some trouble with that part (yes still xD):
xl.Application.Run("excelsheet.xlsm!macroname.macroname")
cos im not using excel often (same with vb or macros, but i need it to use femap with python) so i finaly resolved it checking macro list:
Developer -> Macros:
there i saw that: this macroname.macroname should be sheet_name.macroname like in "Macros" list.
(i spend something like 30min-1h trying to solve it, so it may be helpful for noobs like me in excel) xD
A variation on SMNALLY's code that doesn't quit Excel if you already have it open:
import os, os.path
import win32com.client
if os.path.exists("excelsheet.xlsm"):
xl=win32com.client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open(os.path.abspath("excelsheet.xlsm"), ReadOnly=1) #create a workbook object
xl.Application.Run("excelsheet.xlsm!modulename.macroname")
wb.Close(False) #close the work sheet object rather than quitting excel
del wb
del xl
I tried the win32com way and xlwings way but I didn't get any luck. I use PyCharm and didn't see the .WorkBook option in the autocompletion for win32com.
I got the -2147352567 error when I tried to pass a workbook as variable.
Then, I found a work around using vba shell to run my Python script.
Write something on the XLS file you are working with when everything is done. So that Excel knows that it's time to run the VBA macro.
But the vba Application.wait function will take up 100% cpu which is wierd. Some people said that using the windows Sleep function would fix it.
Import xlsxwriter
Shell "C:\xxxxx\python.exe
C:/Users/xxxxx/pythonscript.py"
exitLoop = 0
wait for Python to finish its work.
Do
waitTime = TimeSerial(Hour(Now), Minute(Now), Second(Now) + 30)
Application.Wait waitTime
Set wb2 = Workbooks.Open("D:\xxxxx.xlsx", ReadOnly:=True)
exitLoop = wb2.Worksheets("blablabla").Cells(50, 1)
wb2.Close exitLoop
Loop While exitLoop <> 1
Call VbaScript
For Python 3.7 or later,(2018-10-10), I have to combine both #Alejandro BR and SMNALLY's answer, coz #Alejandro forget to define wincl.
import os, os.path
import win32com.client
if os.path.exists('C:/Users/jz/Desktop/test.xlsm'):
excel_macro = win32com.client.DispatchEx("Excel.Application") # DispatchEx is required in the newest versions of Python.
excel_path = os.path.expanduser('C:/Users/jz/Desktop/test.xlsm')
workbook = excel_macro.Workbooks.Open(Filename = excel_path, ReadOnly =1)
excel_macro.Application.Run("test.xlsm!Module1.Macro1") # update Module1 with your module, Macro1 with your macro
workbook.Save()
excel_macro.Application.Quit()
del excel_macro