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

BeNdErR
quelle
14
Wie kommt es, dass dies nicht eingebaut ist?
Cyril Duchon-Doris
1
Duplikat: stackoverflow.com/questions/12699030/…
Ondra Žižka
1
Beste Antwort
Stephen M. Harris
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;
}
AdamL
quelle
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.

Wronex
quelle
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.
Ondra Žižka
quelle
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 ())

SauloAlessandre
quelle
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"

Tomi Heiskanen
quelle
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')
Pascal DeMilly
quelle
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!

Gärtner
quelle
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
hum3
quelle
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)
Fred
quelle
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 :)

Ondra Žižka
quelle
0

Java Apache POI

String columnLetter = CellReference.convertNumToColString(columnNumber);
CelinHC
quelle
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")
Christian Swanson
quelle
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)
}
Ian Elliott
quelle
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
Redlasha
quelle
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;
}

jim_kastrin
quelle
0

In Python gibt es die gspread-Bibliothek

import gspread
column_letter = gspread.utils.rowcol_to_a1(1, <put your col number here>)[:-1]

Wenn Sie Python nicht verwenden können, empfehle ich, den Quellcode von rowcol_to_a1 () unter https://github.com/burnash/gspread/blob/master/gspread/utils.py zu suchen

George C.
quelle
-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)))"
}

Mike Shaw
quelle
-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))
blais
quelle
Das ist es nicht. Die Frage ist nicht base26. Ich wurde auch ursprünglich dazu gelockt :)
Ondra Žižka