Reputation: 2328
In Excel VBA, you can use the Intersect function which returns a range object that is the intersection of the arguments. You can then get a value from that like so.
Intersection("Name1", "Name2").Value
In a standard cell formula you can do the same thing:
=Name1 Name2
How do I accomplish this using xlrd? I've tried reading through the Name class and area2d looks like what I'll be using, but I don't know how to tie this all together.
Upvotes: 1
Views: 2227
Reputation: 17383
As far as I know, xlrd
does not natively support this kind of intersection functionality. For the kinds of rectangular ranges that you describe, you can fairly easily calculate the intersection though, using the Name
class, like you already suggested yourself.
The xlrd-0.9.0
distribution that I use with Python 2.7.2
has a directory examples
that shows how to work with named ranges. It comes with the file namesdemo.xls
which is a workbook from an older version of Excel (it says version 97-2004
).
An example of using that file to determine the cells in a range called Sales
is as follows:
>>> import xlrd
>>> book=xlrd.open_workbook('namesdemo.xls')
>>> nameObj = book.name_and_scope_map.get(('sales', -1))
>>> nameObj.area2d()[1:5]
(1, 2, 1, 14)
>>> nameObj.result.text
u'Sheet3!$B$2:$N$2'
You can parse that last result to obtain the rectangle of cells in your range, or use the elements [1:5]
from the tuple returned by the area2d()
function -- they represent rowxlo
, rowxhi
, colxlo
and colxhi
of the rectangle. Do the same thing for another range and then you can intersect them "manually".
Note the lower-case name 'sales'
in the call to name_and_scope_map.get()
. That is required because Excel does not have case-sensitive range names. The -1
parameter indicates that it should search for the name globally, on all sheets.
If saved in the newer Excel .xlsx
format, the Name
object seems to behave slightly differently:
>>> book=xlrd.open_workbook('namesdemo.xlsx')
>>> nameObj = book.name_and_scope_map.get(('sales', -1))
>>> nameObj.formula_text
u'Sheet3!$B$2:$N$2'
In this case, I have not found any way to get access to any actual coordinates via area2d()
:
>>> nameObj.area2d()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.7/site-packages/xlrd/book.py", line 291, in area2d
self.dump(self.book.logfile,
AttributeError: 'NoneType' object has no attribute 'logfile'
so it looks like you would need to parse the formula_text
string or check out the source code of xlrd
to see if you can fix it :-)
The example script xlrdnameAPIdemo.py
gives some more explanations, for example about how to look for named ranges in a particular scope/worksheet.
Upvotes: 1