source

열 번호(예: 127)를 Excel 열(예: AA)로 변환하는 방법

myloves 2023. 4. 19. 00:42

열 번호(예: 127)를 Excel 열(예: AA)로 변환하는 방법

Excel에서 직접 값을 얻는 자동화를 사용하지 않고 C#에서 숫자를 Excel 열 이름으로 변환하려면 어떻게 해야 합니까?

Excel 2007의 유효 범위는 1 ~16384 입니다.이것은 지원하는 컬럼의 수입니다.결과값은 A, AA, AAA 등 Excel 컬럼명의 형태로 해야 합니다.

방법은 다음과 같습니다.

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;
}

VBA를 사용하지 않고 Excel에서 이 작업을 수행해야 하는 사용자는 다음과 같습니다.

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

여기서 colNum은 열 번호입니다.

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

AAZ와 같은 Excel 열 주소에서 정수, 임의의 정수에서 Excel로 변환하는 등 양방향 변환이 필요할 수 있습니다.다음 두 가지 방법으로 그렇게 할 수 있습니다.1 베이스의 인덱싱을 전제로 하고, 「어레이」의 첫 번째 요소는 요소 번호 1입니다.크기 제한이 없기 때문에 ERROR와 같은 주소를 사용할 수 있습니다.열 번호는 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;
}

죄송합니다. 이것은 C#이 아닌 Python이지만 적어도 결과는 정확합니다.

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))

첫 번째 게시물에서 오류를 발견했기 때문에 앉아서 계산을 해보기로 했습니다.제가 발견한 것은 다른 사람이 올린 것처럼 엑셀열을 식별하기 위한 번호 체계가 Base 26 시스템이 아니라는 것입니다.베이스 10의 다음 사항을 고려합니다.알파벳 글자로도 할 수 있습니다.

파일: ............................S1, S2, S3 : S1, S2, S3
00, :..............................0, 00, 000:..A, AA, AAA
, 01, :................................................1, 01, 001 :..B, AB, AAB
…, …, …, …, …
, 999, :.., ZZ, ZZZ
내 총, : 676,
상태: ....................18278 : ........................1110..........18278

Excel은 베이스 26을 사용하여 개별 알파벳 공간에 있는 숫자 열을 나타냅니다.일반적으로 상태 공간 수열은 a, a^2, a^3, …이며, 상태 총수는 a + a^2 + a^3 + …임을 알 수 있습니다.

첫 번째 N개의 공간에서 상태 A의 총 수를 찾는다고 가정합니다.그 공식은 A = (a)(a^N - 1)/(a-1)이다.이것은 우리의 지수 K에 해당하는 공간 N을 찾아야 하기 때문에 중요합니다.숫자 체계에서 K가 어디에 있는지 알아내려면 A를 K로 대체하고 N에 대해 풀어야 합니다.용액은 N = log{base a}(A (a-1)/a +1)입니다.a = 10 및 K = 192의 예를 사용하면 N = 2.23804…임을 알 수 있습니다.이것은 K가 3번째 공간의 선두에 있다는 것을 말해준다. 왜냐하면 K는 2보다 조금 크기 때문이다.

다음 단계는 현재 공간에서 정확히 얼마나 떨어져 있는지 알아내는 것입니다.이를 구하려면 N의 바닥을 사용하여 생성된 A를 K에서 빼야 합니다.이 예에서 N의 바닥은 2입니다.따라서 A = (10) (10^2 – 1)/(10-1) = 110입니다. 처음 두 공간의 상태를 결합할 때 예상할 수 있습니다.처음 110개의 상태는 처음 두 공간에서 이미 설명되었으므로 K에서 이 값을 빼야 합니다.이로써 82개 주가 남았습니다.그래서 이 숫자 체계에서, 밑수 10의 192의 표현은 082입니다.

기본 인덱스를 0으로 사용하는 C# 코드는 다음과 같습니다.

    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;
    }

//오래된 투고

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;
    }

다음 답변은 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;
}

재귀가 용이합니다.

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) );
}

지금까지의 해결책에 모두 반복이나 재귀가 포함되어 있는 것이 놀랍습니다.

이것은 일정한 시간(루프 없음)에 실행되는 솔루션입니다.이 솔루션은 가능한 모든 Excel 열에 대해 작동하며 입력을 Excel 열로 변환할 수 있는지 확인합니다.사용 가능한 열은 [A, XFD] 또는 [1, 16384] 범위입니다.(이는 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);
    }
}

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; 
    }  
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;

갱신: Peter의 코멘트가 옳습니다.브라우저에 코드를 쓰면 이렇게 됩니다.:-) 솔루션이 컴파일되지 않고 왼쪽 끝 문자가 누락되어 역순으로 스트링이 작성되었습니다.이 모든 것이 수정되었습니다.

버그는 차치하고 알고리즘은 기본적으로 기본 10에서 기본 26으로 숫자를 변환하는 것입니다.

업데이트 2: Joel Coehoorn이 옳습니다. 위 코드는 27에 대해 AB를 반환합니다.만약 그것이 실제 base 26 번호라면, AA는 A와 같고, Z 뒤의 다음 번호는 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;

..그리고 php로 변환:

function GetExcelColumnName($columnNumber) {
    $columnName = '';
    while ($columnNumber > 0) {
        $modulo = ($columnNumber - 1) % 26;
        $columnName = chr(65 + $modulo) . $columnName;
        $columnNumber = (int)(($columnNumber - $modulo) / 26);
    }
    return $columnName;
}

재귀에 의한 간단한2 행의 C# 실장만 하면 됩니다.여기에서는 모든 답변이 필요 이상으로 복잡해 보이기 때문입니다.

/// <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);
}

이미 많은 유효한1 답이 있지만, 아무도 그 뒤에 있는 이론에 들어가지 않는다.

Excel 열 이름은 해당 번호를 base-26으로 표현한 입니다.이는 일반 베이스 26(선행 0은 없음)과는 상당히 다르므로 Wikipedia 엔트리를 읽고 차이점을 파악하는 것을 추천합니다.예를 들어, 10진수 값702됨)26*26 + 26으로 26을 나타낼 26을 나타낼 때 사용합니다.110 (예:)1x26^2 + 1x26^1 + 0x26^0) bijectionive base-26 by.ZZ (예:)26x26^1 + 26x26^0를 참조해 주세요.

차이는 차치하고, 생물적 숫자위치 표기법이며, 따라서 우리는 각 반복에서 다음 위치의 숫자를 찾는 반복(또는 재귀) 알고리즘을 사용하여 변환을 수행할 수 있다(일반 기저 변환 알고리즘과 유사).

분사 기저의 마지막 위치(지수 0)에서 숫자를 얻는 일반적인 공식은 다음과 같습니다.km필수)f천장 - 1 ) :

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

1)는을 음음즉(으, 즉 1)의 .f(m / k) 자릿수)에 알 수 f(m / k)0이 .

되는 각 .k10시 정하다.digit()는, 진수의 에 매핑 예: 「10」등).digit(1)A bijectionive 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);

이를 C#2으로 변환하여 일반적인3 "bijectionive base-k로 변환"을 얻을 수 있습니다.ToBijective()★★★★

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);
    }
}

이제 bijectionive base-26으로 변환하는 경우("Excel column name" 사용 사례:

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입니다.16384XFD아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.

추가 보너스로서, 우리는 이제 어떤 바이젝티브 베이스로도 쉽게 전환할 수 있습니다.를 들어 bijectionive 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 이 일반적인 답변은 결국 다른, 정확하고 구체적인 답변으로 귀결될 수 있지만, 나는 일반적으로 생물적 숫자에 대한 공식적인 이론 없이는 해결책의 논리를 완전히 파악하기가 어렵다는 것을 알게 된다.그것은 또한 그것의 정확성을 잘 증명한다.또, 몇개의 유사한 질문이, 언어에 구애받지 않는 질문, 또는 보다 일반적인 질문으로 되돌아갑니다.그래서 나는 이 답변의 추가가 정당하다고 생각했고, 이 질문은 그것을 넣기에 좋은 장소라고 생각했다.

2 C# 면책사항:C#의 예시는 여기에 기재되어 있기 때문에 실장했습니다만, 언어를 배우거나 사용한 적은 없습니다.컴파일 및 실행이 가능한 것은 확인했습니다만, 필요에 따라서 언어의 베스트 프랙티스/일반 규약에 맞추어 변경해 주세요.

3 이 예에서는 정확하고 이해하기 쉬운 것만 목적으로 하고 있습니다.최적화할 수 있고 최적화할 수 있어야 합니다(예를 들어 테일 재귀 -- 그러나 이 예에서는 C#에서의 트램폴리닝이 필요한 것 같으며, 보다 안전합니다(예를 들어 파라미터 검증).

col index와 col Label 사이의 상호 배열을 위해 사용하는 정적 클래스를 삽입하려고 합니다.ColumnLabel 메서드에 수정된 승인 답변을 사용합니다.

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;
    }
}

이걸 이렇게...

30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
private String getColumn(int c) {
    String s = "";
    do {
        s = (char)('A' + (c % 26)) + s;
        c /= 26;
    } while (c-- > 0);
    return s;
}

정확히는 베이스 26이 아닙니다.시스템에 0은 없습니다.만약 있다면, 'Z' 뒤에 'AA'가 아니라 'BA'가 뒤따를 것이다.

코드 없는 셀 공식에 대해서만 원하는 경우 공식은 다음과 같습니다.

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))

델파이(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;

게임 시작은 조금 늦었지만 사용하는 코드는 다음과 같습니다(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));
}

perl에서는 1(A), 27(AA) 등의 입력에 대해서.

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;
}

내가 게임에 늦었지만, 그레이엄의 대답은 결코 최적이 아니다.특히, 이 명령어를 사용할 필요가 없습니다.modulo,불러ToString()신청하다(int)cast. 대부분의 경우 C# 세계에서는 0부터 번호를 매기기 시작합니다.다음은 개정판입니다.

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;
}

이미 30개 이상의 솔루션이 제공되고 있습니다만, 여기 C#의 솔루션이 있습니다.

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)));
}

여기에 제공된 버전을 모두 확인한 후 재귀로 직접 수행하기로 했습니다.

vb.net 버전은 다음과 같습니다.

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

파워셸에 있는 그레이엄의 암호는 다음과 같습니다.

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;
}

원래의 솔루션 개량(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;
    }
}

Actionscript 버전은 다음과 같습니다.

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;
    }

JavaScript 솔루션

/**
 * 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;
};

특정 숫자(인덱스)를 Excel Column으로 변환하기 위한 my code입니다.

    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;
    }

마이 유닛 테스트:

    [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));
    }

죄송합니다. 이것은 C#이 아닌 Python이지만 적어도 결과는 정확합니다.

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))

다음의 테스트 케이스에 합격했습니다.

  • 컬럼 번호: 494286 => ABCDZ
  • 칼럼 번호: 27 = > AA
  • 열 번호: 52 = > AZ

다른 VBA 방식

Public Function GetColumnName(TargetCell As Range) As String
    GetColumnName = Split(CStr(TargetCell.Cells(1, 1).Address), "$")(1)
End Function

여기 PHP에 대한 저의 초라한 구현이 있습니다.이건 재귀적이야제가 이 글을 발견하기 직전에 쓴 거예요.다른 사람들이 이미 이 문제를 해결했는지 보고 싶었는데...

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;
}

언급URL : https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-e-g-127-into-an-excel-column-e-g-aa