Konvertieren Sie den Spaltenindex in den entsprechenden Spaltenbuchstaben


86

Ich muss einen Google Spreadsheet-Spaltenindex in den entsprechenden Buchstabenwert konvertieren, z. B. anhand einer Tabelle:

Geben Sie hier die Bildbeschreibung ein

Ich muss dies tun (diese Funktion existiert offensichtlich nicht, es ist ein Beispiel):

getColumnLetterByIndex(4);  // this should return "D"
getColumnLetterByIndex(1);  // this should return "A"
getColumnLetterByIndex(6);  // this should return "F"

Jetzt erinnere ich mich nicht genau, ob der Index von 0oder von beginnt 1, trotzdem sollte das Konzept klar sein.

Ich habe in der Gasdokumentation nichts darüber gefunden. Bin ich blind? Irgendeine Idee?

Vielen Dank


14
Wie kommt es, dass dies nicht eingebaut ist?
Cyril Duchon-Doris



1
X = (n) => (a = Math.floor (n / 26))> = 0? X (a-1) + String.fromCharCode (65+ (n% 26)): '';
Pascal DeMilly

Antworten:


151

Ich habe diese vor einiger Zeit für verschiedene Zwecke geschrieben (gibt die aus zwei Buchstaben bestehenden Spaltennamen für Spaltennummern> 26 zurück):

function columnToLetter(column)
{
  var temp, letter = '';
  while (column > 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}

function letterToColumn(letter)
{
  var column = 0, length = letter.length;
  for (var i = 0; i < length; i++)
  {
    column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
  }
  return column;
}

1
Ist das Maximum kleiner als ZZ?
Old Geezer

1
Verwenden Sie dies nur, um die Spaltennummern zu erhöhen : var column = letterToColumn(AA); columnToLetter(column + 1);. Könnte jemandem helfen.
Joshfindit

1
Ich schlage vor, zu ändern column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);, column += (letter.toUpperCase().charCodeAt(i) - 64) * Math.pow(26, length - i - 1);damit es funktioniert, wenn letteres Kleinbuchstaben enthält, andernfalls awürde es 33anstelle von1
tukusejssirs

fwiw - dies war ein Interview Q für mich bei einem der großen Cos
Taylor Halliday

Ich denke, String.fromCharCodefunktioniert nicht mit Apps Script
c-an

68

Das funktioniert gut

=REGEXEXTRACT(ADDRESS(ROW(); COLUMN()); "[A-Z]+")

auch für Spalten jenseits von Z.

Funktionsdemo

Ersetzen COLUMN()Sie einfach durch Ihre Spaltennummer. Der Wert von ROW()spielt keine Rolle.


4
Sie verwenden Formeln, nicht GAS
BeNdErR

11
Das funktioniert wirklich gut. Auch wenn hier kein GAS verwendet wird (mit dem die Frage markiert ist), sind integrierte Funktionen fast immer vorzuziehen, da sie überhaupt nicht geschrieben werden müssen und meiner Erfahrung nach erheblich schneller ausgeführt werden.
Kevinmicke

36
=SUBSTITUTE(ADDRESS(1,COLUMN(),4), "1", "")

Dies nimmt Ihre Zelle, erhält ihre Adresse als zB C1 und entfernt die "1".

Geben Sie hier die Bildbeschreibung ein

Wie es funktioniert

  • COLUMN() gibt die Nummer der Spalte der Zelle an.
  • ADDRESS(1, ..., <format>)gibt eine Adresse einer Zelle in einem durch <format>Parameter angegebenen Format an . 4bedeutet die Adresse, die Sie kennen - z C1.
    • Die Zeile spielt hier keine Rolle, also verwenden wir 1.
    • Siehe ADDRESSDokumente
  • Schließlich SUBSTITUTE(..., "1", "")ersetzt die 1in der Adresse C1, so dass Sie mit dem Spaltenbuchstaben links sind.

3
Dies ist eine elegante Lösung - ich mag es am besten. Ich bin mir nicht sicher, warum es nicht mehr Upvotes gibt.
Singularität

1
Ich habe dies beim Versuch bekommen: screencast.com/t/Jmc8L9W5LB . Ich habe das herausgefunden. Ich habe es gelöst, indem ich alle Kommas durch Semikolons ersetzt habe. Dies ist wahrscheinlich ein Lokalisierungsproblem
David

@ David, es funktioniert bei mir mit Kommas. Möglicherweise liegt es an den Gebietsschemaeinstellungen.
Ondra Žižka

1
Die Frage lautet nach einer Funktion zur Verwendung in Skripten, während diese Lösung eine Formel zur Verwendung in Zellen enthält.
Markshep

Wirklich elegante Lösung.
Gabz

21

diese Arbeit am Intervall AZ

= char (64 + Spalte ())


2
Dies ist ziemlich schwierig für Leute, die keinen Programmierhintergrund haben und nicht an Spalten jenseits von "Z" (dh "AA") arbeiten, aber ich mag es trotzdem, weil es die kürzeste und schnellste Berechnung ist (z. B. könnten Sie 1.000 haben s davon gehen sofort, ohne dass Ihr Computer ins Schwitzen kommt).
Dave

20

Hier muss das Rad nicht neu erfunden werden. Verwenden Sie stattdessen die GAS-Reihe:

 var column_index = 1; // your column to resolve
 
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = ss.getSheets()[0];
 var range = sheet.getRange(1, column_index, 1, 1);

 Logger.log(range.getA1Notation().match(/([A-Z]+)/)[0]); // Logs "A"


6

In Javascript:

X = (n) => (a=Math.floor(n/26)) >= 0 ? X(a-1) + String.fromCharCode(65+(n%26)) : '';
console.assert (X(0) == 'A')
console.assert (X(25) == 'Z')
console.assert (X(26) == 'AA')
console.assert (X(51) == 'AZ')
console.assert (X(52) == 'BA')

Ich wünschte, es würde in Google-Skripten funktionieren, aber erstaunlicher kleiner Code.
Giampaolo Ferradini

1
@Giam Es funktioniert im Apps-Skript. Dies sollte die akzeptierte Antwort sein
TheMaster


3

Wenn Sie die Antwort von @ SauloAlessandre hinzufügen, funktioniert dies für Spalten von A bis ZZ.

=if(column() >26,char(64+(column()-1)/26),) & char(65 + mod(column()-1,26))

Ich mag die Antworten von @wronex und @Ondra Žižka. Ich mag jedoch die Einfachheit der Antwort von @ SauloAlessandre sehr.

Also habe ich gerade den offensichtlichen Code hinzugefügt, damit die Antwort von @ SauloAlessandre für breitere Tabellenkalkulationen funktioniert.

Wie @Dave in seinem Kommentar erwähnt hat, ist es hilfreich, einen Programmierhintergrund zu haben, insbesondere einen in C, bei dem wir einer Zahl den Hex-Wert 'A' hinzugefügt haben, um den n-ten Buchstaben des Alphabets als Standardmuster zu erhalten.

Die Antwort wurde aktualisiert, um den von @Sangbok Lee angegebenen Fehler zu erkennen. Vielen Dank!


1
Es gibt @statt Zbei Verwendung in ZSpalte.
Sangbok Lee

1
@ Sangbok ist richtig! Dies wurde aktualisiert und für die Spalten Z, AA, AZ, BB getestet. Ich glaube, es wird durch ZZ funktionieren.
Gärtner

2

Ich habe auch nach einer Python-Version gesucht, die auf Python 3.6 getestet wurde

def columnToLetter(column):
    character = chr(ord('A') + column % 26)
    remainder = column // 26
    if column >= 26:
        return columnToLetter(remainder-1) + character
    else:
        return character

1
X=lambda n:~n and X(n/26-1)+chr(65+n%26)or''
Ondra Žižka

Wie auch immer, wenn ich mich nicht irre, ist dies base26. Tricky: neben Zsollte sein AA. Dies gibt BA.
Ondra Žižka

1
Ihre Version ist fast richtig, ich denke, es sollte sein: X=lambda n:~int(n) and X(int(n/26)-1)+chr(65+n%26)or''
hum3

Heiliger Mist, das war eine erstaunliche Lambda-Funktion, die du dort bekommen hast, hum3. Vielen Dank!
ViggoTW

Danke, aber ich habe gerade Ondras Lösung getestet.
hum3

2

Ich suchte nach einer Lösung in PHP. Vielleicht hilft das jemandem.

<?php

$numberToLetter = function(int $number)
{
    if ($number <= 0) return null;

    $temp; $letter = '';
    while ($number > 0) {
        $temp = ($number - 1) % 26;
        $letter = chr($temp + 65) . $letter;
        $number = ($number - $temp - 1) / 26;
    }
    return $letter;
};

$letterToNumber = function(string $letters) {
    $letters = strtoupper($letters);
    $letters = preg_replace("/[^A-Z]/", '', $letters);

    $column = 0; 
    $length = strlen($letters);
    for ($i = 0; $i < $length; $i++) {
        $column += (ord($letters[$i]) - 64) * pow(26, $length - $i - 1);
    }
    return $column;
};

var_dump($numberToLetter(-1));
var_dump($numberToLetter(26));
var_dump($numberToLetter(27));
var_dump($numberToLetter(30));

var_dump($letterToNumber('-1A!'));
var_dump($letterToNumber('A'));
var_dump($letterToNumber('B'));
var_dump($letterToNumber('Y'));
var_dump($letterToNumber('Z'));
var_dump($letterToNumber('AA'));
var_dump($letterToNumber('AB'));

Ausgabe:

NULL
string(1) "Z"
string(2) "AA"
string(2) "AD"
int(1)
int(1)
int(2)
int(25)
int(26)
int(27)
int(28)

1

Ein Kommentar zu meiner Antwort besagt, dass Sie eine Skriptfunktion dafür wollten. Also gut, los geht's:

function excelize(colNum) {
    var order = 1, sub = 0, divTmp = colNum;
    do {
        divTmp -= order; sub += order; order *= 26;
        divTmp = (divTmp - (divTmp % 26)) / 26;
    } while(divTmp > 0);

    var symbols = "0123456789abcdefghijklmnopqrstuvwxyz";
    var tr = c => symbols[symbols.indexOf(c)+10];
    return Number(colNum-sub).toString(26).split('').map(c=>tr(c)).join('');
}

Dies kann mit jeder Zahl umgehen, die JS verarbeiten kann, denke ich.

Erläuterung:

Da dies nicht base26 ist, müssen wir die Basiszeitreihenfolge für jedes zusätzliche Symbol ("Ziffer") subtrahieren. Also zählen wir zuerst die Reihenfolge der resultierenden Zahl und gleichzeitig die zu subtrahierende Zahl. Und dann konvertieren wir es in Basis 26 und subtrahieren es und verschieben dann die Symbole zu A-Zstatt 0-P.

Wie auch immer, diese Frage verwandelt sich in einen Code Golf :)


0

Java Apache POI

String columnLetter = CellReference.convertNumToColString(columnNumber);

0

Dies wird Sie bis zur Spalte AZ abdecken:

=iferror(if(match(A2,$A$1:$AZ$1,0)<27,char(64+(match(A2,$A$1:$AZ$1,0))),concatenate("A",char(38+(match(A2,$A$1:$AZ$1,0))))),"No match")

0

Hier ist eine allgemeine Version in Scala geschrieben. Es ist für einen Spaltenindexstart bei 0 (es ist einfach zu ändern für einen Indexstart bei 1):

def indexToColumnBase(n: Int, base: Int): String = {
  require(n >= 0, s"Index is non-negative, n = $n")
  require(2 <= base && base <= 26, s"Base in range 2...26, base = $base")

  def digitFromZeroToLetter(n: BigInt): String =
    ('A' + n.toInt).toChar.toString

  def digitFromOneToLetter(n: BigInt): String =
    ('A' - 1 + n.toInt).toChar.toString

  def lhsConvert(n: Int): String = {
    val q0: Int = n / base
    val r0: Int = n % base

    val q1 = if (r0 == 0) (n - base) / base else q0
    val r1 = if (r0 == 0) base else r0

    if (q1 == 0)
      digitFromOneToLetter(r1)
    else
      lhsConvert(q1) + digitFromOneToLetter(r1)
  }

  val q: Int = n / base
  val r: Int = n % base

  if (q == 0)
    digitFromZeroToLetter(r)
  else
    lhsConvert(q) + digitFromZeroToLetter(r)
}

def indexToColumnAtoZ(n: Int): String = {
  val AtoZBase = 26
  indexToColumnBase(n, AtoZBase)
}

0

Einfacher Weg durch Google Sheet-Funktionen von A bis Z.

=column(B2) : value is 2
=address(1, column(B2)) : value is $B$1
=mid(address(1, column(B2)),2,1) : value is B

Es ist ein komplizierter Weg durch Google Sheet-Funktionen, aber es ist auch mehr als AA.

=mid(address(1, column(AB3)),2,len(address(1, column(AB3)))-3) : value is AB

0

Eine Funktion zum rekursiven Konvertieren eines Spaltenindex in Buchstabenkombinationen:

function lettersFromIndex(index, curResult, i) {

  if (i == undefined) i = 11; //enough for Number.MAX_SAFE_INTEGER
  if (curResult == undefined) curResult = "";

  var factor = Math.floor(index / Math.pow(26, i)); //for the order of magnitude 26^i

  if (factor > 0 && i > 0) {
    curResult += String.fromCharCode(64 + factor);
    curResult = lettersFromIndex(index - Math.pow(26, i) * factor, curResult, i - 1);

  } else if (factor == 0 && i > 0) {
    curResult = lettersFromIndex(index, curResult, i - 1);

  } else {
    curResult += String.fromCharCode(64 + index % 26);

  }
  return curResult;
}



-1

In PowerShell:

function convert-IndexToColumn
{
    Param
    (
        [Parameter(Mandatory)]
        [int]$col
    )
    "$(if($col -gt 26){[char][int][math]::Floor(64+($col-1)/26)})$([char](65 + (($col-1) % 26)))"
}


-2

Hier ist eine Version mit null Index (in Python):

letters = []
while column >= 0:
    letters.append(string.ascii_uppercase[column % 26])
    column = column // 26 - 1
return ''.join(reversed(letters))

Das ist es nicht. Die Frage ist nicht base26. Ich wurde auch ursprünglich dazu gelockt :)
Ondra Žižka
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.