556

How do you convert a numerical number to an Excel column name in C# without using automation getting the value directly from Excel.

Excel 2007 has a possible range of 1 to 16384, which is the number of columns that it supports. The resulting values should be in the form of excel column names, e.g. A, AA, AAA etc.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
robertkroll
  • 8,544
  • 6
  • 24
  • 24
  • 2
    Not forgetting that there are limits in the number of columns available. E.g. * Excel 2003 (v11) goes up to IV, 2^8 or 256 columns). * Excel 2007 (v12) goes up to XFD, 2^14 or 16384 columns. – Unsliced Oct 08 '08 at 08:34
  • 1
    possible duplicate of [How do I find the Excel column name that corresponds to a given integer?](http://stackoverflow.com/questions/22708/how-do-i-find-the-excel-column-name-that-corresponds-to-a-given-integer) – Daniel Trebbien Jun 19 '13 at 14:47
  • This question is tagged C# and excel. I flag this question as outdated, because we live in 2016 and there is [EPPLUS](https://www.nuget.org/packages/EPPlus). A commonly used C# library to create advanced Excel spreadsheets on the server. Which is made available under: GNU Library General Public License (LGPL). Using EPPlus you can easily get the Column string. – Tony_KiloPapaMikeGolf Dec 14 '16 at 09:42
  • Note that the row and column limits depend more on the file format than the Excel version, and can be different for each workbook. They can change even for the same workbook if it is saved to older or newer format. – Slai Dec 14 '16 at 19:45
  • @Tony_KiloPapaMikeGolf I don't think this is outdated. In fact, EPPLUS have changed their licensing, which may not be suitable to all for a variety of reasons. Also, why bring in a library if all you need is something this simple? I'm exporting data in Excel format using OpenXML and I've only needed a couple of algorithms like what is asked here. Why add a library to the mix? Needs vary. The question is not outdated and is relevant for simple use cases. That said, EPPLUS is a pretty cool library. ;) – MetalMikester Jun 22 '20 at 13:07
  • In case you are needing this for Aspose Cells, they have [built-in helpers](https://docs.aspose.com/cells/net/names-and-indices/). – Uwe Keim Sep 16 '20 at 07:58

60 Answers60

1047

Here's how I do it:

private string GetExcelColumnName(int columnNumber)
{
    string columnName = "";

    while (columnNumber > 0)
    {
        int modulo = (columnNumber - 1) % 26;
        columnName = Convert.ToChar('A' + modulo) + columnName;
        columnNumber = (columnNumber - modulo) / 26;
    } 

    return columnName;
}
Craig Brown
  • 1,891
  • 1
  • 24
  • 25
Graham
  • 14,885
  • 4
  • 36
  • 42
  • 76
    This code works well. It assumes Column A is columnNumber 1. I had to make a quick change to account for my system using Column A as columnNumber 0. I changed the line int dividend to int dividend = columnNumber + 1; Keith – Keith Sirmons Aug 06 '09 at 18:33
  • You could probably make this slightly faster by removing the string concatenations and using a StringBuilder. I work with OpenXML, so I need all the speed I can muster. +1 though, this is correct. – Jduv May 04 '11 at 17:08
  • 16
    @Jduv just tried it out using `StringBuilder`. It takes about twice as long. It's a very short string (max 3 characters - Excel 2010 goes up to column XFD), so maximum of 2 string concatenations. (I used 100 iterations of translating the integers 1 to 16384, i.e. Excel columns A to XFD, as the test). – Graham May 04 '11 at 19:06
  • 21
    For better understanding, I would replace the 65 with 'A' – Stef Heyenrath Nov 11 '11 at 11:12
  • 1
    Just about to write this myself, glad I checked, this is more elegant then what I was thinking about doing. – TravisWhidden Dec 26 '12 at 21:23
  • 11
    I think it would be better to use 'A' instead of 65. And 26 could be evaluated as ('Z' - 'A' + 1), for example: const int AlphabetLength = 'Z' - 'A' + 1; – Denis Gladkiy Nov 03 '13 at 06:14
  • 1
    @Graham I've just tried StringBuilder - it's just ~1.2 slower than strings concatenation (not 2 times). But anyway slower than string. – Denis Gladkiy Nov 03 '13 at 06:28
  • Why are you using YET ANOTHER variable (dividend) allocated on the stack? Use the parameter itself (columnNumber)... It is not a reference nor a pointer, so it is perfectly safe to use it - and it is as fast as yet another local variable. PS: parameters ARE local variables... – ZioBit Jun 13 '16 at 08:30
  • 10
    Though I am late to the game, the code is far from being optimal.Particularly, you don't have to use the `modulo`, call `ToString()` and apply `(int)` cast. Considering that in most cases in C# world you would start numbering from 0, here is my revision: public static string GetColumnName(int index) // zero-based { const byte BASE = 'Z' - 'A' + 1; string name = String.Empty; do { name = Convert.ToChar('A' + index % BASE) + name; index = index / BASE - 1; } while (index >= 0); return name; } – Herman Kan Aug 18 '16 at 12:23
  • @HermanKan how do I modify it so that not zero-based. Excel columns are not zero-based, they start at 1. Otherwise it's useless. – Leo Gurdian Nov 28 '16 at 18:56
  • 1
    @LeoGurdian that is pretty easy: `... GetColumnName(int col) { int index = col - 1; ...` – Herman Kan Nov 29 '16 at 05:31
  • I don't know how it's chosen as correct answer. Since for me it's failing for basic test case: It's giving AZ when I pass 26. Correct answer would be Z. Please correct me if I am missing something. – Kiran Dec 29 '16 at 13:22
  • Hi @Graham, Is it? I have copied this snippet and executed without any change in C# but I didn't get Z as answer when I gave input 26. Is it anything to do with language? – Kiran Dec 30 '16 at 05:22
  • Hi @bill, I forgot to reply again. The snippet shown here actually worked for me. I did some mistake in copying. Let me know if you face any issue. – Kiran Jul 12 '17 at 08:56
  • I see. It seems that dividend = (int)((dividend - modulo-1) / 26) will work too? – bill Jul 12 '17 at 22:57
  • @HermanKan: I hope you have done some performance tests that clearly show that `modulo` is suboptimal when compared to `.ToString()`? XD – quetzalcoatl May 05 '20 at 16:32
  • @Graham can u give short explanation of why (col - m) / 26? My explanation is way too verbose. (1) `For XXXA...XXXZ, (remainder - m) / 26 is [N, N, ... N], remainder/26 will be [N, N, ... N+1]` (2) `For XXXZ...XXXXA, (remainder - m) / 26 is N, N+1, remainder/26 will be N, N` (3) the subtract actually just fixes the 2 boundary items. – addlistener May 02 '22 at 10:27
66

If anyone needs to do this in Excel without VBA, here is a way:

=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")

where colNum is the column number

And in VBA:

Function GetColumnName(colNum As Integer) As String
    Dim d As Integer
    Dim m As Integer
    Dim name As String
    d = colNum
    name = ""
    Do While (d > 0)
        m = (d - 1) Mod 26
        name = Chr(65 + m) + name
        d = Int((d - m) / 26)
    Loop
    GetColumnName = name
End Function
vzczc
  • 9,270
  • 5
  • 52
  • 61
  • 2
    Example: =SUBSTITUTE(TEXT(ADDRESS(1,1000,4),""),"1","") – Dolph Oct 13 '10 at 18:55
  • Yes, I use Excel in a locale where ; is used in place of , to separate function arguments in Excel. Thanks for pointing this out. – vzczc Oct 14 '10 at 07:05
  • 2
    I did this without the TEXT function. What is the purpose of the TEXT function? – dayuloli Jan 28 '14 at 18:49
  • 2
    @dayuloli Long time since this answer was written, you are correct, the TEXT function does not serve a purpose here. Will update the answer. – vzczc Jan 29 '14 at 09:03
28

Sorry, this is Python instead of C#, but at least the results are correct:

def ColIdxToXlName(idx):
    if idx < 1:
        raise ValueError("Index is too small")
    result = ""
    while True:
        if idx > 26:
            idx, r = divmod(idx - 1, 26)
            result = chr(r + ord('A')) + result
        else:
            return chr(idx + ord('A') - 1) + result


for i in xrange(1, 1024):
    print "%4d : %s" % (i, ColIdxToXlName(i))
RoMa
  • 799
  • 1
  • 8
  • 25
  • Yes I downVoted , don't post Python when the question is C#. And yes , more people should do this. – KyloRen Jul 21 '19 at 09:31
  • 5
    The title of the question does not imply C#, so many people may come here that don't exepect C#. Hence, thanks for sharing in Python! – Tim Sep 16 '19 at 08:35
27

You might need conversion both ways, e.g from Excel column adress like AAZ to integer and from any integer to Excel. The two methods below will do just that. Assumes 1 based indexing, first element in your "arrays" are element number 1. No limits on size here, so you can use adresses like ERROR and that would be column number 2613824 ...

public static string ColumnAdress(int col)
{
  if (col <= 26) { 
    return Convert.ToChar(col + 64).ToString();
  }
  int div = col / 26;
  int mod = col % 26;
  if (mod == 0) {mod = 26;div--;}
  return ColumnAdress(div) + ColumnAdress(mod);
}

public static int ColumnNumber(string colAdress)
{
  int[] digits = new int[colAdress.Length];
  for (int i = 0; i < colAdress.Length; ++i)
  {
    digits[i] = Convert.ToInt32(colAdress[i]) - 64;
  }
  int mul=1;int res=0;
  for (int pos = digits.Length - 1; pos >= 0; --pos)
  {
    res += digits[pos] * mul;
    mul *= 26;
  }
  return res;
}
bluish
  • 26,356
  • 27
  • 122
  • 180
Arent Arntzen
  • 271
  • 3
  • 2
14

I discovered an error in my first post, so I decided to sit down and do the the math. What I found is that the number system used to identify Excel columns is not a base 26 system, as another person posted. Consider the following in base 10. You can also do this with the letters of the alphabet.

Space:.........................S1, S2, S3 : S1, S2, S3
....................................0, 00, 000 :.. A, AA, AAA
....................................1, 01, 001 :.. B, AB, AAB
.................................... …, …, … :.. …, …, …
....................................9, 99, 999 :.. Z, ZZ, ZZZ
Total states in space: 10, 100, 1000 : 26, 676, 17576
Total States:...............1110................18278

Excel numbers columns in the individual alphabetical spaces using base 26. You can see that in general, the state space progression is a, a^2, a^3, … for some base a, and the total number of states is a + a^2 + a^3 + … .

Suppose you want to find the total number of states A in the first N spaces. The formula for doing so is A = (a)(a^N - 1 )/(a-1). This is important because we need to find the space N that corresponds to our index K. If I want to find out where K lies in the number system I need to replace A with K and solve for N. The solution is N = log{base a} (A (a-1)/a +1). If I use the example of a = 10 and K = 192, I know that N = 2.23804… . This tells me that K lies at the beginning of the third space since it is a little greater than two.

The next step is to find exactly how far in the current space we are. To find this, subtract from K the A generated using the floor of N. In this example, the floor of N is two. So, A = (10)(10^2 – 1)/(10-1) = 110, as is expected when you combine the states of the first two spaces. This needs to be subtracted from K because these first 110 states would have already been accounted for in the first two spaces. This leaves us with 82 states. So, in this number system, the representation of 192 in base 10 is 082.

The C# code using a base index of zero is

    private string ExcelColumnIndexToName(int Index)
    {
        string range = string.Empty;
        if (Index < 0 ) return range;
        int a = 26;
        int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
        Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
        for (int i = x+1; Index + i > 0; i--)
        {
            range = ((char)(65 + Index % a)).ToString() + range;
            Index /= a;
        }
        return range;
    }

//Old Post

A zero-based solution in C#.

    private string ExcelColumnIndexToName(int Index)
    {
        string range = "";
        if (Index < 0 ) return range;
        for(int i=1;Index + i > 0;i=0)
        {
            range = ((char)(65 + Index % 26)).ToString() + range;
            Index /= 26;
        }
        if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
        return range;
    }
John
  • 141
  • 1
  • 3
  • 1
    ooh i don't know why but i like this solution. Nothing fancy just good use of logic... easily readable code for levels of programmer. One thing though, I believe its best practise to specify an empty string in C# as string range = string.Empty; – Anonymous Type Aug 09 '10 at 22:15
  • Yes, very nice explanation. But could you also just state that it is not base 27 either? Your explanation shows this when studied, but a quick mention at the top may save a few other people some time. – Marius Sep 02 '13 at 19:57
13

This answer is in javaScript:

function getCharFromNumber(columnNumber){
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo).toString() + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    } 
    return  columnName;
}
MaVRoSCy
  • 17,747
  • 15
  • 82
  • 125
10

I'm surprised all of the solutions so far contain either iteration or recursion.

Here's my solution that runs in constant time (no loops). This solution works for all possible Excel columns and checks that the input can be turned into an Excel column. Possible columns are in the range [A, XFD] or [1, 16384]. (This is dependent on your version of Excel)

private static string Turn(uint col)
{
    if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
        throw new ArgumentException("col must be >= 1 and <= 16384");

    if (col <= 26) //one character
        return ((char)(col + 'A' - 1)).ToString();

    else if (col <= 702) //two characters
    {
        char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
        char secondChar = (char)(col % 26 + 'A' - 1);

        if (secondChar == '@') //Excel is one-based, but modulo operations are zero-based
            secondChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}", firstChar, secondChar);
    }

    else //three characters
    {
        char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
        char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
        char thirdChar = (char)(col % 26 + 'A' - 1);

        if (thirdChar == '@') //Excel is one-based, but modulo operations are zero-based
            thirdChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
    }
}
user2023861
  • 8,030
  • 9
  • 57
  • 86
  • 2
    FYI: @Graham's answer (and probably the others) are more general than yours: they support 4+ characters in the column names. And that's precisely why they are iterative. – bernard paulus Jul 10 '13 at 14:25
  • In fact, if they used unlimited integers and not `int`s, the resulting column name could be arbitrarily long (that's the case of the python answer, for instance) – bernard paulus Jul 10 '13 at 14:25
  • 2
    If my data is ever too large for a 16,384-column spreadsheet, I'll shoot myself in the head. Anyways, Excel doesn't even support all of the possible three-letter columns (it cuts off at XFD leaving out 1,894 columns). Right now anyways. I'll update my answer in the future as required. – user2023861 Jul 10 '13 at 14:45
  • :) didn't knew that! My comment was on the theoretical properties of the different algorithms. – bernard paulus Jul 10 '13 at 15:17
  • This one is probably the simplest and clearest solution. – Juan Jul 11 '18 at 06:24
  • Too complex. Loops are legitimate way to keep code short & readable. – Mulli Jul 07 '19 at 13:50
  • +1 for showing what the maximum cell reference is - you wouldn't believe how difficult it is to find that info on the web. – controlbox Dec 15 '19 at 15:43
  • @controlbox here's a tip. Open a new Excel spreadsheet and click on any cell. Then hold down control and click the right arrow. It'll go out to column XFD. If you click the down arrow instead (while holding down control), you'll go to row 1048576. This is a quick way to find the max cell reference. – user2023861 Dec 17 '19 at 14:10
  • Won't this give trailing spaces in the return value? – David Heffernan Apr 20 '22 at 12:03
10
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
    int nChar = nCol % 26;
    nCol = (nCol - nChar) / 26;
    // You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
    sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;

Update: Peter's comment is right. That's what I get for writing code in the browser. :-) My solution was not compiling, it was missing the left-most letter and it was building the string in reverse order - all now fixed.

Bugs aside, the algorithm is basically converting a number from base 10 to base 26.

Update 2: Joel Coehoorn is right - the code above will return AB for 27. If it was real base 26 number, AA would be equal to A and the next number after Z would be BA.

int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
    int nChar = nCol % 26;
    if (nChar == 0)
        nChar = 26;
    nCol = (nCol - nChar) / 26;
    sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
    sCol = sChars[nCol] + sCol;
Community
  • 1
  • 1
Franci Penov
  • 74,861
  • 18
  • 132
  • 169
  • Code will not compile (sCol not initialized). If it does, it will not give the right answer. – Peter Oct 08 '08 at 09:05
  • 6
    THIS ANSWER IS WRONG. Base26 isn't good enough. Think about what happens when your wrap from Z to AA. If A is equivalent to the 0 digit, then it's like wraping from 9 to 00. If it's the 1 digits, it's like wrapping from 9 to 11. – Joel Coehoorn Nov 21 '08 at 21:41
  • 5
    I'm not clear after the updates... is either of the algorithms now correct? And if so, which one, the second one? I'd edit this and make it obvious for posterity.... – JoeCool Jul 27 '09 at 19:51
10

Easy with recursion.

public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
  int baseValue = Convert.ToInt32('A');
  int columnNumberZeroBased = columnNumberOneBased - 1;

  string ret = "";

  if (columnNumberOneBased > 26)
  {
    ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
  }

  return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
Peter
  • 3,563
  • 5
  • 30
  • 43
10

Same implementation in Java

public String getExcelColumnName (int columnNumber) 
    {     
        int dividend = columnNumber;   
        int i;
        String columnName = "";     
        int modulo;     
        while (dividend > 0)     
        {        
            modulo = (dividend - 1) % 26;         
            i = 65 + modulo;
            columnName = new Character((char)i).toString() + columnName;        
            dividend = (int)((dividend - modulo) / 26);    
        }       
        return columnName; 
    }  
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Balaji.N.S
  • 745
  • 3
  • 13
  • 28
9

..And converted to php:

function GetExcelColumnName($columnNumber) {
    $columnName = '';
    while ($columnNumber > 0) {
        $modulo = ($columnNumber - 1) % 26;
        $columnName = chr(65 + $modulo) . $columnName;
        $columnNumber = (int)(($columnNumber - $modulo) / 26);
    }
    return $columnName;
}
Stephen Fuhry
  • 12,624
  • 6
  • 56
  • 55
9

Just throwing in a simple two-line C# implementation using recursion, because all the answers here seem far more complicated than necessary.

/// <summary>
/// Gets the column letter(s) corresponding to the given column number.
/// </summary>
/// <param name="column">The one-based column index. Must be greater than zero.</param>
/// <returns>The desired column letter, or an empty string if the column number was invalid.</returns>
public static string GetColumnLetter(int column) {
    if (column < 1) return String.Empty;
    return GetColumnLetter((column - 1) / 26) + (char)('A' + (column - 1) % 26);
}
Extragorey
  • 1,654
  • 16
  • 30
9

Although there are already a bunch of valid answers1, none get into the theory behind it.

Excel column names are bijective base-26 representations of their number. This is quite different than an ordinary base 26 (there is no leading zero), and I really recommend reading the Wikipedia entry to grasp the differences. For example, the decimal value 702 (decomposed in 26*26 + 26) is represented in "ordinary" base 26 by 110 (i.e. 1x26^2 + 1x26^1 + 0x26^0) and in bijective base-26 by ZZ (i.e. 26x26^1 + 26x26^0).

Differences aside, bijective numeration is a positional notation, and as such we can perform conversions using an iterative (or recursive) algorithm which on each iteration finds the digit of the next position (similarly to an ordinary base conversion algorithm).

The general formula to get the digit at the last position (the one indexed 0) of the bijective base-k representation of a decimal number m is (f being the ceiling function minus 1):

m - (f(m / k) * k)

The digit at the next position (i.e. the one indexed 1) is found by applying the same formula to the result of f(m / k). We know that for the last digit (i.e. the one with the highest index) f(m / k) is 0.

This forms the basis for an iteration that finds each successive digit in bijective base-k of a decimal number. In pseudo-code it would look like this (digit() maps a decimal integer to its representation in the bijective base -- e.g. digit(1) would return A in bijective base-26):

fun conv(m)
    q = f(m / k)
    a = m - (q * k)
    if (q == 0)
        return digit(a)
    else
        return conv(q) + digit(a);

So we can translate this to C#2 to get a generic3 "conversion to bijective base-k" ToBijective() routine:

class BijectiveNumeration {
    private int baseK;
    private Func<int, char> getDigit;
    public BijectiveNumeration(int baseK, Func<int, char> getDigit) {
        this.baseK = baseK;
        this.getDigit = getDigit;
    }

    public string ToBijective(double decimalValue) {
        double q = f(decimalValue / baseK);
        double a = decimalValue - (q * baseK);
        return ((q > 0) ? ToBijective(q) : "") + getDigit((int)a);
    }

    private static double f(double i) {
        return (Math.Ceiling(i) - 1);
    }
}

Now for conversion to bijective base-26 (our "Excel column name" use case):

static void Main(string[] args)
{
    BijectiveNumeration bijBase26 = new BijectiveNumeration(
        26,
        (value) => Convert.ToChar('A' + (value - 1))
    );

    Console.WriteLine(bijBase26.ToBijective(1));     // prints "A"
    Console.WriteLine(bijBase26.ToBijective(26));    // prints "Z"
    Console.WriteLine(bijBase26.ToBijective(27));    // prints "AA"
    Console.WriteLine(bijBase26.ToBijective(702));   // prints "ZZ"
    Console.WriteLine(bijBase26.ToBijective(16384)); // prints "XFD"
}

Excel's maximum column index is 16384 / XFD, but this code will convert any positive number.

As an added bonus, we can now easily convert to any bijective base. For example for bijective base-10:

static void Main(string[] args)
{
    BijectiveNumeration bijBase10 = new BijectiveNumeration(
        10,
        (value) => value < 10 ? Convert.ToChar('0'+value) : 'A'
    );

    Console.WriteLine(bijBase10.ToBijective(1));     // prints "1"
    Console.WriteLine(bijBase10.ToBijective(10));    // prints "A"
    Console.WriteLine(bijBase10.ToBijective(123));   // prints "123"
    Console.WriteLine(bijBase10.ToBijective(20));    // prints "1A"
    Console.WriteLine(bijBase10.ToBijective(100));   // prints "9A"
    Console.WriteLine(bijBase10.ToBijective(101));   // prints "A1"
    Console.WriteLine(bijBase10.ToBijective(2010));  // prints "19AA"
}

1 This generic answer can eventually be reduced to the other, correct, specific answers, but I find it hard to fully grasp the logic of the solutions without the formal theory behind bijective numeration in general. It also proves its correctness nicely. Additionally, several similar questions link back to this one, some being language-agnostic or more generic. That's why I thought the addition of this answer was warranted, and that this question was a good place to put it.

2 C# disclaimer: I implemented an example in C# because this is what is asked here, but I have never learned nor used the language. I have verified it does compile and run, but please adapt it to fit the language best practices / general conventions, if necessary.

3 This example only aims to be correct and understandable ; it could and should be optimized would performance matter (e.g. with tail-recursion -- but that seems to require trampolining in C#), and made safer (e.g. by validating parameters).

desseim
  • 7,968
  • 2
  • 24
  • 26
6

I wanted to throw in my static class I use, for interoping between col index and col Label. I use a modified accepted answer for my ColumnLabel Method

public static class Extensions
{
    public static string ColumnLabel(this int col)
    {
        var dividend = col;
        var columnLabel = string.Empty;
        int modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
            dividend = (int)((dividend - modulo) / 26);
        } 

        return columnLabel;
    }
    public static int ColumnIndex(this string colLabel)
    {
        // "AD" (1 * 26^1) + (4 * 26^0) ...
        var colIndex = 0;
        for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
        {
            var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
            colIndex += cVal * ((int)Math.Pow(26, pow));
        }
        return colIndex;
    }
}

Use this like...

30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
t3dodson
  • 3,949
  • 2
  • 29
  • 40
4

In perl, for an input of 1 (A), 27 (AA), etc.

sub excel_colname {
  my ($idx) = @_;       # one-based column number
  --$idx;               # zero-based column index
  my $name = "";
  while ($idx >= 0) {
    $name .= chr(ord("A") + ($idx % 26));
    $idx   = int($idx / 26) - 1;
  }
  return scalar reverse $name;
}
jrw32982
  • 608
  • 5
  • 11
Myforwik
  • 3,438
  • 5
  • 35
  • 42
4
private String getColumn(int c) {
    String s = "";
    do {
        s = (char)('A' + (c % 26)) + s;
        c /= 26;
    } while (c-- > 0);
    return s;
}

Its not exactly base 26, there is no 0 in the system. If there was, 'Z' would be followed by 'BA' not by 'AA'.

4

if you just want it for a cell formula without code, here's a formula for it:

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
CoolBeans
  • 20,654
  • 10
  • 86
  • 101
Matt Lewis
  • 79
  • 1
4

In Delphi (Pascal):

function GetExcelColumnName(columnNumber: integer): string;
var
  dividend, modulo: integer;
begin
  Result := '';
  dividend := columnNumber;
  while dividend > 0 do begin
    modulo := (dividend - 1) mod 26;
    Result := Chr(65 + modulo) + Result;
    dividend := (dividend - modulo) div 26;
  end;
end;
JRL
  • 3,363
  • 24
  • 36
4

A little late to the game, but here's the code I use (in C#):

private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static int ColumnNameParse(string value)
{
    // assumes value.Length is [1,3]
    // assumes value is uppercase
    var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x));
    return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1));
}
Kelly L
  • 366
  • 1
  • 3
  • 8
3

Though I am late to the game, Graham's answer is far from being optimal. Particularly, you don't have to use the modulo, call ToString() and apply (int) cast. Considering that in most cases in C# world you would start numbering from 0, here is my revision:

public static string GetColumnName(int index) // zero-based
{
    const byte BASE = 'Z' - 'A' + 1;
    string name = String.Empty;

    do
    {
        name = Convert.ToChar('A' + index % BASE) + name;
        index = index / BASE - 1;
    }
    while (index >= 0);

    return name;
}
Community
  • 1
  • 1
Herman Kan
  • 2,253
  • 1
  • 25
  • 32
3

For what it is worth, here is Graham's code in Powershell:

function ConvertTo-ExcelColumnID {
    param (
        [parameter(Position = 0,
            HelpMessage = "A 1-based index to convert to an excel column ID. e.g. 2 => 'B', 29 => 'AC'",
            Mandatory = $true)]
        [int]$index
    );

    [string]$result = '';
    if ($index -le 0 ) {
        return $result;
    }

    while ($index -gt 0) {
        [int]$modulo = ($index - 1) % 26;
        $character = [char]($modulo + [int][char]'A');
        $result = $character + $result;
        [int]$index = ($index - $modulo) / 26;
    }

    return $result;
}
Ro Yo Mi
  • 14,790
  • 5
  • 35
  • 43
3

More than 30 solutions already, but here's my one-line C# solution...

public string IntToExcelColumn(int i)
{
    return ((i<16926? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<2730? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<26? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + ((char)((i%26)+65)));
}
AlishahNovin
  • 1,904
  • 3
  • 20
  • 37
3

After looking at all the supplied Versions here, I decided to do one myself, using recursion.

Here is my vb.net Version:

Function CL(ByVal x As Integer) As String
    If x >= 1 And x <= 26 Then
        CL = Chr(x + 64)
    Else
        CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64)
    End If
End Function
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
user932708
  • 89
  • 3
  • 5
2

Refining the original solution (in C#):

public static class ExcelHelper
{
    private static Dictionary<UInt16, String> l_DictionaryOfColumns;

    public static ExcelHelper() {
        l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
    }

    public static String GetExcelColumnName(UInt16 l_Column)
    {
        UInt16 l_ColumnCopy = l_Column;
        String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String l_rVal = "";
        UInt16 l_Char;


        if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
        {
            l_rVal = l_DictionaryOfColumns[l_Column];
        }
        else
        {
            while (l_ColumnCopy > 26)
            {
                l_Char = l_ColumnCopy % 26;
                if (l_Char == 0)
                    l_Char = 26;

                l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
                l_rVal = l_Chars[l_Char] + l_rVal;
            }
            if (l_ColumnCopy != 0)
                l_rVal = l_Chars[l_ColumnCopy] + l_rVal;

            l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
        }

        return l_rVal;
    }
}
ShloEmi
  • 1,851
  • 2
  • 20
  • 25
2

JavaScript Solution

/**
 * Calculate the column letter abbreviation from a 1 based index
 * @param {Number} value
 * @returns {string}
 */
getColumnFromIndex = function (value) {
    var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    var remainder, result = "";
    do {
        remainder = value % 26;
        result = base[(remainder || 26) - 1] + result;
        value = Math.floor(value / 26);
    } while (value > 0);
    return result;
};
Ally
  • 4,894
  • 8
  • 37
  • 45
2

Another VBA way

Public Function GetColumnName(TargetCell As Range) As String
    GetColumnName = Split(CStr(TargetCell.Cells(1, 1).Address), "$")(1)
End Function
chris neilsen
  • 52,446
  • 10
  • 84
  • 123
Paul Ma
  • 469
  • 2
  • 5
  • 15
2

Here is an Actionscript version:

private var columnNumbers:Array = ['A', 'B', 'C', 'D', 'E', 'F' , 'G', 'H', 'I', 'J', 'K' ,'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];

    private function getExcelColumnName(columnNumber:int) : String{
        var dividend:int = columnNumber;
        var columnName:String = "";
        var modulo:int;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = columnNumbers[modulo] + columnName;
            dividend = int((dividend - modulo) / 26);
        } 

        return columnName;
    }
Rob
  • 46
  • 1
2

These my codes to convert specific number (index start from 1) to Excel Column.

    public static string NumberToExcelColumn(uint number)
    {
        uint originalNumber = number;

        uint numChars = 1;
        while (Math.Pow(26, numChars) < number)
        {
            numChars++;

            if (Math.Pow(26, numChars) + 26 >= number)
            {
                break;
            }               
        }

        string toRet = "";
        uint lastValue = 0;

        do
        {
            number -= lastValue;

            double powerVal = Math.Pow(26, numChars - 1);
            byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal);
            lastValue = (int)powerVal * thisCharIdx;

            if (numChars - 2 >= 0)
            {
                double powerVal_next = Math.Pow(26, numChars - 2);
                byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next);
                int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next;

                if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26)
                {
                    thisCharIdx--;
                    lastValue = (int)powerVal * thisCharIdx;
                }
            }

            toRet += (char)((byte)'A' + thisCharIdx + ((numChars > 1) ? -1 : 0));

            numChars--;
        } while (numChars > 0);

        return toRet;
    }

My Unit Test:

    [TestMethod]
    public void Test()
    {
        Assert.AreEqual("A", NumberToExcelColumn(1));
        Assert.AreEqual("Z", NumberToExcelColumn(26));
        Assert.AreEqual("AA", NumberToExcelColumn(27));
        Assert.AreEqual("AO", NumberToExcelColumn(41));
        Assert.AreEqual("AZ", NumberToExcelColumn(52));
        Assert.AreEqual("BA", NumberToExcelColumn(53));
        Assert.AreEqual("ZZ", NumberToExcelColumn(702));
        Assert.AreEqual("AAA", NumberToExcelColumn(703));
        Assert.AreEqual("ABC", NumberToExcelColumn(731));
        Assert.AreEqual("ACQ", NumberToExcelColumn(771));
        Assert.AreEqual("AYZ", NumberToExcelColumn(1352));
        Assert.AreEqual("AZA", NumberToExcelColumn(1353));
        Assert.AreEqual("AZB", NumberToExcelColumn(1354));
        Assert.AreEqual("BAA", NumberToExcelColumn(1379));
        Assert.AreEqual("CNU", NumberToExcelColumn(2413));
        Assert.AreEqual("GCM", NumberToExcelColumn(4823));
        Assert.AreEqual("MSR", NumberToExcelColumn(9300));
        Assert.AreEqual("OMB", NumberToExcelColumn(10480));
        Assert.AreEqual("ULV", NumberToExcelColumn(14530));
        Assert.AreEqual("XFD", NumberToExcelColumn(16384));
    }
S_R
  • 157
  • 1
  • 4
  • +1 for showing what the maximum cell reference is in your tests (XFD) - you wouldn't believe how difficult it is to find that info on the web. – controlbox Dec 15 '19 at 15:26
2

Sorry, this is Python instead of C#, but at least the results are correct:

def excel_column_number_to_name(column_number):
    output = ""
    index = column_number-1
    while index >= 0:
        character = chr((index%26)+ord('A'))
        output = output + character
        index = index/26 - 1

    return output[::-1]


for i in xrange(1, 1024):
    print "%4d : %s" % (i, excel_column_number_to_name(i))

Passed these test cases:

  • Column Number: 494286 => ABCDZ
  • Column Number: 27 => AA
  • Column Number: 52 => AZ
DataEngineer
  • 396
  • 1
  • 10
1

Here's my super late implementation in PHP. This one's recursive. I wrote it just before I found this post. I wanted to see if others had solved this problem already...

public function GetColumn($intNumber, $strCol = null) {

    if ($intNumber > 0) {
        $intRem = ($intNumber - 1) % 26;
        $strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf('%s%s', chr(65 + $intRem), $strCol));
    }

    return $strCol;
}
Ian Atkin
  • 6,302
  • 2
  • 17
  • 24
1

Coincise and elegant Ruby version:

def col_name(col_idx)
    name = ""
    while col_idx>0
        mod     = (col_idx-1)%26
        name    = (65+mod).chr + name
        col_idx = ((col_idx-mod)/26).to_i
    end
    name
end
Iwan B.
  • 3,982
  • 2
  • 27
  • 18
1

NodeJS implementation:

/**
* getColumnFromIndex
* Helper that returns a column value (A-XFD) for an index value (integer).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa/3444285#3444285
* @param numVal: Integer
* @return String
*/
getColumnFromIndex: function(numVal){
   var dividend = parseInt(numVal);
   var columnName = '';
   var modulo;
   while (dividend > 0) {
      modulo = (dividend - 1) % 26;
      columnName = String.fromCharCode(65 + modulo) + columnName;
      dividend = parseInt((dividend - modulo) / 26);
   }
   return columnName;
},

Thanks to Convert excel column alphabet (e.g. AA) to number (e.g., 25). And in reverse:

/**
* getIndexFromColumn
* Helper that returns an index value (integer) for a column value (A-XFD).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/9905533/convert-excel-column-alphabet-e-g-aa-to-number-e-g-25
* @param strVal: String
* @return Integer
*/
getIndexFromColumn: function(val){
   var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
   for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
      result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
   }
   return result;
}
Community
  • 1
  • 1
Rob Sawyer
  • 2,163
  • 1
  • 24
  • 25
1

F# version of each way

let rec getExcelColumnName x  = if x<26 then int 'A'+x|>char|>string else (x/26-1|>c)+ c(x%26)

pardon the minimizing, was working on a better version of https://stackoverflow.com/a/4500043/57883


and the opposite direction:
// return values start at 0
let getIndexFromExcelColumnName (x:string) =
    let a = int 'A'
    let fPow len i =
        Math.Pow(26., len - 1 - i |> float)
        |> int

    let getValue len i c = 
        int c - a + 1 * fPow len i
    let f i = getValue x.Length i x.[i]
    [0 .. x.Length - 1]
    |> Seq.map f
    |> Seq.sum
    |> fun x -> x - 1
Community
  • 1
  • 1
Maslow
  • 18,464
  • 20
  • 106
  • 193
1

This is the question all others as well as Google redirect to so I'm posting this here.

Many of these answers are correct but too cumbersome for simple situations such as when you don't have over 26 columns. If you have any doubt whether you might go into double character columns then ignore this answer, but if you're sure you won't, then you could do it as simple as this in C#:

public static char ColIndexToLetter(short index)
{
    if (index < 0 || index > 25) throw new ArgumentException("Index must be between 0 and 25.");
    return (char)('A' + index);
}

Heck, if you're confident about what you're passing in you could even remove the validation and use this inline:

(char)('A' + index)

This will be very similar in many languages so you can adapt it as needed.

Again, only use this if you're 100% sure you won't have more than 26 columns.

Vlad Schnakovszki
  • 8,434
  • 6
  • 80
  • 114
1

Thanks for the answers here!! helped me come up with these helper functions for some interaction with the Google Sheets API that i'm working on in Elixir/Phoenix

here's what i came up with (could probably use some extra validation and error handling)

In Elixir:

def number_to_column(number) do
  cond do
    (number > 0 && number <= 26) ->
      to_string([(number + 64)])
    (number > 26) ->
      div_col = number_to_column(div(number - 1, 26))
      remainder = rem(number, 26)
      rem_col = cond do
        (remainder == 0) ->
          number_to_column(26)
        true ->
          number_to_column(remainder)
      end
      div_col <> rem_col
    true ->
      ""
  end
end

And the inverse function:

def column_to_number(column) do
  column
    |> to_charlist
    |> Enum.reverse
    |> Enum.with_index
    |> Enum.reduce(0, fn({char, idx}, acc) ->
      ((char - 64) * :math.pow(26,idx)) + acc
    end)
    |> round
end

And some tests:

describe "test excel functions" do
  @excelTestData [{"A", 1}, {"Z",26}, {"AA", 27}, {"AB", 28}, {"AZ", 52},{"BA", 53}, {"AAA", 703}]

  test "column to number" do
    Enum.each(@excelTestData, fn({input, expected_result}) ->
      actual_result = BulkOnboardingController.column_to_number(input)
      assert actual_result == expected_result
    end)
  end

  test "number to column" do
    Enum.each(@excelTestData, fn({expected_result, input}) ->
      actual_result = BulkOnboardingController.number_to_column(input)
      assert actual_result == expected_result
    end)
  end
end
phlare
  • 318
  • 3
  • 11
1

This is a javascript version according to Graham's code

function (columnNumber) {
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0) {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo) + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    }

    return columnName;
};
Phoeson
  • 191
  • 1
  • 6
1

Most of previous answers are correct. Here is one more way of converting column number to excel columns. solution is rather simple if we think about this as a base conversion. Simply, convert the column number to base 26 since there is 26 letters only. Here is how you can do this:

steps:

  • set the column as a quotient

  • subtract one from quotient variable (from previous step) because we need to end up on ascii table with 97 being a.

  • divide by 26 and get the remainder.

  • add +97 to remainder and convert to char (since 97 is "a" in ASCII table)
  • quotient becomes the new quotient/ 26 (since we might go over 26 column)
  • continue to do this until quotient is greater than 0 and then return the result

here is the code that does this :)

def convert_num_to_column(column_num):
    result = ""
    quotient = column_num
    remainder = 0
    while (quotient >0):
        quotient = quotient -1
        remainder = quotient%26
        result = chr(int(remainder)+97)+result
        quotient = int(quotient/26)
    return result

print("--",convert_num_to_column(1).upper())
grepit
  • 21,260
  • 6
  • 105
  • 81
1

This snippet works for A to ZZ column Names

string columnName = columnNumber > 26 ? Convert.ToChar(64 + (columnNumber / 26)).ToString() + Convert.ToChar(64 + (columnNumber % 26)) : Convert.ToChar(64 + columnNumber).ToString();
Chirag Sheth
  • 99
  • 11
1

My solution based on Graham, Herman Kan and desseim answers, with using StringBuilder:

internal class Program
{
    #region get_excel_col_name
    /// <summary>
    /// Returns the name of the column by its number
    /// </summary>
    /// <param name="col_num">Column number</param>
    /// <returns>Column name</returns>
    /// <remarks>Numbering columns from zero</remarks>
    private static string get_excel_col_name(int col_num)
    {
        StringBuilder sb = new StringBuilder(2);
        if (col_num >= 0)
        {
            do
            {
                sb.Insert(0, (char)(col_num % 26 + 65));
                col_num /= 26;
            }
            while (--col_num >= 0);
        }
        return sb.ToString();
    }
    #endregion

    private static void Main(string[] args)
    {
        Console.WriteLine(get_excel_col_name(34));//outputs AI
        Console.ReadKey(true);
    }
}
Ramil Shavaleev
  • 364
  • 3
  • 12
1

I'm trying to do the same thing in Java... I've wrote following code:

private String getExcelColumnName(int columnNumber) {

    int dividend = columnNumber;
    String columnName = "";
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;

        char val = Character.valueOf((char)(65 + modulo));

        columnName += val;

        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}

Now once I ran it with columnNumber = 29, it gives me the result = "CA" (instead of "AC") any comments what I'm missing? I know I can reverse it by StringBuilder.... But looking at the Graham's answer, I'm little confused....

bluish
  • 26,356
  • 27
  • 122
  • 180
Hasan
  • 299
  • 3
  • 6
  • 16
  • Graham says: `columnName = Convert.ToChar(65 + modulo).ToString() + columnName` (ie value + ColName). Hasan says: `columnName += val;` (ie ColName + value) – mcalex Mar 28 '13 at 05:51
  • You're appending the new character instead of prepending it. Should be `columnName = columnName + val`. – Domenic D. Jan 24 '20 at 18:32
0

Another solution:

private void Foo()
{
   l_ExcelApp = new Excel.ApplicationClass();
   l_ExcelApp.ReferenceStyle = Excel.XlReferenceStyle.xlR1C1;
   // ... now reference by R[row]C[column], Ex. A1 <==> R1C1, C6 <==> R3C6, ...
}

see more here - Cell referencing in Excel for everyone! by Dr Nitin Paranjape

ShloEmi
  • 1,851
  • 2
  • 20
  • 25
0

(I realise the question relates to C# however, if anyone reading needs to do the same thing with Java then the following may be useful)

It turns out that this can easily be done using the the "CellReference" class in Jakarta POI. Also, the conversion can be done both ways.

// Convert row and column numbers (0-based) to an Excel cell reference
CellReference numbers = new CellReference(3, 28);
System.out.println(numbers.formatAsString());

// Convert an Excel cell reference back into digits
CellReference reference = new CellReference("AC4");
System.out.println(reference.getRow() + ", " + reference.getCol());
Ian
  • 7,480
  • 2
  • 47
  • 51
0
public static string ConvertToAlphaColumnReferenceFromInteger(int columnReference)
    {
        int baseValue = ((int)('A')) - 1 ;
        string lsReturn = String.Empty; 

        if (columnReference > 26) 
        {
            lsReturn = ConvertToAlphaColumnReferenceFromInteger(Convert.ToInt32(Convert.ToDouble(columnReference / 26).ToString().Split('.')[0]));
        } 

        return lsReturn + Convert.ToChar(baseValue + (columnReference % 26));            
    }
Daniel
  • 1
0

I'm using this one in VB.NET 2003 and it works well...

Private Function GetExcelColumnName(ByVal aiColNumber As Integer) As String
    Dim BaseValue As Integer = Convert.ToInt32(("A").Chars(0)) - 1
    Dim lsReturn As String = String.Empty

    If (aiColNumber > 26) Then
        lsReturn = GetExcelColumnName(Convert.ToInt32((Format(aiColNumber / 26, "0.0").Split("."))(0)))
    End If

    GetExcelColumnName = lsReturn + Convert.ToChar(BaseValue + (aiColNumber Mod 26))
End Function
0

I just had to do this work today, my implementation uses recursion:

private static string GetColumnLetter(string colNumber)
{
    if (string.IsNullOrEmpty(colNumber))
    {
        throw new ArgumentNullException(colNumber);
    }

    string colName = String.Empty;

    try
    {
        var colNum = Convert.ToInt32(colNumber);
        var mod = colNum % 26;
        var div = Math.Floor((double)(colNum)/26);
        colName = ((div > 0) ? GetColumnLetter((div - 1).ToString()) : String.Empty) + Convert.ToChar(mod + 65);
    }
    finally
    {
        colName = colName == String.Empty ? "A" : colName;
    }

    return colName;
}

This considers the number coming as string the the method and the numbers starting in "0" (A = 0)

Hangarter
  • 582
  • 4
  • 12
0

If you are wanting to reference the cell progmatically then you will get much more readable code if you use the Cells method of a sheet. It takes a row and column index instead of a traditonal cell reference. It is very similar to the Offset method.

pipTheGeek
  • 2,703
  • 17
  • 16
  • ? Cells is possibly the worst way to reference a range in Excel. It's performance is appalling. Offset or just Worksheet.Range is much better. – Anonymous Type Jul 22 '10 at 23:27
0

Objective-C Implementation :

-(NSString*)getColumnName:(int)n {
     NSString *name = @"";
     while (n>0) {
     n--;
     char c = (char)('A' + n%26);
     name = [NSString stringWithFormat:@"%c%@",c,name];
     n = n/26;
  }    
     return name;

}

SWIFT Implementation:

func getColumnName(n:Int)->String{
 var columnName = ""
 var index = n
 while index>0 {
     index--
     let char = Character(UnicodeScalar(65 + index%26))
     columnName = "\(char)\(columnName)"
     index = index / 26
 }
 return columnName

}

The answer is based on :https://stackoverflow.com/a/4532562/2231118

Community
  • 1
  • 1
bpolat
  • 3,879
  • 20
  • 26
0

Saw one other VBA answer - this can be done in with a 1 line UDF:

Function GetColLetter(ByVal colID As Integer) As String
    If colID > Columns.Count Then
        Err.Raise 9, , "Column index out of bounds"
    Else
        GetColLetter = Split(Cells(1, colID).Address, "$")(1)
    End If
End Function
SierraOscar
  • 17,507
  • 6
  • 40
  • 68
0

Typescript

function lengthToExcelColumn(len: number): string {

    let dividend: number = len;
    let columnName: string = '';
    let modulo: number = 0;

    while (dividend > 0) {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo).toString() + columnName;
        dividend = Math.floor((dividend - modulo) / 26);
    }
    return columnName;
}
Tyler
  • 1,163
  • 16
  • 37
0

Seems like so many answers are much more complex than necessary. Here is a generic Ruby answer based on the recursion described above:

One nice thing about this answer is that it's not limited to the 26 characters of English Alphabet. You can define any range you like in COLUMNS constant and it will do the right thing.

  # vim: ft=ruby
  class Numeric
    COLUMNS = ('A'..'Z').to_a

    def to_excel_column(n = self)
      n < 1 ?  '' : begin
        base = COLUMNS.size
        to_excel_column((n - 1) / base) + COLUMNS[(n - 1) % base]
      end
    end
  end

  # verify:
  (1..52).each { |i| printf "%4d => %4s\n", i, i.to_excel_column }

This prints the following, eg:

   1 =>    A
   2 =>    B
   3 =>    C
  ....
  33 =>   AG
  34 =>   AH
  35 =>   AI
  36 =>   AJ
  37 =>   AK
  38 =>   AL
  39 =>   AM
  40 =>   AN
  41 =>   AO
  42 =>   AP
  43 =>   AQ
  44 =>   AR
  45 =>   AS
  46 =>   AT
  47 =>   AU
  48 =>   AV
  49 =>   AW
  50 =>   AX
  51 =>   AY
  52 =>   AZ
0

This is a common question asked in coding test. it has some constraints: max columns per row= 702 output should have row number+column name e.g. for 703 answer is 2A. (note: i have just modified existing code from another answer) here is the code for the same:

    static string GetExcelColumnName(long columnNumber)
    {
        //max number of column per row
        const long maxColPerRow = 702;
        //find row number
        long rowNum = (columnNumber / maxColPerRow);
        //find tierable columns in the row.
        long dividend = columnNumber - (maxColPerRow * rowNum);

        string columnName = String.Empty;

        long modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
            dividend = (int)((dividend - modulo) / 26);
        }

        return rowNum+1+ columnName;
    }
}
Pranav Mishra
  • 456
  • 2
  • 7
  • 14
0

T-SQL (SQL SERVER 18)

Copy of the solution on first page

CREATE FUNCTION dbo.getExcelColumnNameByOrdinal(@RowNum int)  
RETURNS varchar(5)   
AS   
BEGIN  
    DECLARE @dividend int = @RowNum;
    DECLARE @columnName varchar(max) = '';
    DECLARE @modulo int;

    WHILE (@dividend > 0)
    BEGIN  
        SELECT @modulo = ((@dividend - 1) % 26);
        SELECT @columnName = CHAR((65 + @modulo)) + @columnName;
        SELECT @dividend = CAST(((@dividend - @modulo) / 26) as int);
    END
    RETURN 
       @columnName;

END;
Agneum
  • 727
  • 7
  • 23
0

Here is a simpler solution for zero based column Index

 public static string GetColumnIndexNumberToExcelColumn(int columnIndex)
        {
            int offset = columnIndex % 26;
            int multiple = columnIndex / 26;

            int initialSeed = 65;//Represents column "A"
            if (multiple == 0)
            {
                return Convert.ToChar(initialSeed + offset).ToString();
            }

            return $"{Convert.ToChar(initialSeed + multiple - 1)}{Convert.ToChar(initialSeed + offset)}";
        }
Hunter
  • 2,370
  • 2
  • 20
  • 24
0
 static string[] ExcelColumnAlphabetIdentifiers = new string[] { "", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", 
     "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
 public static string ExcelColumnAlphabetIdentifier( int ColumnNumber)
    {
        StringBuilder sb = new StringBuilder();
        int remainder = ColumnNumber;
        do
        {
            sb.Append(ExcelColumnAlphabetIdentifiers[remainder % 26]);
            remainder = remainder / 26;
        }
        while (remainder > 0);
       return sb.ToString();
    }
yuriy
  • 264
  • 1
  • 3
  • 11
0

Simple and concise JavaScript function that converts column number to a spreadsheet column name.

function column(number)
{
    const name = [];
    for(let n = number - 1; n >= 0; n = Math.floor(n / 26) - 1)
    {
        name.push(String.fromCharCode(65 + n % 26));
    }
    return name.reverse().join("");
};

console.log(column(1), "A");
console.log(column(26), "Z");
console.log(column(27), "AA");
console.log(column(52), "AZ");
console.log(column(53), "BA");
console.log(column(702), "ZZ");
console.log(column(703), "AAA");
console.log(column(704), "AAB");
console.log(column(16384), "XFD");
gogo
  • 950
  • 12
  • 20
0

Here is how I would do it in Python. The algorithm is explained below:

alph = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
def labelrec(n, res):
    if n<26:
        return alph[n]+res
    else:
        rem = n%26
        res = alph[rem]+res
        n = n/26-1
        return labelrec(n, res)

The function labelrec can be called with the number and an empty string like:

print labelrec(16383, '')

Here is why it works: If decimal numbers were written the same way as Excel sheet columns, number 0-9 would be written normally, but 10 would become '00' and then 20 would become '10' and so on. Mapping few numbers:

0 - 0

9 - 9

10 - 00

20 - 10

100 - 90

110 - 000

1110 - 0000

So, the pattern is clear. Starting at the unit's place, if a number is less than 10, it's representation is same as the number itself, else you need to adjust the remaining number by subtracting it by 1 and recurse. You can stop when the number is less than 10.

The same logic is applied for numbers of base 26 in above solution.

P.S. If you want the numbers to begin from 1, call the same function on input number after decreasing it by 1.

lambdapilgrim
  • 1,041
  • 7
  • 10
0

Using this in VB.Net 2005 :

Private Function ColumnName(ByVal ColumnIndex As Integer) As String

   Dim Name As String = ""

   Name = (New Microsoft.Office.Interop.Owc11.Spreadsheet).Columns.Item(ColumnIndex).Address(False, False, Microsoft.Office.Interop.Owc11.XlReferenceStyle.xlA1)
   Name = Split(Name, ":")(0)

   Return Name

End Function
Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
  • 1
    nice idea. but terrible performance wise. newing up an object implicitly then using another four dots to call the final Address method is going to result in some terrible interop marshalling. definately needs to be rewritten. – Anonymous Type Jul 22 '10 at 23:28
-2

Microsoft Excel Miniature, Quick-and-Dirty formula.

Hi,

Here's one way to get the Excel character-column-header from a number....

I created a formula for an Excel cell.

(i.e. I took the approach of not using VBA programming.)

The formula looks at a cell that has a number in it and tells you what the column is -- in letters.

In the attached image:

  • I put 1,2,3 etc in the top row all the way out to column ABS.
  • I pasted my formula in the second row all the way out to ABS.
  • My formula looks at row 1 and converts the number to Excel's column header id.
  • My formula works for all numbers out to 702 (zz).
  • I did it in this manner to prove that the formula works so you can look at the output from the formula and look at the column header above and easily visually verify that the formula works. :-)

    =CONCATENATE(MID("_abcdefghijklmnopqrstuvwxyz",(IF(MOD(K1,26)>0,INT(K1/26)+1,(INT(K1/26)))),1),MID("abcdefghijklmnopqrstuvwxyz",IF(MOD(K1,26)=0,26,MOD(K1,26)),1))

The underscore was there for debugging purposes - to let you know there was an actual space and that it was working correctly.

With this formula above -- whatever you put in K1 - the formula will tell you what the column header will be.

The formula, in its current form, only goes out to 2 digits (ZZ) but could be modified to add the 3rd letter (ZZZ).

enter image description here

user2792497
  • 119
  • 8
-2

Here is my solution in python

import math

num = 3500
row_number = str(math.ceil(num / 702))
letters = ''
num = num - 702 * math.floor(num / 702)
while num:
    mod = (num - 1) % 26
    letters += chr(mod + 65)
    num = (num - 1) // 26
result = row_number + ("".join(reversed(letters)))
print(result)

Ricky
  • 147
  • 1
  • 2
  • 9
-4
    public string ToBase26(int number)
    {
        if (number < 0) return String.Empty;

        int remainder = number % 26;
        int value = number / 26;

        return value == 0 ?
            String.Format("{0}", Convert.ToChar(65 + remainder)) :
            String.Format("{0}{1}", ToBase26(value - 1), Convert.ToChar(65 + remainder));
    }
dirn
  • 1
  • 1
  • 2
    It's not just a simple base-26 conversion. Read the other answers. – Joel Coehoorn Nov 15 '10 at 20:00
  • Assuming first column is 0. 0 will return A, 26 will return AA and 702 will return AAA. The different between mine and the first correct answer was, it started with 1 and mine started with 0. That's my understanding. Correct me if i'm wrong. – dirn Nov 18 '10 at 07:20
  • @dirn you are wrong. Base 10 to 26, converts 11 to A, not 1 to A. – Benubird Aug 20 '13 at 15:22