Sütun dizinini karşılık gelen sütun harfine dönüştür


88

Bir Google E-Tablo sütun dizinini karşılık gelen harf değerine dönüştürmem gerekiyor, örneğin, bir e-tablo verildiğinde:

görüntü açıklamasını buraya girin

Bunu yapmam gerekiyor (bu işlev açıkça mevcut değil, bu bir örnek):

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

Şimdi, indeks başlar tam olarak eğer hatırlamıyorum 0ya gelen 1, zaten konsept açık olmalıdır.

Gaz belgelerinde bununla ilgili hiçbir şey bulamadım .. Kör müyüm? Herhangi bir fikir?

teşekkür ederim


17
Bu nasıl oluyor da yerleşik değil ??
Cyril DUCHON-Doris


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

Yanıtlar:


158

Bunları bir süre önce çeşitli amaçlar için yazdım (> 26 sütun numaraları için çift harfli sütun adlarını döndüreceğim):

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
Maksimum ZZ'den küçük mü?
Old Geezer

1
Sadece artan bir sütun numaralarına kullandı: var column = letterToColumn(AA); columnToLetter(column + 1);. Birine yardımcı olabilir.
joshfindit

1
Ben değiştirmek için önermek column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);için column += (letter.toUpperCase().charCodeAt(i) - 64) * Math.pow(26, length - i - 1);eğer o iş yapmak letteriçin aksi takdirde küçük harfler içeren abu çıkış alacaktı 33yerine1
tukusejssirs

fwiw - bu benim için büyük Cos
Taylor Halliday'den

String.fromCharCodeApps Komut Dosyasında çalışmadığını düşünüyorum
c-an

70

Bu iyi çalışıyor

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

Z'nin ötesindeki sütunlar için bile.

İşlevin demosu

Sadece COLUMN()sütun numaranızla değiştirin . Değeri ROW()önemli değil.


4
GAS değil formül kullanıyorsunuz
BeNdErR

11
Bu gerçekten iyi çalışıyor. Bu GAS'ı kullanmasa da (sorunun etiketlendiği), yerleşik işlevler neredeyse her zaman tercih edilir çünkü yazılmalarına gerek yoktur ve tecrübelerime göre çok daha hızlı çalışırlar.
kevinmicke

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

Bu, hücrenizi alır, adresini örneğin C1 olarak alır ve "1" i kaldırır.

görüntü açıklamasını buraya girin

Nasıl çalışır

  • COLUMN() hücrenin sütun numarasını verir.
  • ADDRESS(1, ..., <format>)<format>parametre tarafından belirlenen biçimde bir hücrenin adresini verir . 4bildiğiniz adres anlamına gelir - ör C1.
    • Burada satırın önemi yok, bu yüzden kullanırız 1.
    • Belgelere bakınADDRESS
  • Son olarak, adresteki SUBSTITUTE(..., "1", "")yerini alır , böylece sütun harfiyle kalırsınız.1C1

3
Bu zarif bir çözüm - en iyisini beğendim. Neden daha fazla olumlu oy almadığından emin değilim.
tekillik

1
Bunu denerken anladım: screencast.com/t/Jmc8L9W5LB . Bunu ben çözdüm. Tüm virgülleri noktalı virgüllerle değiştirerek çözdüm. Bu muhtemelen bir yerelleştirme sorunudur
David

@David, virgülle benim için çalışıyor. Belki yerel ayarlardan dolayıdır.
Ondra Žižka

1
Soru, komut dosyalarında kullanılmak üzere bir işlev istemektir, oysa bu çözüm hücrelerde kullanım için bir formül verir.
markshep

Gerçekten zarif çözüm.
Gabz

23

Bu aralıklarda çalışır A-Z

=char(64+column())


4
Bu, programlama geçmişinden gelmeyen ve "Z" (yani "AA") dışındaki sütunlarda çalışmayan insanlar için oldukça zordur, ancak yine de hoşuma gidiyor çünkü en kısa ve en hızlı hesaplama (örneğin, 1000 Bilgisayarınız terlemeden aynı anda gidiyor).
Dave

21

Burada tekerleği yeniden icat etmeye gerek yok, bunun yerine GAS serisini kullanın:

 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"



3

@ SauloAlessandre'ın cevabına ek olarak, bu A-ZZ'den itibaren sütunlarda işe yarayacaktır.

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

@Wronex ve @Ondra Žižka'nın cevaplarını beğendim. Ancak @ SauloAlessandre'ın yanıtının sadeliğini gerçekten seviyorum.

Bu yüzden, @ SauloAlessandre'ın yanıtının daha geniş e-tablolar için çalışmasına izin verecek bariz kodu ekledim.

@ Dave'in yorumunda bahsettiği gibi, bir programlama geçmişine sahip olmanın faydası var, özellikle de alfabenin n'inci harfini standart bir kalıp olarak elde etmek için bir sayıya 'A'nın onaltılık değerini eklediğimiz bir C' de.

@Sangbok Lee tarafından belirtilen hatayı yakalamak için yanıt güncellendi. Teşekkür ederim!


1
Sütunda kullanıldığında @yerine verir . ZZ
Sangbok Lee

1
@Sangbok doğru! Bu güncellenmiş ve Z, AA, AZ, BB sütunları için test edilmiştir. ZZ aracılığıyla işe yarayacağına inanıyorum.
Bahçıvan

2

PHP'de bir çözüm arıyordum. Belki bu birine yardımcı olur.

<?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'));

Çıktı:

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

Ayrıca Python 3.6'da test edilmiş bir Python sürümü arıyordum.

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

Her neyse, yanılmıyorsam bu base26'dır. Zor: yanında Zolmalı AA. Bu BA verir.
Ondra Žižka

1
Sürümünüz neredeyse doğru, sanırım şöyle olmalı: X=lambda n:~int(n) and X(int(n/26)-1)+chr(65+n%26)or''
hum3

Vay canına, bu harika bir lambda fonksiyonuydu, hum3. Teşekkürler!
ViggoTW

Teşekkürler ama Ondra'nın çözümünde hata ayıklamaya çalışıyordum.
hum3

1

Cevabıma yapılan bir yorum, bunun için bir komut dosyası işlevi istediğinizi söylüyor. Pekala, işte başlıyoruz:

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

Sanırım bu, JS'nin kaldırabileceği herhangi bir sayıyı kaldırabilir.

Açıklama:

Bu base26 olmadığından, her ek sembol için ("rakam") temel zaman sırasını çıkarmamız gerekir. Bu yüzden önce ortaya çıkan sayının sırasını sayıyoruz ve aynı zamanda çıkarılacak sayıyı sayıyoruz. Ve sonra bunu 26 tabanına çevirip çıkarıyoruz ve sonra A-Zyerine sembolleri değiştiriyoruz 0-P.

Her neyse, bu soru bir kod golfüne dönüşüyor :)


0

Bu sizi AZ sütununa kadar kapsayacaktır:

=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

A'dan Z'ye Google E-Tablo işlevlerinin basit yolu.

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

Bu, Google Sheet işlevlerinin karmaşık bir yoludur, ancak aynı zamanda AA'dan da fazlasıdır.

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

0

Bir sütun dizinini tekrar tekrar harf kombinasyonlarına dönüştürmek için bir işlev:

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

Java Apache İÇN

String columnLetter = CellReference.convertNumToColString(columnNumber);

-1

İşte Scala ile yazılmış genel bir versiyon. 0'dan başlayan bir sütun dizini içindir (1'den başlayan bir dizini değiştirmek basittir):

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

-1

PowerShell'de:

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

İşte sıfır endeksli bir sürüm (Python'da):

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

Bu o değil. Soru base26 değil. Ben de başlangıçta buna ben de kandırıldım :)
Ondra Žižka
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.