Is there a more pythonic way of converting excel-style columns to numbers (starting with 1)?
Working code up to two letters:
This should do, in VBA, what you're looking for:
Function columnNumber(colLetter As String) As Integer
Dim colNumber As Integer
Dim i As Integer
colLetter = UCase(colLetter)
colNumber = 0
For i = 1 To Len(colLetter)
colNumber = colNumber + (Asc(Mid(colLetter, Len(colLetter) - i + 1, 1)) - 64) * 26 ^ (i - 1)
Next
columnNumber = colNumber
End Function
You can use it as you would an Excel formula--enter column, in letters, as a string (eg, "AA") and should work regardless of column length.
Your code breaks when dealing with three letters because of the way you're doing the counting--you need to use base 26.
I'm not sure I understand properly, do you want to "translate" the referenced C# code to python? If so, you were on the right track; just modify it so:
def column_to_number(c):
"""Return number corresponding to excel-style column."""
sum = 0
for l in c:
if not l in string.ascii_letters:
return False
sum*=26
sum+=ord(l.upper())-64
return sum
You could also do it by a series of multiplies and adds as follows. Here "A" will equal to 1
. Running time is O(n)
where n
is the length of the column, col
.
import functools
def spreadsheet_column_encoding(col):
return functools.reduce(
lambda result, char: result * 26 + ord(char) - ord("A") + 1, col, 0
)
E.g ZZ
= 702
:
0 * 26 + 90 - 65 + 1 = 26
26 * 26 + 90 - 65 + 1 = 702
P.S:
ord('Z') = 90
To convert number to column letter, kindly see my answer here. You get to do the opposite using division and modulus calculations.
After reading this, I decided to find a way to do it directly in Excel cells. It even accounts for columns after Z.
Just paste this formula into a cell of any row of any column and it will give you the corresponding number.
=IF(LEN(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))=2,
CODE(LEFT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1))-64*26)+
CODE(RIGHT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1)-64),
CODE(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))-64)
The theme here was to grab the letter of the column, get the Code()
of it and subtract 64, based on the fact that the ASCII character code for letter A
is 64.
just do :
print ws.Range("E2").Column
call example :
from win32com import client
xl = client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open("c:/somePath/file.xls")
xl.Visible = 1
ws = wb.Sheets("sheet 1")
print ws.Range("E2").Column
result :
>>5
For index that starts from zero (e.g. A = 0, B = 1, and so on):
def col_to_index(col):
A = ord('A')
return sum(i * 26 + (ord(c) - A) for i, c in enumerate(col[::-1].upper()))