열 인덱스를 Excel 열 이름으로 변환
열 인덱스가 주어진 경우 엑셀 열 이름을 어떻게 얻을 수 있습니까?
26번 베이스가 아니기 때문에 문제는 생각보다 복잡합니다.열은 일반 숫자처럼 겹치지 않습니다.마이크로소프트 지원 사례조차도 ZZZ 이상으로 확장할 수 없습니다.
면책 사항:이것은 제가 얼마 전에 했던 코드인데, 오늘 제 데스크톱에 다시 들어왔습니다.사전답변 질문으로 여기에 글을 올릴 가치가 있다고 생각했습니다.
제가 생각해낸 답은 약간의 재귀적인 것입니다.이 코드는 VB에 있습니다.그물:
Function ColumnName(ByVal index As Integer) As String
Static chars() As Char = {"A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
index -= 1 ' adjust so it matches 0-indexed array rather than 1-indexed column
Dim quotient As Integer = index \ 26 ' normal / operator rounds. \ does integer division, which truncates
If quotient > 0 Then
ColumnName = ColumnName(quotient) & chars(index Mod 26)
Else
ColumnName = chars(index Mod 26)
End If
End Function
그리고 C#에서:
string ColumnName(int index)
{
index -= 1; //adjust so it matches 0-indexed array rather than 1-indexed column
int quotient = index / 26;
if (quotient > 0)
return ColumnName(quotient) + chars[index % 26].ToString();
else
return chars[index % 26].ToString();
}
private char[] chars = new char[] {'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'};
유일한 단점은 0인덱스가 아닌 1인덱스 열을 사용한다는 것입니다.
여기 제로 기반 열 인덱스와 char 배열 없이 작동하도록 Joel의 멋진 코드가 수정되었습니다.
Public Shared Function GetExcelColumn(ByVal index As Integer) As String
Dim quotient As Integer = index \ 26 ' Truncate
If quotient > 0 Then
Return GetExcelColumn(quotient - 1) & Chr((index Mod 26) + 64).ToString
Else
Return Chr(index + 64).ToString
End If
End Function
바로 이러한 이유로 엑셀의 프로그래밍된 인터페이스에서 열 이름을 피하게 됩니다.열 번호를 사용하는 것은 Cell(r,c) 참조 및 R1C1 주소 지정에서 매우 잘 작동합니다.
편집: Range 기능은 Range(Cell(r1,c1), Cell(r2,c2))에서와 같이 셀 참조도 사용합니다.또한 Address 기능을 사용하여 셀 또는 범위의 A1 스타일 주소를 얻을 수 있습니다.
EDIT2: 다음은 Address() 함수를 사용하여 열 이름을 검색하는 VBA 함수입니다.
Function colname(colindex)
x = Cells(1, colindex).Address(False, False) ' get the range name (e.g. AB1)
colname = Mid(x, 1, Len(x) - 1) ' return all but last character
End Function
public static String translateColumnIndexToName(int index) {
//assert (index >= 0);
int quotient = (index)/ 26;
if (quotient > 0) {
return translateColumnIndexToName(quotient-1) + (char) ((index % 26) + 65);
} else {
return "" + (char) ((index % 26) + 65);
}
}
테스트:
for (int i = 0; i < 100; i++) {
System.out.println(i + ": " + translateColumnIndexToName(i));
}
출력은 다음과 같습니다.
0: A
1: B
2: C
3: D
4: E
5: F
6: G
7: H
8: I
9: J
10: K
11: L
12: M
13: N
14: O
15: P
16: Q
17: R
18: S
19: T
20: U
21: V
22: W
23: X
24: Y
25: Z
26: AA
27: AB
28: AC
POI 기준 0이 필요했습니다.
인덱스에서 이름으로의 변환:
public static int translateComunNameToIndex0(String columnName) {
if (columnName == null) {
return -1;
}
columnName = columnName.toUpperCase().trim();
int colNo = -1;
switch (columnName.length()) {
case 1:
colNo = (int) columnName.charAt(0) - 64;
break;
case 2:
colNo = ((int) columnName.charAt(0) - 64) * 26 + ((int) columnName.charAt(1) - 64);
break;
default:
//illegal argument exception
throw new IllegalArgumentException(columnName);
}
return colNo;
}
# Python 2.x, no recursive function calls
def colname_from_colx(colx):
assert colx >= 0
colname = ''
r = colx
while 1:
r, d = divmod(r, 26)
colname = chr(d + ord('A')) + colname
if not r:
return colname
r -= 1
이것은 오래된 게시물이지만, 몇몇 솔루션을 보고 나는 나만의 C# 변형을 생각해 냈습니다. 0-Based, 재귀 없이:
public static String GetExcelColumnName(int columnIndex)
{
if (columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex: " + columnIndex);
}
Stack<char> stack = new Stack<char>();
while (columnIndex >= 0)
{
stack.Push((char)('A' + (columnIndex % 26)));
columnIndex = (columnIndex / 26) - 1;
}
return new String(stack.ToArray());
}
다음은 주요 전환 지점에서의 몇 가지 테스트 결과입니다.
0: A
1: B
2: C
...
24: Y
25: Z
26: AA
27: AB
...
50: AY
51: AZ
52: BA
53: BB
...
700: ZY
701: ZZ
702: AAA
703: AAB
python에서, 재귀와 함께. 조이의 대답에서 번역. 지금까지 GetExcelByColumn(35) = 'AI'까지 작동하는 것으로 테스트되었습니다.
def GetExcelColumn(index):
quotient = int(index / 26)
if quotient > 0:
return GetExcelColumn(quotient) + str(chr((index % 26) + 64))
else:
return str(chr(index + 64))
php 버전, 제가 알아낼 수 있게 도와주신 이 게시물 감사합니다! ^^
/**
* Get excel column name
* @param index : a column index we want to get the value in excel column format
* @return (string) : excel column format
*/
function getexcelcolumnname($index) {
//Get the quotient : if the index superior to base 26 max ?
$quotient = $index / 26;
if ($quotient >= 1) {
//If yes, get top level column + the current column code
return getexcelcolumnname($quotient-1). chr(($index % 26)+65);
} else {
//If no just return the current column code
return chr(65 + $index);
}
}
자바스크립트 솔루션
/**
* Calculate the column letter abbreviation from a 0 based index
* @param {Number} value
* @returns {string}
*/
getColumnFromIndex = function (value) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
value++;
var remainder, result = "";
do {
remainder = value % 26;
result = base[(remainder || 26) - 1] + result;
value = Math.floor(value / 26);
} while (value > 0);
return result;
};
나는 재귀적 함수를 쓰는 것을 좋아하지만, 여기서는 그것이 필요하지 않다고 생각합니다.이것이 VB에서의 나의 해결책입니다.열 ZZ까지 작동합니다.누군가 나에게 그것이 AAA에게 ZZZ에 적합한지 말해줄 수 있다면 알려주면 좋을 것 같습니다.
Public Function TranslateColumnIndexToName(index As Integer) As String
'
Dim remainder As Integer
Dim remainder2 As Integer
Dim quotient As Integer
Dim quotient2 As Integer
'
quotient2 = ((index) / (26 * 26)) - 2
remainder2 = (index Mod (26 * 26)) - 1
quotient = ((remainder2) / 26) - 2
remainder = (index Mod 26) - 1
'
If quotient2 > 0 Then
TranslateColumnIndexToName = ChrW(quotient2 + 65) & ChrW(quotient + 65) & ChrW(remainder + 65)
ElseIf quotient > 0 Then
TranslateColumnIndexToName = ChrW(quotient + 65) & ChrW(remainder + 65)
Else
TranslateColumnIndexToName = ChrW(remainder + 65)
End If
함수 종료
여기 C#에 있는 나의 해결책이 있습니다.
// test
void Main()
{
for( var i = 0; i< 1000; i++ )
{ var byte_array = code( i );
Console.WriteLine("{0} | {1} | {2}", i, byte_array, offset(byte_array));
}
}
// Converts an offset to AAA code
public string code( int offset )
{
List<byte> byte_array = new List<byte>();
while( offset >= 0 )
{
byte_array.Add( Convert.ToByte(65 + offset % 26) );
offset = offset / 26 - 1;
}
return ASCIIEncoding.ASCII.GetString( byte_array.ToArray().Reverse().ToArray());
}
// Converts AAA code to an offset
public int offset( string code)
{
var offset = 0;
var byte_array = Encoding.ASCII.GetBytes( code ).Reverse().ToArray();
for( var i = 0; i < byte_array.Length; i++ )
{
offset += (byte_array[i] - 65 + 1) * Convert.ToInt32(Math.Pow(26.0, Convert.ToDouble(i)));
}
return offset - 1;
}
열 인덱스와 열 이름 사이의 양방향 번역을 위해 C#로 답변을 드립니다.
/// <summary>
/// Gets the name of a column given the index, as it would appear in Excel.
/// </summary>
/// <param name="columnIndex">The zero-based column index number.</param>
/// <returns>The name of the column.</returns>
/// <example>Column 0 = A, 26 = AA.</example>
public static string GetColumnName(int columnIndex)
{
if (columnIndex < 0) throw new ArgumentOutOfRangeException("columnIndex", "Column index cannot be negative.");
var dividend = columnIndex + 1;
var columnName = string.Empty;
while (dividend > 0)
{
var modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo) + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
/// <summary>
/// Gets the zero-based column index given a column name.
/// </summary>
/// <param name="columnName">The column name.</param>
/// <returns>The index of the column.</returns>
public static int GetColumnIndex(string columnName)
{
var index = 0;
var total = 0;
for (var i = columnName.Length - 1; i >= 0; i--)
total += (columnName.ToUpperInvariant()[i] - 64) * (int)Math.Pow(26, index++);
return total - 1;
}
루비:
class Fixnum
def col_name
quot = self/26
(quot>0 ? (quot-1).col_name : "") + (self%26+65).chr
end
end
puts 0.col_name # => "A"
puts 51.col_name # => "AZ"
이 자바스크립트 버전은 핵심이 베이스 26으로 전환되었음을 보여줍니다.
function colName(x)
{
x = (parseInt("ooooooop0", 26) + x).toString(26);
return x.slice(x.indexOf('p') + 1).replace(/./g, function(c)
{
c = c.charCodeAt(0);
return String.fromCharCode(c < 64 ? c + 17 : c - 22);
});
}
.toString(26)
비트는 Joel Coehorn이 틀렸다는 것을 보여줍니다. 그것은 단순한 기본 변환입니다.
(참고: 제작 시 Dana의 답변을 바탕으로 좀 더 간단한 구현이 있습니다.덜 무겁고, 더 큰 숫자에는 효과가 있지만, 저에게는 영향이 없을 뿐만 아니라, 수학적 원리를 명확하게 보여주지도 못합니다.)
추신: 중요한 지점에서 평가된 기능은 다음과 같습니다.
0 A
1 B
9 J
10 K
24 Y
25 Z
26 AA
27 AB
700 ZY
701 ZZ
702 AAA
703 AAB
18276 ZZY
18277 ZZZ
18278 AAAA
18279 AAAB
475252 ZZZY
475253 ZZZZ
475254 AAAAA
475255 AAAAB
12356628 ZZZZY
12356629 ZZZZZ
12356630 AAAAAA
12356631 AAAAAB
321272404 ZZZZZY
321272405 ZZZZZZ
321272406 AAAAAAA
321272407 AAAAAAB
8353082580 ZZZZZZY
8353082581 ZZZZZZZ
8353082582 AAAAAAAA
8353082583 AAAAAAAB
스위프트 4와 함께 합니다.
@IBAction func printlaction(_ sender: Any) {
let textN : Int = Int (number_textfield.text!)!
reslut.text = String (printEXCL_Letter(index: textN))
}
func printEXCL_Letter(index : Int) -> String {
let letters = ["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"]
var index = index;
index -= 1
let index_div = index / 26
if (index_div > 0){
return printEXCL_Letter(index: index_div) + letters[index % 26];
}
else {
return letters[index % 26]
}
}
언급URL : https://stackoverflow.com/questions/297213/translate-a-column-index-into-an-excel-column-name
'programing' 카테고리의 다른 글
PL/SQL 날짜에서 X 일 전에 X를 가져오는 방법은? (0) | 2023.09.10 |
---|---|
INSERT GRANGE가 auto_increment primary key를 증가시키는 이유는 무엇입니까? (0) | 2023.09.10 |
Ajax 오류 후 RxJS 계속 듣기 (0) | 2023.09.10 |
Windows : 크기와 마지막 액세스 날짜로 파일을 재귀적으로 나열하는 방법? (0) | 2023.09.10 |
Oracle 11g dmp 가져오기.ORA-39000 / ORA-39143 오류 (0) | 2023.09.10 |