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

자동화를 사용하여 Excel에서 직접 값을 가져 오지 않고 C #에서 숫자를 Excel 열 이름으로 변환하는 방법은 무엇입니까?

Excel 2007의 가능한 범위는 1-16384이며 지원되는 열 수입니다. 결과 값은 A, AA, AAA 등 엑셀 열 이름 형식이어야합니다.



답변

내가하는 방법은 다음과 같습니다.

private string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (int)((dividend - 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


답변

죄송합니다. 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))


답변

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


답변

첫 번째 게시물에서 오류가 발견되어 앉아서 ​​수학을하기로 결정했습니다. 내가 찾은 것은 다른 사람이 게시 한 것처럼 Excel 열을 식별하는 데 사용되는 숫자 시스템이 기본 26 시스템이 아니라는 것입니다. 밑줄 10에서 다음을 고려하십시오. 알파벳 문자로도이를 수행 할 수 있습니다.

공간 : ……………………. S1, S2, S3 : S1, S2, S3
………… …………………… 0, 00, 000 : .. A, AA, AAA
…………. ………………….. 1, 01, 001 : .. B, AB, AAB
………….. …………… …, …, … .. … … …
… … … … … ………………… 9, 99, 999 : .. Z, ZZ, ZZZ
공간의 총 상태 : 10, 100, 1000 : 26, 676, 17576
총 상태 : …………… 1110 ……………. 18278

Excel은 base 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 { 기본 a} (A (a-1) / a +1). a = 10 및 K = 192의 예를 사용하면 N = 2.23804… 이것은 K가 두 번째보다 약간 크기 때문에 세 번째 공간의 시작 부분에 있다는 것을 말해줍니다.

다음 단계는 현재 공간에서 얼마나 멀리 있는지 정확히 찾는 것입니다. 이를 찾으려면 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;
    }


답변

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를 반환합니다. 실제 밑수 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;


답변

재귀가 쉽습니다.

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