Мне нужно преобразовать индекс столбца Google Spreadsheet в соответствующее буквенное значение, например, для электронной таблицы:
Мне нужно это сделать (такой функции явно не существует, это пример):
getColumnLetterByIndex(4); // this should return "D"
getColumnLetterByIndex(1); // this should return "A"
getColumnLetterByIndex(6); // this should return "F"
Я не помню точно, начинается ли индекс с 0
или с 1
, в любом случае концепция должна быть ясной.
Я не нашел ничего об этом в документации по газу .. я слепой? Любая идея?
Спасибо
Ответы:
Я написал это некоторое время назад для различных целей (верну двухбуквенные имена столбцов для номеров столбцов> 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; }
источник
var column = letterToColumn(AA);
columnToLetter(column + 1);
. Может быть кому-то полезно.column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
на,column += (letter.toUpperCase().charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
чтобы заставить его работать, если онletter
содержит строчные буквы, иначеa
он будет выводить33
вместо1
String.fromCharCode
что не работает в Apps ScriptЭто хорошо работает
=REGEXEXTRACT(ADDRESS(ROW(); COLUMN()); "[A-Z]+")
даже для столбцов за Z.
Просто замените его
COLUMN()
номером столбца. ЗначениеROW()
не имеет значения.источник
=SUBSTITUTE(ADDRESS(1,COLUMN(),4), "1", "")
Это берет вашу ячейку, получает ее адрес, например, C1, и удаляет "1".
Как это работает
COLUMN()
дает номер столбца ячейки.ADDRESS(1, ..., <format>)
дает адрес ячейки в формате, заданном<format>
параметром.4
означает адрес, который вы знаете - напримерC1
.1
.ADDRESS
ДокументыSUBSTITUTE(..., "1", "")
заменяет1
в адресеC1
, так что остается буква столбца.источник
Это работает на диапазонах
A-Z
источник
Здесь не нужно изобретать велосипед, используйте вместо этого гамму GAS:
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"
источник
В 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')
источник
Добавив к ответу @SauloAlessandre, это будет работать для столбцов от A до ZZ.
=if(column() >26,char(64+(column()-1)/26),) & char(65 + mod(column()-1,26))
Мне нравятся ответы @wronex и @Ondra ižka. Однако мне очень нравится простота ответа @SauloAlessandre.
Итак, я просто добавил очевидный код, чтобы позволить ответу @SauloAlessandre работать с более широкими таблицами.
Как отметил @Dave в своем комментарии, это действительно помогает иметь опыт программирования, особенно в C, где мы добавили шестнадцатеричное значение 'A' к числу, чтобы получить n-ю букву алфавита в качестве стандартного шаблона.
Ответ обновлен, чтобы уловить ошибку, указанную @Sangbok Lee. Спасибо!
источник
@
вместо того,Z
когда используется вZ
столбце.Я также искал версию Python, вот моя, которая была протестирована на 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
источник
X=lambda n:~n and X(n/26-1)+chr(65+n%26)or''
Z
должно бытьAA
. Это дает БА.X=lambda n:~int(n) and X(int(n/26)-1)+chr(65+n%26)or''
Искал решение на PHP. Может это кому-то поможет.
<?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'));
Выход:
NULL string(1) "Z" string(2) "AA" string(2) "AD" int(1) int(1) int(2) int(25) int(26) int(27) int(28)
источник
В комментарии к моему ответу говорится, что вам нужна функция сценария для этого. Хорошо, поехали:
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(''); }
Я думаю, это может обработать любое количество, которое может обработать JS.
Пояснение:
Поскольку это не base26, нам нужно вычесть порядок базового времени для каждого дополнительного символа («цифры»). Итак, сначала мы подсчитываем порядок полученного числа и в то же время подсчитываем число для вычитания. Затем мы преобразуем его в основание 26 и вычитаем из него, а затем сдвигаем символы на
A-Z
вместо0-P
.Так или иначе, этот вопрос превращается в кодовый гольф :)
источник
POI Java Apache
String columnLetter = CellReference.convertNumToColString(columnNumber);
источник
Это охватит вас до столбца 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")
источник
Вот общая версия, написанная на Scala. Это для индекса столбца, начинающегося с 0 (его просто изменить для начала индекса с 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) }
источник
Простой способ использования функций Google Sheet, от А до Я.
=column(B2) : value is 2 =address(1, column(B2)) : value is $B$1 =mid(address(1, column(B2)),2,1) : value is B
Это сложный способ использования функций Google Sheet, но это также больше, чем AA.
=mid(address(1, column(AB3)),2,len(address(1, column(AB3)))-3) : value is AB
источник
Функция для рекурсивного преобразования индекса столбца в комбинации букв:
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; }
Показать фрагмент кода
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>
источник
В python есть библиотека gspread
import gspread column_letter = gspread.utils.rowcol_to_a1(1, <put your col number here>)[:-1]
Если вы не можете использовать python, я предлагаю посмотреть исходный код rowcol_to_a1 () в https://github.com/burnash/gspread/blob/master/gspread/utils.py
источник
В 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)))" }
источник
Вот версия с нулевым индексом (на Python):
letters = [] while column >= 0: letters.append(string.ascii_uppercase[column % 26]) column = column // 26 - 1 return ''.join(reversed(letters))
источник