将列索引转换为相应的列字母

130

我需要将Google表格的列索引转换为相应的字母值,例如,给定以下电子表格:

enter image description here

我需要执行此操作(显然不存在此函数,这只是一个示例):

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

现在,我不确定索引是从0开始还是从1开始,不过概念应该是清楚的。

我在gas文档中没有找到关于此事的任何信息.. 我瞎了吗?有什么想法吗?

谢谢


41
这为什么没有内置? - Cyril Duchon-Doris
2
请实现类似于 A、B、C、AA、AB、AAA 这样的编号方案,类似于将数字转换为 Excel 中的列名称。 - Ondra Žižka
2
X = (n) => (a=Math.floor(n/26)) >= 0 ? X(a-1) + String.fromCharCode(65+(n%26)) : ''; - Pascal DeMilly
@PascalDeMilly,你能解释一下如何使用吗?X接收字符串吗?列索引放在哪里? - Robert M.
24个回答

228

我之前为了不同目的编写了以下代码(将返回双字母列名,用于列号 > 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;
}

1
最大值是否小于 ZZ? - Old Geezer
1
刚刚使用了这个来增加列号:var column = letterToColumn(AA); columnToLetter(column + 1);。可能对某些人有帮助。 - joshfindit
2
我建议将 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 - tukusejssirs
我认为 String.fromCharCode 在 Apps Script 上不起作用。 - c-an
你确定没有什么可以做的吗?几个函数有一个“B14”语法和一个“(14, 2)”语法。我很惊讶没有字母到数字的自动转换...请参见@Tomi Heiskanen的答案。 - Sandburg

79

这个很好用。

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

即使是超出Z列的列也适用。

函数演示

只需将COLUMN()替换为您的列号。 ROW()的值无关紧要。


8
你正在使用公式,而不是GAS。 - BeNdErR
11
这个方法非常有效。尽管它没有使用GAS(问题所标记的),但由于无需编写内置函数,并且在我的经验中,它们运行得更快,因此几乎总是首选。 - kevinmicke

47

不需要在这里重新发明轮子,使用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"


1
这应该是被接受的答案。您还可以通过 replace(/\d+/, '') 去掉数字。 - thdoan
我得到了一个异常:参数(String,number,number,number)与SpreadsheetApp.Spreadsheet.getRange方法签名不匹配。 - Rishabh Bhatnagar
该方法的签名是第一个参数是整数,但您正在传递一个字符串,因此出现了错误。首先将其转换为整数或检查是否将正确的变量作为参数传递。请参考以下链接以获取更多信息:https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column,-numrows,-numcolumns - Tomi Heiskanen
没有 ".match(/([A-Z]+)/)" 也能很好地工作。 这是一个“以防万一”的安全检查,以避免随机错误,还是我在这里漏掉了重要的东西? - Mario
1
@Mario,这是要从注释中删除行号,例如getA1Notation()返回类似于“AZ1”的内容,要获取纯列索引“AZ”,您需要剥离行号。 - Tomi Heiskanen

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

此代码获取单元格的地址,例如C1,并去掉“1”。

图片描述

工作原理

  • COLUMN() 返回单元格列数。
  • ADDRESS(1, ..., <format>) 根据<format>参数提供的格式给出一个单元格地址。4 表示您知道的地址-例如 C1
    • 这里不需要行号,所以我们使用 1
    • 请参阅ADDRESS文档
  • 最后,SUBSTITUTE(..., "1", "")替换地址中的1,以便只剩下列字母。

1
尝试时我得到了这个:http://screencast.com/t/Jmc8L9W5LB。我找出来了,通过将所有逗号替换为分号来解决它。这可能是一个本地化问题。 - David
@David,使用逗号对我有效。也许是由于本地设置的原因。 - Ondra Žižka
3
此问题要求提供适用于脚本的函数,而该解决方案提供了适用于单元格的公式。 - markshep
我想知道在有两位数的行(例如第10行及以下)会发生什么情况。 这个替换是否能够正常工作? - Re'em

30

这适用于范围A-Z

公式为=char(64+column())

JavaScript代码为String.fromCharCode(64+colno)

一个基于@Gardener的谷歌电子表格应用脚本代码如下:

function columnName(index) {
    var cname = String.fromCharCode(65 + ((index - 1) % 26));
    if (index > 26)
        cname = String.fromCharCode(64 + (index - 1) / 26) + cname;
    return cname;
}

4
对于没有编程背景且不会处理超过“Z”列(如“AA”)的人来说,这可能有些棘手。但我仍然喜欢它,因为它是最简短和最快速的计算方法(例如,你可以同时进行成千上万次这样的计算而不会让你的电脑感到吃力)。 - Dave
1
很遗憾,这个答案是一个表格公式,在GAS中无法使用。 - Simon East

13

在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')

1
将列索引转换为相应的列字母 - TheMaster

3

补充@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指出的错误。谢谢!

1
当在“Z”列中使用时,它会给出“@”,而不是“Z”。 - Sangbok Lee
1
@Sangbok是正确的!这已经更新并测试了Z、AA、AZ、BB列。我相信它将在ZZ列中起作用。 - Gardener
很遗憾,这个答案是一个表格公式,在GAS中无法使用。 - Simon East

3

我在寻找一个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)

2
这是一个使用递归在ZZ以外运行的两行代码:
Python
def col_to_letter(n):
    l = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return col_to_letter((n-1)//26) + col_to_letter(n%26) if n > 26 else l[n-1]

JavaScript

function colToLetter(n) {
    l = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return n > 26 ? colToLetter(Math.floor((n-1)/26)) + colToLetter(n%26) : l[n-1]
}

1
感谢您提供的可靠解决方案。在Python版本中,l = string.ascii_uppercase 确保您拥有所有的字母。 - undefined

2

通过Google表格函数简单实现从A到Z的方式。

=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更强大。

原始答案:Original Answer

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接