Как преобразовать имена столбцов листа Excel в числа?

Мне было интересно, как лучше всего преобразовать имена столбцов Excel в числа.

Я работаю с Пакет Excel - хорошая библиотека для обработки документов .xlsx. К сожалению, эта библиотека не включает эту функциональность.

OBS: первая колонка A соответствует к номеру 1 в этой библиотеке.

Ответ 1

Эта функция должна работать для имени столбца произвольной длины.

public static int GetColumnNumber(string name)
{
    int number = 0;
    int pow = 1;
    for (int i = name.Length - 1; i >= 0; i--)
    {
        number += (name[i] - 'A' + 1) * pow;
        pow *= 26;
    }

    return number;
}

Ответ 2

Мне пришлось иметь дело с этим несколько месяцев назад. Индекс обратного столбца к имени столбца - тоже забавно, и становится действительно беспорядочным, если вы попытаетесь решить его с помощью индекса на основе нуля, не признающего, что это усложняет ситуацию. Это может быть так просто, если это будет нормальная полиадическая система цифр...

Вот упрощенная версия моего решения как метода расширения без обработки ошибок и всего этого.

public static Int32 ToOneBasedIndex(this String name)
{
    return name.ToUpper().
       Aggregate(0, (column, letter) => 26 * column + letter - 'A' + 1);
}

Ответ 3

Я работаю с этим некоторое время и нашел, что это действительно хорошо работает для столбцов, выходящих за пределы AZ или даже за пределы AA-ZZ... Это достигается разбиением каждого символа в строке и рекурсивным вызовом чтобы получить значение DEC символа ASCII (менее 64), а затем умножить его на 26 ^ n. Для преодоления потенциального ограничения при n > 4 использовалось возвращаемое значение long.

    public long columnNumber(String columnName)
    {
        char[] chars = columnName.ToUpper().ToCharArray();

        return (long)(Math.Pow(26, chars.Count() - 1)) * 
            (System.Convert.ToInt32(chars[0]) - 64) + 
            ((chars.Count() > 2) ? columnNumber(columnName.Substring(1, columnName.Length - 1)) : 
            ((chars.Count() == 2) ? (System.Convert.ToInt32(chars[chars.Count() - 1]) - 64) : 0));
    }

Кроме того, если вы хотите получить обратный (например, передать в столбце NumberNumber и получить имя столбца, вот какой код работает для этого.

    public String columnName(long columnNumber)
    {
        StringBuilder retVal = new StringBuilder();
        int x = 0;

        for (int n = (int)(Math.Log(25*(columnNumber + 1))/Math.Log(26)) - 1; n >= 0; n--)
        {
            x = (int)((Math.Pow(26,(n + 1)) - 1) / 25 - 1);
            if (columnNumber > x)
                retVal.Append(System.Convert.ToChar((int)(((columnNumber - x - 1) / Math.Pow(26, n)) % 26 + 65)));
        }

        return retVal.ToString();
    }

Ответ 4

попробуйте мой код

пространство имен XLS {

/// <summary>
/// Represents a single cell in a excell sheet
/// </summary>
public struct Cell
{
    private long row;
    private long column;
    private string columnAddress;
    private string address;
    private bool dataChange;

    /// <summary>
    /// Initializes a new instance of the XLS.Cell 
    /// class with the specified row and column of excel worksheet
    /// </summary>
    /// <param name="row">The row index of a cell</param>
    /// <param name="column">The column index of a cell</param>
    public Cell(long row, long column)
    {
        this.row = row;
        this.column = column;
        dataChange = true;
        address = string.Empty;
        columnAddress = string.Empty;
    }

    /// <summary>
    /// Initializes a new instance of the XLS.Cell
    /// class with the specified address of excel worksheet
    /// </summary>
    /// <param name="address">The adress of a cell</param>
    public Cell(string address)
    {
        this.address = address;
        dataChange = false;
        row = GetRow(address);
        columnAddress = GetColumnAddress(address);
        column = GetColumn(columnAddress);
    }

    /// <summary>
    /// Gets or sets the row of this XLS.Cell
    /// </summary>
    public long Row
    {
        get { return row <= 0 ? 1 : row; }
        set { row = value; dataChange = true; }
    }

    /// <summary>
    /// Gets or sets the column of this XLS.Cell
    /// </summary>
    public long Column
    {
        get { return column <= 0 ? 1 : column; }
        set { column = value; dataChange = true; }
    }

    /// <summary>
    /// Gets or sets the address of this XLS.Cell
    /// </summary>
    public string Address
    {
        get { return dataChange ? ToAddress() : address; }
        set
        {
            address = value;
            row = GetRow(address);
            column = GetColumn(address);
        }
    }

    /// <summary>
    /// Gets the column address of this XLS.Cell
    /// </summary>
    public string ColumnAddress
    {
        get { return GetColumnAddress(Address); }
        private set { columnAddress = value; }
    }

    #region Private Methods

    private static long GetRow(string address)
    {
        return long.Parse(address.Substring(GetStartIndex(address)));
    }

    private static string GetColumnAddress(string address)
    {
        return address.Substring(0, GetStartIndex(address)).ToUpperInvariant();
    }

    private static long GetColumn(string columnAddress)
    {
        char[] characters = columnAddress.ToCharArray();
        int sum = 0;
        for (int i = 0; i < characters.Length; i++)
        {
            sum *= 26;
            sum += (characters[i] - 'A' + 1);
        }

        return (long)sum;
    }

    private static int GetStartIndex(string address)
    {
        return address.IndexOfAny("123456789".ToCharArray());
    }

    private string ToAddress()
    {
        string indexToString = string.Empty;

        if (Column > 26)
        {
            indexToString = ((char)(65 + (int)((Column - 1) / 26) - 1)).ToString();
        }

        indexToString += (char)(65 + ((Column - 1) % 26));

        dataChange = false;
        return indexToString + Row;
    }

    #endregion
}

}

Ответ 5

O24 имеет номер столбца, и вы хотите получить имя:

= LEFT (ПРАВЫЙ (АДРЕС (1, O24), LEN (АДРЕС (1, O24)) - 1), FIND ( "$", RIGHT ((ADDRESS (1, O24)), LEN (АДРЕС (1, O24)) - 1)) - 1)

O37 имеет имя столбца, и вы хотите номер:

= COLUMN (ДВССЫЛ (О37 & 1))

Ответ 6

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] + "";
}