How to force xlwings to use COMRetryObjectWrapper instead of win32com api? - python

I recently had to reformat my computer, and now whenever I try to call the Sheet.api property in xlwings, I get the following result:
>>> wb = xw.Book('<path-to-wb>')
>>> sht = wb.sheets['Sheet1']
>>> sht.api
<win32com.gen_py.Microsoft Excel 16.0 Object Library._Worksheet instance at 0x1293314650312>
Previously, sht.api returned me a <xlwings._xlwindows.COMRetryObjectWrapper at 0x1e816dda7c8> object.
Is this some kind of windows configuration that I have to restore? Why is xlwings behaving differently all of a sudden?

This isn't all of a sudden but the effect of upgrading to a new version where the RetryObjectWrapper is printed with more meaningful information. It's still the same object though as you will see when you print its type:
>>> type(sht.api)
<class 'xlwings._xlwindows.COMRetryObjectWrapper'>

Related

CATIA V5 Automation with Python Script

I'm a Python beginner and am attempting to do some automation in CATIA (Dassault Systemes CAD pacakge) with it, but I've run into an issue that I've been unable to solve despite searching extensively for a solution.
I'm trying to mimic the behavior of this VBA macro that was written within CATIAs native editor interface:
Sub CATMain()
Dim drawingDocument1 As DrawingDocument
Set drawingDocument1 = CATIA.ActiveDocument
Dim selection1 As Selection
Set selection1 = drawingDocument1.Selection
selection1.Search "CATDrwSearch.DrwDimension,all"
For i = 1 To selection1.Count
Dim Dimension1 As DrawingDimension
Set Dimension1 = selection1.Item(i).Value
Dim DimDimValue As DrawingDimValue
Set DimDimValue = Dimension1.GetValue
DimDimValue.SetFormatPrecision 1, 0.001
Next
selection1.Clear
End Sub
To do so I wrote this Python script:
import win32com.client
CATIA = win32com.client.Dispatch('CATIA.Application')
ad = CATIA.ActiveDocument
sel = ad.Selection
sel.Search("CATDrwSearch.DrwDimension,all")
for i in range(1, sel.Count2+1):
aDim = sel.Item2(i).Value
aDimValue = aDim.GetValue
aDimValue.SetFormatPrecision(1,0.001)
sel.Clear
Everything works except for the last operation within the for loop which returns the error:
Traceback (most recent call last):
<bound method DrawingDimension.GetValue of <win32com.gen_py.CATIA V5
DraftingInterfaces Object Library.DrawingDimension instance at 0x67582896>>
File "C:/...", line 15, in <module>
aDimValue.SetFormatPrecision(1,0.001)
AttributeError: 'function' object has no attribute 'SetFormatPrecision'
Note that I used makepy to early bind the COM object otherwise Python doesn't recognize it (returns COMObject [unknown]), but from what I understand that shouldn't impact the script behavior.
I haven't been able to troubleshoot the error successfully because everything I can find suggests the object should have the attribute SetFormatPrecision. I've tried a bunch of other attributes that it should have as well, and none of them work. Because I'm trying to operate on a COM object, I'm not aware of a way to get a comprehensive list of legal attributes, or a way to get any information on the type of object I have stored in aDimValue
I inspected the makepy output file and it does include a function definition for SetFormatPrecision so my guess is I have a syntax issue, but I'm at a loss for what it is.
I know it's a narrowly focused question, but I'm hoping somebody with knowledge of CATIA Object Libraries sees this. And although I don't expect it, if somebody wants to go the extra mile, there's documentation on CATIAs Object Libraries here:
http://catiadoc.free.fr/online/CAAScdBase/CAAScdAutomationHome.htm
Drafting > Drafting Reference > DrawingDimValue
to get to the specific object I think I'm working with in aDimValue
Any help is appreciated. Thanks.
aDim.GetValue returns the function object, rather than calling the function. Use aDim.GetValue(). Same with sel.Clear() on the last line.

HTML not rendering properly with Canopy 1.7.1.3323 / IPython 4.1.2

I've just upgraded to Canopy 1.7.1; I think this problem stems from the change in IPython version from 2.4.1 to 4.1.2.
The issue I have is that calling a DataFrame object in Python seems to use the __print__ method, i.e. there's no difference between typing print df and df into the interpreter, and unfortunately this gives me an all-text output rather than the nice tables I normally get.
So I get something that looks exactly like this when I call df rather than a table:
date flag
1 20151102 0
98663 20151101 1
This happened immediately after the upgrade, and I also tried updating all my packages. I've also looked at this and this, but none of the solutions there work for me. ('display.notebook_repr_html' is already True)
EDIT: The issue seems to do with rendering HTML; typing in
from IPython.core.display import display, HTML
display(HTML('<h1>Hello, world!</h1>'))
returns
<IPython.core.display.HTML object>
This has purposely been disabled. I have requested a way to have it re-enabled but but unsupported.
Please see the request. https://github.com/jupyter/qtconsole/issues/165

Does xlwings support "Wrap Text" property?

Can I control the "Wrap Text" property of a cell using Python+xlwings?
It's currently not implemented but I've opened a feature request here. In the meantime, you can always work around by accessing the underlying COM object on Windows: mysheet.range('A1').api.WrapText = True or appscript object on Mac: mysheet.range('A1').api.wrap_text.set(True).
For anybody like me who comes to this now and doesn't find these solutions are working, I found accessing the pywin32 API directly with work_sheet.range('A:A').api.WrapText = True worked in Python 3.7 and xlwings 0.15.8 in Windows 7 and Excel 2010.
For the newest xlwings version:
import xlwings as xw
wb1 = xw.Book('Book1.xlsm').sheets['Sheet1']
wb1.range('A1').value="It's currently not implemented but I've opened a feature request here. In the meantime, you can always work around by accessing the underlying COM object on Windows: "
wb1.range('A1').WrapText = True
xlwings 0.19.5 this works:
sht.range('A1').api.WrapText = True

Loading a document on OpenOffice using an external Python program

I'm trying to create a python program (using pyUNO ) to make some changes on a OpenOffice calc sheet.
I've launched previously OpenOffice on "accept" mode to be able to connect from an external program. Apparently, should be as easy as:
import uno
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext)
# connect to the running office
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;"
"urp;StarOffice.ComponentContext")
smgr = ctx.ServiceManager
# get the central desktop object
DESKTOP =smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
#The calling it's not exactly this way, just to simplify the code
DESKTOP.loadComponentFromURL('file.ods')
But I get an AttributeError when I try to access loadComponentFromURL. If I make a dir(DESKTOP), I've see only the following attributes/methods:
['ActiveFrame', 'DispatchRecorderSupplier', 'ImplementationId', 'ImplementationName',
'IsPlugged', 'PropertySetInfo', 'SupportedServiceNames', 'SuspendQuickstartVeto',
'Title', 'Types', 'addEventListener', 'addPropertyChangeListener',
'addVetoableChangeListener', 'dispose', 'disposing', 'getImplementationId',
'getImplementationName', 'getPropertySetInfo', 'getPropertyValue',
'getSupportedServiceNames', 'getTypes', 'handle', 'queryInterface',
'removeEventListener', 'removePropertyChangeListener', 'removeVetoableChangeListener',
'setPropertyValue', 'supportsService']
I've read that there are where a bug doing the same, but on OpenOffice 3.0 (I'm using OpenOffice 3.1 over Red Hat5.3). I've tried to use the workaround stated here, but they don't seems to be working.
Any ideas?
It has been a long time since I did anything with PyUNO, but looking at the code that worked last time I ran it back in '06, I did my load document like this:
def urlify(path):
return uno.systemPathToFileUrl(os.path.realpath(path))
desktop.loadComponentFromURL(
urlify(tempfilename), "_blank", 0, ())
Your example is a simplified version, and I'm not sure if you've removed the extra arguments intentionally or not intentionally.
If loadComponentFromURL isn't there, then the API has changed or there's something else wrong, I've read through your code and it looks like you're doing all the same things I have.
I don't believe that the dir() of the methods on the desktop object will be useful, as I think there's a __getattr__ method being used to proxy through the requests, and all the methods you've printed out are utility methods used for the stand-in object for the com.sun.star.frame.Desktop.
I think perhaps the failure could be that there's no method named loadComponentFromURL that has exactly 1 argument. Perhaps giving the 4 argument version will result in the method being found and used. This could simply be an impedance mismatch between Python and Java, where Java has call-signature method overloading.
This looks like issue 90701: http://www.openoffice.org/issues/show_bug.cgi?id=90701
See also http://piiis.blogspot.com/2008/10/pyuno-broken-in-ooo-30-with-system.html and http://udk.openoffice.org/python/python-bridge.html

How do I import a COM object namespace/enumeration in Python?

I'm relatively new to programming/python, so I'd appreciate any help I can get. I want to save an excel file as a specific format using Excel through COM. Here is the code:
import win32com.client as win32
def excel():
app = 'Excel'
x1 = win32.gencache.EnsureDispatch('%s.Application' % app)
ss = x1.Workbooks.Add()
sh = ss.ActiveSheet
x1.Visible = True
sh.Cells(1,1).Value = 'test write'
ss.SaveAs(Filename="temp.xls", FileFormat=56)
x1.Application.Quit()
if __name__=='__main__':
excel()
My question is how do I specify the FileFormat if I don't explicitly know the code for it? Browsing through the documentation I find the reference at about a FileFormat object. I'm clueless on how to access the XlFileFormat object and import it in a way that I can find the enumeration value for it.
Thanks!
This question is a bit stale, but for those reaching this page from Google (as I did) my solution was accessing the constants via the win32com.client.constants object instead of on the application object itself as suggested by Eric. This lets you use enum constants just like in the VBE:
>>> import win32com.client
>>> xl = win32com.client.gencache.EnsureDispatch('Excel.Application')
>>> C = win32com.client.constants
>>> C.xlWorkbookNormal
-4143
>>> C.xlCSV
6
>>> C.xlErrValue
2015
>>> C.xlThemeColorAccent1
5
Also, unless you've manually run the makepy utility, the constants may not be available if initializing the application with the regular win32com.client.Dispatch(..) method, which was another issue I was having. Using win32com.client.gencache.EnsureDispatch(..) (as the questioner does) checks for and generates the Python bindings at runtime if required.
I found this ActiveState page to be helpful.
When I used COM to access quickbooks, I could reach the constants defined under a constants member of the object. The code looked something like this (you'll be intersted in the third line):
self._session_manager.OpenConnection2("",
application_name,
QBFC8Lib.constants.ctLocalQBD)
I'm not sure if this will work, but try this:
import win32com.client as win32
def excel():
app = 'Excel'
x1 = win32.gencache.EnsureDispatch('%s.Application' % app)
ss = x1.Workbooks.Add()
sh = ss.ActiveSheet
x1.Visible = True
sh.Cells(1,1).Value = 'test write'
ss.SaveAs(Filename="temp.xls", FileFormat=x1.constants.xlWorkbookNormal)
x1.Application.Quit()
if __name__=='__main__':
excel()
Replace xlWorkbookNormal with whatever format your trying to choose in the X1FileFormat web page you posted in your question.
All of the file format constants are documented here
As a general rule I find it really useful to pre-record any code in the VBA IDE in Excel. This way you can find out all the values of constants etc that you need to use within your python code. You can also make sure stuff will work from within a more controlled environment.

Categories