Necesito convertir un índice de columna de la hoja de cálculo de Google en su valor de letra correspondiente, por ejemplo, dada una hoja de cálculo:
Necesito hacer esto (esta función obviamente no existe, es un ejemplo):
getColumnLetterByIndex(4); // this should return "D"
getColumnLetterByIndex(1); // this should return "A"
getColumnLetterByIndex(6); // this should return "F"
Ahora, no recuerdo exactamente si el índice comienza desde 0
o desde 1
, de todos modos el concepto debería ser claro.
No encontré nada sobre esto en la documentación del gas. ¿Estoy ciego? ¿Alguna idea?
Gracias
Respuestas:
Los escribí hace un tiempo para varios propósitos (devolveré los nombres de columna de doble letra para los números de columna> 26):
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; }
fuente
var column = letterToColumn(AA);
columnToLetter(column + 1);
. Podría ser útil para alguien.column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
acolumn += (letter.toUpperCase().charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
para que funcione siletter
contiene letras minúsculas, de lo contrario,a
se generaría en33
lugar de1
String.fromCharCode
que no funciona en Apps ScriptEsto funciona bien
=REGEXEXTRACT(ADDRESS(ROW(); COLUMN()); "[A-Z]+")
incluso para columnas más allá de Z.
Simplemente reemplácelo
COLUMN()
con su número de columna. El valor deROW()
no importa.fuente
=SUBSTITUTE(ADDRESS(1,COLUMN(),4), "1", "")
Esto toma su celda, obtiene su dirección como, por ejemplo, C1 y elimina el "1".
Cómo funciona
COLUMN()
da el número de la columna de la celda.ADDRESS(1, ..., <format>)
da una dirección de una celda, en formato especificado por<format>
parámetro.4
significa la dirección que conoce, por ejemploC1
.1
.ADDRESS
documentosSUBSTITUTE(..., "1", "")
reemplaza el1
en la direcciónC1
, por lo que te queda la letra de la columna.fuente
Esto funciona en rangos
A-Z
fuente
No es necesario reinventar la rueda aquí, use la gama GAS en su lugar:
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"
fuente
En 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')
fuente
Agregando a la respuesta de @ SauloAlessandre, esto funcionará para columnas desde A-ZZ.
=if(column() >26,char(64+(column()-1)/26),) & char(65 + mod(column()-1,26))
Me gustan las respuestas de @wronex y @Ondra Žižka. Sin embargo, me gusta mucho la simplicidad de la respuesta de @ SauloAlessandre.
Entonces, acabo de agregar el código obvio para permitir que la respuesta de @ SauloAlessandre funcione para hojas de cálculo más amplias.
Como @Dave mencionó en su comentario, ayuda tener experiencia en programación, particularmente uno en C donde agregamos el valor hexadecimal de 'A' a un número para obtener la enésima letra del alfabeto como patrón estándar.
Respuesta actualizada para detectar el error señalado por @Sangbok Lee. ¡Gracias!
fuente
@
lugar deZ
cuando se usa enZ
columna.También estaba buscando una versión de Python aquí, la mía, que se probó en Python 3.6
def columnToLetter(column): character = chr(ord('A') + column % 26) remainder = column // 26 if column >= 26: return columnToLetter(remainder-1) + character else: return character
fuente
X=lambda n:~n and X(n/26-1)+chr(65+n%26)or''
Z
debería estarAA
. Esto le da a BA.X=lambda n:~int(n) and X(int(n/26)-1)+chr(65+n%26)or''
Estaba buscando una solución en PHP. Quizás esto ayude a alguien.
<?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'));
Salida:
NULL string(1) "Z" string(2) "AA" string(2) "AD" int(1) int(1) int(2) int(25) int(26) int(27) int(28)
fuente
Un comentario sobre mi respuesta dice que querías una función de script para ello. Muy bien, aquí vamos:
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(''); }
Esto puede manejar cualquier número que JS pueda manejar, creo.
Explicación:
Dado que esto no es base26, necesitamos restar el orden de tiempos base para cada símbolo adicional ("dígito"). Entonces, primero contamos el orden del número resultante y, al mismo tiempo, contamos el número a restar. Y luego lo convertimos a base 26 y restamos eso, y luego cambiamos los símbolos a en
A-Z
lugar de0-P
.De todos modos, esta pregunta se está convirtiendo en un código de golf :)
fuente
PDI de Java Apache
String columnLetter = CellReference.convertNumToColString(columnNumber);
fuente
Esto lo cubrirá hasta la columna AZ:
=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")
fuente
Aquí hay una versión general escrita en Scala. Es para un índice de columna que comienza en 0 (es simple de modificar para un índice que comienza en 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) }
fuente
Manera simple a través de las funciones de Google Sheet, de la A a la 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 una forma complicada de pasar por las funciones de Google Sheet, pero también es más que AA.
=mid(address(1, column(AB3)),2,len(address(1, column(AB3)))-3) : value is AB
fuente
Una función para convertir un índice de columna en combinaciones de letras, de forma recursiva:
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; }
Mostrar fragmento de código
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)); 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; } document.getElementById("result1").innerHTML = lettersFromIndex(32); document.getElementById("result2").innerHTML = lettersFromIndex(6800); document.getElementById("result3").innerHTML = lettersFromIndex(9007199254740991);
32 --> <span id="result1"></span><br> 6800 --> <span id="result2"></span><br> 9007199254740991 --> <span id="result3"></span>
fuente
En Python, existe la biblioteca gspread
import gspread column_letter = gspread.utils.rowcol_to_a1(1, <put your col number here>)[:-1]
Si no puede usar Python, le sugiero que busque el código fuente de rowcol_to_a1 () en https://github.com/burnash/gspread/blob/master/gspread/utils.py
fuente
En 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)))" }
fuente
Aquí hay una versión con índice cero (en Python):
letters = [] while column >= 0: letters.append(string.ascii_uppercase[column % 26]) column = column // 26 - 1 return ''.join(reversed(letters))
fuente