Wie finde ich den Excel-Spaltennamen, der einer bestimmten Ganzzahl entspricht?[Duplikat]
-
09-06-2019 - |
Frage
Auf diese Frage gibt es hier bereits eine Antwort:
Wie würden Sie den Spaltennamen bestimmen (z. B.„AQ“ oder „BH“) der n-ten Spalte in Excel?
Bearbeiten:Ein sprachunabhängiger Algorithmus, um dies zu bestimmen, ist hier das Hauptziel.
Lösung
Ich habe diese Funktion einmal geschrieben, um genau diese Aufgabe auszuführen:
public static string Column(int column)
{
column--;
if (column >= 0 && column < 26)
return ((char)('A' + column)).ToString();
else if (column > 25)
return Column(column / 26) + Column(column % 26 + 1);
else
throw new Exception("Invalid Column #" + (column + 1).ToString());
}
Andere Tipps
Hier ist es am saubersten richtig Lösung, die mir einfallen könnte (in Java, aber Sie können gerne Ihre Lieblingssprache verwenden):
String getNthColumnName(int n) {
String name = "";
while (n > 0) {
n--;
name = (char)('A' + n%26) + name;
n /= 26;
}
return name;
}
Bitte teilen Sie mir jedoch mit, wenn Sie einen Fehler in diesem Code finden. Vielen Dank.
Ein sprachunabhängiger Algorithmus würde wie folgt aussehen:
function getNthColumnName(int n) {
let curPower = 1
while curPower < n {
set curPower = curPower * 26
}
let result = ""
while n > 0 {
let temp = n / curPower
let result = result + char(temp)
set n = n - (curPower * temp)
set curPower = curPower / 26
}
return result
Dieser Algorithmus berücksichtigt auch, wenn Excel erneut aktualisiert wird, um mehr als 16.000 Spalten zu verarbeiten.Wenn Sie es wirklich übertreiben möchten, können Sie einen zusätzlichen Wert übergeben und die Stellen von 26 durch eine andere Zahl ersetzen, um alternative Alphabete zu ermöglichen
Danke, Joseph Sturtevant!Ihr Code funktioniert perfekt – ich brauchte ihn in VBScript, also dachte ich, ich würde meine Version teilen:
Function ColumnLetter(ByVal intColumnNumber)
Dim sResult
intColumnNumber = intColumnNumber - 1
If (intColumnNumber >= 0 And intColumnNumber < 26) Then
sResult = Chr(65 + intColumnNumber)
ElseIf (intColumnNumber >= 26) Then
sResult = ColumnLetter(CLng(intColumnNumber \ 26)) _
& ColumnLetter(CLng(intColumnNumber Mod 26 + 1))
Else
err.Raise 8, "Column()", "Invalid Column #" & CStr(intColumnNumber + 1)
End If
ColumnLetter = sResult
End Function
Josephs Code ist gut, aber wenn Sie keine VBA-Funktion verwenden möchten oder müssen, versuchen Sie es mit diesem.
Angenommen, der Wert von n befindet sich in der Zelle A2
Verwenden Sie diese Funktion:
=MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
Dies funktioniert mit 2 Buchstabenspalten (bis zur Spalte). ZZ
).Sie müssten eine weitere if-Anweisung für Spalten mit drei Buchstaben verschachteln.
Die obige Formel schlägt bei Spalten fehl AY
, AZ
und jedes der folgenden nY
Und nZ
Säulen.Die korrigierte Formel lautet:
=IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)
VON wcm:
Wenn Sie VBA nicht verwenden möchten, können Sie diesen Ersatz für Colnr durch die gewünschte Nummer verwenden
=MID(ADDRESS(1,colnr),2,LEN(ADDRESS(1,colnr))-3)
Bitte beachten Sie, dass diese Formel aufgrund der Verwendung der ADDRESS-Funktion flüchtig ist.Volatile Funktionen sind Funktionen, die von Excel nach JEDER Änderung neu berechnet werden.Normalerweise berechnet Excel Formeln nur dann neu, wenn sich ihre abhängigen Referenzen ändern.
Es könnte ein Leistungskiller sein, diese Formel zu verwenden.
Und hier ist eine Konvertierung von der VBScript-Version auf SQL Server 2000+.
CREATE FUNCTION [dbo].[GetExcelColRef]
(
@col_seq_no int
)
RETURNS varchar(5)
AS
BEGIN
declare @Result varchar(5)
set @Result = ''
set @col_seq_no = @col_seq_no - 1
If (@col_seq_no >= 0 And @col_seq_no < 26)
BEGIN
set @Result = char(65 + @col_seq_no)
END
ELSE
BEGIN
set @Result = [dbo].[GetExcelColRef] (@col_seq_no / 26) + '' + [dbo].[GetExcelColRef] ((@col_seq_no % 26) + 1)
END
Return @Result
END
GO
Ruby-Einzeiler:
def column_name_for(some_int)
some_int.to_s(26).split('').map {|c| (c.to_i(26) + 64).chr }.join # 703 => "AAA"
end
Es konvertiert die Ganzzahl in Base26, teilt sie dann auf und führt einige Berechnungen durch, um jedes Zeichen aus dem ASCII-Format zu konvertieren.Endlich sind sie alle wieder zusammen.Keine Division, Modul oder Rekursion.
Spaß.
Dies funktioniert in MS Excel 2003-2010 einwandfrei.Sollte für frühere Versionen funktionieren, die das unterstützen Zellen(...).Adresse Funktion:
- Für die 28. Spalte - Einnahme
columnNumber=28
;Cells(1, columnNumber).Address
kehrt zurück"$AB$1"
. - Machen Sie einen Split auf dem
$
sign gibt das Array zurück:["","AB","1"]
- Also
Split(Cells(1, columnNumber).Address, "$")(1)
gibt Ihnen den Spaltennamen"AB"
.
AKTUALISIEREN:
Genommen von So konvertieren Sie Excel-Spaltennummern in alphabetische Zeichen
' The following VBA function is just one way to convert column number
' values into their equivalent alphabetical characters:
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
GILT FÜR:Microsoft Office Excel 2007 SE / 2002 SE / 2000 SE / 97 SE
Ich nehme an, Sie benötigen VBA-Code:
Public Function GetColumnAddress(nCol As Integer) As String
Dim r As Range
Set r = Range("A1").Columns(nCol)
GetColumnAddress = r.Address
End Function
Dies macht, was Sie in VBA wollen
Function GetNthExcelColName(n As Integer) As String
Dim s As String
s = Cells(1, n).Address
GetNthExcelColName = Mid(s, 2, InStr(2, s, "$") - 2)
End Function
Dies scheint in vb.net zu funktionieren
Public Function Column(ByVal pColumn As Integer) As String
pColumn -= 1
If pColumn >= 0 AndAlso pColumn < 26 Then
Return ChrW(Asc("A"c) + pColumn).ToString
ElseIf (pColumn > 25) Then
Return Column(CInt(math.Floor(pColumn / 26))) + Column((pColumn Mod 26) + 1)
Else
stop
Throw New ArgumentException("Invalid column #" + (pColumn + 1).ToString)
End If
End Function
Ich nahm Joseph's und testete es bei BH, fütterte es dann mit 980-1000 und es sah gut aus.
In VBA wird davon ausgegangen, dass lCol die Spaltennummer ist:
function ColNum2Letter(lCol as long) as string
ColNum2Letter = Split(Cells(1, lCol).Address, "$")(0)
end function
Alle diese Codebeispiele, die diese guten Leute gepostet haben, sehen gut aus.
Es gibt eine Sache, die man beachten sollte.Ab Office 2007 verfügt Excel tatsächlich über bis zu 16.384 Spalten.Das bedeutet XFD (das alte Maximum von 256 Spalten war IV).Sie müssen diese Methoden etwas modifizieren, damit sie für drei Zeichen funktionieren.
Sollte nicht so schwer sein...
Hier ist die Lösung von Gary Waters
Function ConvertNumberToColumnLetter2(ByVal colNum As Long) As String
Dim i As Long, x As Long
For i = 6 To 0 Step -1
x = (1 - 26 ^ (i + 1)) / (-25) - 1 ‘ Geometric Series formula
If colNum > x Then
ConvertNumberToColumnLetter2 = ConvertNumberToColumnLetter2 & Chr(((colNum - x - 1)\ 26 ^ i) Mod 26 + 65)
End If
Next i
End Function
über http://www.dailydoseofexcel.com/archives/2004/05/21/column-numbers-to-letters/
Unter Berücksichtigung des Kommentars von wcm (oberster Wert = xfd) können Sie ihn wie folgt berechnen;
function IntToExcel(n: Integer); string;
begin
Result := '';
for i := 2 down to 0 do
begin
if ((n div 26^i)) > 0) or (i = 0) then
Result := Result + Char(Ord('A')+(n div (26^i)) - IIF(i>0;1;0));
n := n mod (26^i);
end;
end;
Es gibt 26 Zeichen im Alphabet und wir haben ein Zahlensystem wie hexadezimal oder binär, nur mit einem ungewöhnlichen Zeichensatz (A..Z), der die Potenzen von 26 positionell darstellt:(26^2)(26^1)(26^0).
Zu Ihrer Information: T-SQL gibt den Excel-Spaltennamen mit einer Ordinalzahl (nullbasiert) als einzelne Anweisung an.
Alles unter 0 oder über 16.383 (maximale Spaltenanzahl in Excel2010) gibt NULL zurück.
; WITH TestData AS ( -- Major change points
SELECT -1 AS FieldOrdinal
UNION ALL
SELECT 0
UNION ALL
SELECT 25
UNION ALL
SELECT 26
UNION ALL
SELECT 701
UNION ALL
SELECT 702
UNION ALL
SELECT 703
UNION ALL
SELECT 16383
UNION ALL
SELECT 16384
)
SELECT
FieldOrdinal
, CASE
WHEN FieldOrdinal < 0 THEN NULL
WHEN FieldOrdinal < 26 THEN ''
WHEN FieldOrdinal < 702 THEN CHAR (65 + FieldOrdinal / 26 - 1)
WHEN FieldOrdinal < 16384 THEN CHAR (65 + FieldOrdinal / 676 - 1)
+ CHAR (65 + (FieldOrdinal / 26) - (FieldOrdinal / 676) * 26 - 1)
ELSE NULL
END
+ CHAR (65 + FieldOrdinal % 26)
FROM TestData
ORDER BY FieldOrdinal
Ich verwende dies derzeit, habe aber das Gefühl, dass es optimiert werden kann.
private String GetNthExcelColName(int n)
{
String firstLetter = "";
//if number is under 26, it has a single letter name
// otherwise, it is 'A' for 27-52, 'B' for 53-78, etc
if(n > 26)
{
//the Converts to double and back to int are just so Floor() can be used
Double value = Convert.ToDouble((n-1) / 26);
int firstLetterVal = Convert.ToInt32(Math.Floor(value))-1;
firstLetter = Convert.ToChar(firstLetterValue + 65).ToString();
}
//second letter repeats
int secondLetterValue = (n-1) % 26;
String secondLetter = Convert.ToChar(secondLetterValue+65).ToString();
return firstLetter + secondLetter;
}
=CHAR(64+COLUMN())