Error in deleting excel sheet after exporting using python - python

I am trying to save the chart from Excel as an image file in Python. I am using WIn32com, the chart is getting exported as required but when I am trying to delete the ActiveSheet,it is giving me the error.
excel.ActiveSheet().Delete()
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)
pywintypes.com_error: (-2147352573, 'Member not found.', None, None)
Any help to overcome this error?
Below is my code:
import win32com.client as win32
def saveChart():
excel = win32.Dispatch("Excel.Application")
wb = excel.Workbooks.Open(r'C:\Users\projects\Rating.xlsx')
selection = "A1:K16"
xl_range = wb.Sheets("Categories").Range(selection)
excel.ActiveWorkbook.Sheets.Add().Name="image_sheet"
cht = excel.ActiveSheet.ChartObjects().Add(0,0,xl_range.Width, xl_range.Height)
xl_range.CopyPicture()
cht.Chart.Paste()
cht.Chart.Export(r'C:\Users\projects\MyExportedChart.png')
excel.DisplayAlerts = False
cht.Delete()
excel.ActiveSheet.Delete()
excel.DisplayAlerts = True
excel.ActiveWorkbook.Close()
I took the code from Export Charts from Excel as images using Python
Updated the code,which worked

Is ActiveSheet a field, like you're using it here:
cht = excel.ActiveSheet.ChartObjects().Add(0,0,xl_range.Width, xl_range.Height)
Or a method like you're using it here:
excel.ActiveSheet().Delete()
Since the first call doesn't give you the error, and the error says that the member is not found, I'm going to guess that the second one is wrong, and should be:
excel.ActiveSheet.Delete()

Related

Error handling for Macro calling using python

I am using python to run excel macros but the problem I am getting is that an error is popping up when I run the macros.
How can hide this error pop up?
Following are the piece of code :
try:
if os.path.exists("C:\\test.xlsm"):
# DispatchEx is required in the newest versions of Python.
excel_macro = win32com.client.DispatchEx("Excel.application")
excel_path = os.path.expanduser("C:\\test.xlsm")
workbook = excel_macro.Workbooks.Open(Filename=excel_path,ReadOnly=1)
excel_macro.Application.DisplayAlerts = False
excel_macro.Application.Run("Macro1")
# Save the results in case you have generated data
workbook.Save()
excel_macro.Application.Quit()
del excel_macro
except:
print("Error found while running the excel macro!")
excel_macro.Application.Quit()

Pass the variable `Nothing` using Python's `win32com`

I am trying to pass the variable Nothing in VBA using Python's win32com. I tried to use None but it returned 'Type dismatch.'
Could anyone please help?
Thank you!
An example:
' Book1.xlsm!Module1
Function test(arg As Object) As String
If arg Is Nothing Then
test = "Success"
Exit Function
Else
test = "Failure"
Exit Function
End If
End Function
And in Python:
import win32com.client
import os
import pythoncom
xl = win32com.client.Dispatch('Excel.Application')
xl.Visible = True
xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)
The REPL says:
runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')
Traceback (most recent call last):
File "<ipython-input-22-301693920f2c>", line 1, in <module>
runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads')
File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/shwang/Downloads/untitled0.py", line 16, in <module>
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty)
File "<COMObject <unknown>>", line 14, in Run
File "C:\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352561), None)
In VBA, Nothing is used as the uninitialized default value Object type which usually references COM objects (i.e., Excel object library or external application's object library). VBA's primitive integer, long, and string types cannot be assigned the Nothing value. And usually programmers use this at the end of code block to release objects from memory.
Hence, there is no strict translation between VBA's Nothing (a special value for COM types) and Python's value types including None which crudely means empty or no value for any type.
With that said, your code will not err out if you pass a COM object which you already initialize with xl. Below outputs FAILURE. If somehow you can declare an uninitialized COM object which then will carry Nothing then you can pass that into your function. But to call Dispatch requires a named object. Catch-22!
import win32com.client
import os
try:
xl = win32com.client.Dispatch('Excel.Application')
xl.Visible = True
wb = xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm'))
test_str = xl.Application.Run('test', xl)
print(test_str)
# FAILURE
wb.Close(False)
xl.Quit
except Exception as e:
print(e)
finally:
wb = None
xl = None
Here is a working example (in python) that passes VBA Nothing object to SolidWorks API.
import win32com.client
import pythoncom
swApp = win32com.client.Dispatch('SldWorks.Application')
Part = swApp.ActiveDoc
boolstatus = Part.Extension.SelectByID2("", "SKETCHCONTOUR", 75e-3, -4e-3, 0, False, 0, pythoncom.Nothing, 0)
print(boolstatus)
Here is the output in Sublime Text 3:
True
[Finished in 0.7s]
The script tries to select a sketch contour with the coordinates (75mm, -4mm). The "Callout" argument of the SolidWorks API "SelectByID2" is assigned as pythoncom.Nothing. For the script to work, the premise is that you are editing a sketch as shown in the attached figure below.
The attached figure shows what happens in SolidWorks (before | after).
Pass Nothing to SW API SelectByID2
Some background. I want to draw some electric motor geometry in SolidWorks via python because I already have the working python codes with other drawing tools (such as JMAG Designer, FEMM, or PyX).
Thanks for the post! Your discussion helps me find this.

Write dictionary of lists to xls in Python

1.5 month with Python. I am using Python 3.3.2 with WinPython http://code.google.com/p/winpython/ and port xlwt to Python 3 from here https://github.com/hansrwl/xlwt/tree/py3
This is dict with values as lists. It writes to xls file correctly with the following function.
sampleData = {'Books': ['Book_A', 'Book_B', 'Book_C'],
'Author': ['Author_A', 'Author_B', 'Author_C'],
'Price': ['Price_A', 'Price_B', 'Price_C']}
function:
def saveDataToNewFile(fileName, sheetName, data):
# Creating new workbook
wb = xlwt.Workbook()
# Creating new worksheet with the name specified
ws = wb.add_sheet(sheetName)
# Use dictionary keys as first row values(e.g. headers)
for colIdx, headerCaption in enumerate(data):
ws.write(0, colIdx, headerCaption)
# Use dict values as row values for corresponding columns
for rowIdx, itemVal in enumerate(data[headerCaption]):
ws.write(rowIdx + 1, colIdx, itemVal)
wb.save(fileName)
saveDataToNewFile('sample.xls', 'FirstSaveToXlsSample', sampleData)
- this saved correctly and opened with MS Excel.
I have the same data structure which is produced by this loop:
soup3 = defaultdict(list)
def init_fields(links_first_lvl):
for link in links_first_lvl[1:7]:
soup3['Дата'].append(BeautifulSoup(urllib.request.urlopen(link).read()).select('.author_data'))
soup3['Адрес'].append(link)
return soup3
Here is the structure, dictionary with lists as values (i use pprint to print in console beauty)
PPRINT:
{'url': [ 'http://www.ros.ru/article.php?chapter=1&id=20132503',
'http://www.ros.ru/article.php?chapter=1&id=20132411'],
'date': [[<div class="author_data"><b>Марта Моисеева
</b> № 30 (973) от 24.07.2013
<span class="rubr"> ВЛАСТЬ
</span></div>],
[<div class="author_data"><b>Ольга Космынина
</b> № 29 (972) от 17.07.2013
<span class="rubr"> ВЛАСТЬ
</span></div>]]
saveDataToNewFile('sample2.xls', 'FirstSaveToXlsSample', soup3)
The problem: if i try to save to xls i get an error:
.....
if isinstance(data, basestring):
NameError: global name 'basestring' is not defined
Edit: this is full error stack in console Pycharm
Traceback (most recent call last):
File "F:/Python/NLTK packages/parse_html_py3.3.2.py", line 91, in <module>
saveDataToNewFile('sample2.xls', 'FirstSaveToXlsSample', soup3)
File "F:/Python/NLTK packages/parse_html_py3.3.2.py", line 87, in saveDataToNewFile
ws.write(rowIdx + 1, colIdx, itemVal)
File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\site-packages\xlwt\Worksheet.py", line 1032, in write
self.row(r).write(c, label, style)
File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\site-packages\xlwt\Row.py", line 259, in write
self.__rich_text_helper(col, label, style, style_index)
File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\site-packages\xlwt\Row.py", line 276, in __rich_text_helper
if isinstance(data, basestring):
NameError: global name 'basestring' is not defined
I don't know why, it should work because the structure is the same.
The library you're using is written to work on python 2.x only. Download latest python 2.x from here and try again.
Much lower overhead with LibreOffice. Open the LibreOffice install folder, and scrounge your UNO references from all of the current examples there. Save as XLS. Done.
As the comments suggest, the problem is you are using code that is still written for Python 2, however, before you downgrade to Python 2 as nosklo suggests, make sure you installed the xlwt from the Python 3 branch. After you cloned the xlwt repository, did you remember to perform
git checkout -b py3 origin/py3
before you performed your installation?
If you remembered and you still get the basestring error, then the py3 branch is still incomplete, and you will need to downgrade to Python 2 to run the code in master branch.
You may try changing 'basestring' to 'str'
if isinstance(data, basestring):
NameError: global name 'basestring' is not defined
Probably the object has not such attribute and your test fails, since it just test if the object type is an instance or not, and it implies that your attribute or object already exists.
I recommend you to perform a prior test to verify if the attribute or object exists such as hasattr() or if you consider to use self you can read self.__dict__ to find the existing attributes.

Python error when retrieving a url from a database and opening it with webbrowser()

I am trying to make an app similar to StumbleUpon using Python as a back end for a personal project . From the database I retrieve a website name and then I open that website with webbrowser.open("http://www.website.com"). Sounds pretty straight forward right but there is a problem. When I try to open the website with webbrowser.open("website.com") it returns the following error:
File "fetchall.py", line 18, in <module>
webbrowser.open(x)
File "/usr/lib/python2.6/webbrowser.py", line 61, in open
if browser.open(url, new, autoraise):
File "/usr/lib/python2.6/webbrowser.py", line 190, in open
for arg in self.args]
TypeError: expected a character buffer object
Here is my code:
import sqlite3
import webbrowser
conn = sqlite3.connect("websites.sqlite")
cur = conn.cursor()
cur.execute("SELECT WEBSITE FROM COLUMN")
x = cur.fetchmany(1)
webbrowser.open(x)
EDIT
Okay thanks for the reply, but now I'm receiving this: "Error showing URL: Error stating file '/home/user/(u'http:bbc.co.uk,)': No such file or directory".
What's going on ?
webbrowser.open is expecting a character buffer, but fetchmany returns a list. So webbrowser.open(x[0]) should do the trick.

Automation Excel From Python getting "TypeError: 'unicode' object is not callable" on Range.Address

As per the Title, when I run the below code in Python 2.6 I get the below error on line:
print range.Address(RowAbsolute=False,
ColumnAbsolute=False)"
I know what the error means but the MSDN page (http://msdn.microsoft.com/en-us/library/aa174749(v=office.11).aspx) said this is valid and has an example in it. I have tried this in EXCEL VBA and it works.
TypeError: 'unicode' object is not
callable
Any ideas?
Thanks.
Doanld
import win32com.client
xlApp = win32com.client.DispatchEx('Excel.Application')
xlApp.Visible = True
objWkb = xlApp.Workbooks.Add()
objSht = objWkb.Worksheets(1)
objSht.Cells(2,2).Value = '1'
objSht.Cells(2,3).Value = '2'
range = objSht.Cells(2,4)
range.Value = '=%s+%s' % (objSht.Cells(2,2).Address, objSht.Cells(2,3).Address)
range.AddComment('Test Comment')
print range.Address
print range.Address(RowAbsolute=False, ColumnAbsolute=False)
objWkb.Close(SaveChanges=False) #to avoid prompt
xlApp.Quit()
xlApp.Visible = 0 #must make Visible=0 before del self.excelapp or EXCEL.EXE remains in memory.
del xlApp
Range.Address is a parameterized property. It provides a value when accessed like a property, but can be called like a method with parameters as well. PyWin32 does not support parameterized properties directly. It works around this by providing a GetXXXXX method for each property that supports parameters. Use:
range.GetAddress(RowAbsolute=False,ColumnAbsolute=False)
It can be used with or without keywords.
Use either:
range.GetAddress()
range.Address
To read the property.

Categories