Fastest function to generate Excel column letters in C#

前端 未结 21 1677
无人共我
无人共我 2020-11-29 02:30

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 return

相关标签:
21条回答
  • 2020-11-29 02:44

    Try this function.

    // Returns name of column for specified 0-based index.
    public static string GetColumnName(int index)
    {
        var name = new char[3]; // Assumes 3-letter column name max.
        int rem = index;
        int div = 17576; // 26 ^ 3
    
        for (int i = 2; i >= 0; i++)
        {
            name[i] = alphabet[rem / div];
            rem %= div;
            div /= 26;
        }
    
        if (index >= 676)
            return new string(name, 3);
        else if (index >= 26)
            return new string(name, 2);
        else
            return new string(name, 1);
    }
    

    Now it shouldn't take up that much memory to pre-generate each column name for every index and store them in a single huge array, so you shouldn't need to look up the name for any column twice.

    If I can think of any further optimisations, I'll add them later, but I believe this function should be pretty quick, and I doubt you even need this sort of speed if you do the pre-generation.

    0 讨论(0)
  • 2020-11-29 02:45

    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] + "";
    }
    
    0 讨论(0)
  • 2020-11-29 02:46

    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.

    0 讨论(0)
  • 2020-11-29 02:48

    Just use an Excel formula instead of a user-defined function (UDF) or other program, per Allen Wyatt (https://excel.tips.net/T003254_Alphabetic_Column_Designation.html):

    =SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),"")
    

    (In my organization, using UDFs would be very painful.)

    0 讨论(0)
  • 2020-11-29 02:50

    Don't convert it at all. Excel can work in R1C1 notation just as well as in A1 notation.

    So (apologies for using VBA rather than C#):

    Application.Worksheets("Sheet1").Range("B1").Font.Bold = True
    

    can just as easily be written as:

    Application.Worksheets("Sheet1").Cells(1, 2).Font.Bold = True
    

    The Range property takes A1 notation whereas the Cells property takes (row number, column number).

    To select multiple cells: Range(Cells(1, 1), Cells(4, 6)) (NB would need some kind of object qualifier if not using the active worksheet) rather than Range("A1:F4")

    The Columns property can take either a letter (e.g. F) or a number (e.g. 6)

    0 讨论(0)
  • 2020-11-29 02:50

    Once your function has run, let it cache the results into a dictionary. So that, it won't have to do the calculation again.

    e.g. Convert(27) will check if 27 is mapped/stored in dictionary. If not, do the calculation and store "AA" against 27 in the dictionary.

    0 讨论(0)
提交回复
热议问题