The initial question and example is answered exactly by @jonnybazookatone answer below. The expanded example is a different error. It seems to be an xlrd
deficiency to me, but I've hacked a solution for what you want. First section is explanation, last section the hack.
Explanation
Looking at the more expanded example, the Error message is produced from the lines of code that handle the error condition on a Name
object where the result of evaluating the formulae in a Name
range has failed for some reason.
The actual reported error
AttributeError: 'NoneType' object has no attribute 'logfile'
is a secondary error - indicating that self.book
evaluates to None
for this Name
object.
Secondly - you are missing an important detail, I think, that your Excel file is in .xlsx
format. Note the trailing x. In the normal xls parser, the Name object doesn't have an attribute formula_text
, so your code fails with the following error.
Traceback (most recent call last):
File "D:\q1.py", line 16, in <module>
print cell_obj.formula_text
AttributeError: 'Name' object has no attribute 'formula_text'
Please be careful with your code examples - it took me a while to track that difference - xlsx
files are parsed by entirely different code within xlrd
. With the xlsx
fixed, I can reproduce your error.
The formula_text
attribute in this case is just giving the R-C notation reference to the cell that is your named range. It should be noted that the function that sets formula_text
is caveated "#### UNDER CONSTRUCTION ####"
and has been since the initial commit of the xlsx module in 2012.
The problem is - as far as I can see - formulae are never evaluated in the opening of an xlsx - so you hit the error that Name.res
is None and therefore you see your error. It seems to be an xlrd
bug / feature.
Hack
I have come up with a nasty hack that will do what you want in the case where your range is a single cell by expanding the cell reference. Note it will fail for named ranges referring to more than one cell as it is now, but could be easily modified to cope with that scenario:
hack = cell_obj.formula_text
(sheetName,ref) = hack.split('!')
(discard,colStr,rowStr) = ref.split('$')
col = 0
for i in range(len(colStr)):
colAdd = string.ascii_uppercase.index(colStr)
col += colAdd * 10**i
row = int(rowStr)-1
print("Trying to evaluate cell",row,col,"in sheet",sheetName)
print workbook.sheet_by_name(sheetName).cell(row,col)