Alex Rivera | Logout

Fastest function to generate Excel column letters in C#

Asked 2009-05-07T21:35:05.767
39

What is the fastest c# function that takes and int and returns a string containing a letter or letters for use in an Excel function? For example, 1 returns "A", 26 returns "Z", 27 returns "AA", etc.

This is called tens of thousands of times and is taking 25% of the time needed to generate a large spreadsheet with many formulas.

public string Letter(int intCol) {

    int intFirstLetter = ((intCol) / 676) + 64;
    int intSecondLetter = ((intCol % 676) / 26) + 64;
    int intThirdLetter = (intCol % 26) + 65;

    char FirstLetter = (intFirstLetter > 64) ? (char)intFirstLetter : ' ';
    char SecondLetter = (intSecondLetter > 64) ? (char)intSecondLetter : ' ';
    char ThirdLetter = (char)intThirdLetter;

    return string.Concat(FirstLetter, SecondLetter, ThirdLetter).Trim();
}
Edit
Report

5 Answers

60

I currently use this, with Excel 2007

public static string ExcelColumnFromNumber(int column)
        {
            string columnString = "";
            decimal columnNumber = column;
            while (columnNumber > 0)
            {
                decimal currentLetterNumber = (columnNumber - 1) % 26;
                char currentLetter = (char)(currentLetterNumber + 65);
                columnString = currentLetter + columnString;
                columnNumber = (columnNumber - (currentLetterNumber + 1)) / 26;
            }
            return columnString;
        }

and

public static int NumberFromExcelColumn(string column)
        {
            int retVal = 0;
            string col = column.ToUpper();
            for (int iChar = col.Length - 1; iChar >= 0; iChar--)
            {
                char colPiece = col[iChar];
                int colNum = colPiece - 64;
                retVal = retVal + colNum * (int)Math.Pow(26, col.Length - (iChar + 1));
            }
            return retVal;
        }

As mentioned in other posts, the results can be cached.

answered 2009-08-06T06:56:49.977
7

Here's my version: This does not have any limitation as such 2-letter or 3-letter. Simply pass-in the required number (starting with 0) Will return the Excel Column Header like Alphabet sequence for passed-in number:

private string GenerateSequence(int num)
{
    string str = "";
    char achar;
    int mod;
    while (true)
    {
        mod = (num % 26) + 65;
        num = (int)(num / 26);
        achar = (char)mod;
        str = achar + str;
        if (num > 0) num--;
        else if (num == 0) break;
    }
    return str;
}

I did not tested this for performance, if someone can do that will great for others. (Sorry for being lazy) :)

Cheers!

answered 2013-02-07T11:49:01.717
2

Your first problem is that you are declaring 6 variables in the method. If a methd is going to be called thousands of times, just moving those to class scope instead of function scope will probably cut your processing time by more than half right off the bat.

answered 2009-05-08T05:30:55.390
1

Why don't we try factorial?

public static string GetColumnName(int index)
{
    const string letters = "ZABCDEFGHIJKLMNOPQRSTUVWXY";

    int NextPos = (index / 26);
    int LastPos = (index % 26);
    if (LastPos == 0) NextPos--;

    if (index > 26)
        return GetColumnName(NextPos) + letters[LastPos];
    else
        return letters[LastPos] + "";
}
answered 2013-07-09T14:09:46.120
0

It is recursive. Fast, and right :

class ToolSheet
{


    //Not the prettyest but surely the fastest :
    static string[] ColName = new string[676];


    public ToolSheet()
    {
        ColName[0] = "A";
        for (int index = 1; index < 676; ++index) Recurse(index, index);

    }

    private int Recurse(int i, int index)
    {
        if (i < 1) return 0;
        ColName[index] = ((char)(65 + i % 26)).ToString() + ColName[index];

        return Recurse(i / 26, index);
    }

    public string GetColName(int i)
    {
        return ColName[i - 1];
    }



}
answered 2009-07-11T11:22:11.580

Your Answer