繁体   English   中英

带有范围的 Google Script“替换”功能

[英]Google Script 'replace' function with range

我正在尝试在 Google 电子表格中编写“罗马数字到十进制数字”函数的脚本。 到目前为止,我已经设法使用以下代码使其工作:

function rom2num(inputRange) {
inputRange = inputRange.replace(/\bi\b/gi,1); //convert 'I' to '1'
  return inputRange;
}

当输入只有一个单元格时,这非常有效。 但是,每当我尝试输入范围 (A1:B2) 时,都会收到错误消息:“无法在对象中找到函数替换”。

我想要实现的一些例子:

Column A      | Column with function
i, ii, iii    | 1, 2, 3
Godfather II  | Godfather 2
iv, v, vi     | 4, 5, 6
Star Wars V   | Star Wars 5

我可以选择在下面的单元格中重复该函数,正如 Crayon 建议的那样,但是,需要重新格式化的范围可能是 50 行,也可能是 100 行,如果它们不能被使用。 我希望它尽可能自动。 :-)

我知道可以通过使用以下代码来检索一系列单元格的信息,并在另一个单元格范围内返回该信息:

function copyRange(inputRange) {
return inputRange;
}

所以输入一个范围并输出相同的范围不是问题。 问题是试图合并替换功能。 我设法使用“toString()”函数更改了整个范围内的信息。 然后我能够使用 'split(",")' 将输出分成几列,但我不希望它跨列分布,只是行。

因此,如果我能以某种方式将范围/数组转换为字符串,然后再转换回范围/数组...

是否有可能在不使代码膨胀太多的情况下实现这一目标? (我是一个新手脚本编写者,更喜欢我的脚本简短,就像我上面的例子一样。)

如果我不清楚,我很抱歉。 我习惯于在这样的论坛中查找答案,但不会自己提问!

谢谢!

编辑:终于意识到事情变得有点太复杂了,所以我只是按照 Crayons 的建议并使用了“拖动”方法。 为我省去了很多麻烦。 谢谢您的帮助!!

根据https://developers.google.com/apps-script/execution_custom_functions,您的函数只能更改调用该函数的单元格中的数据,因此无论如何您都不应该尝试更改多个单元格。 您应该具有对该单元执行替换的功能,然后将该功能应用于多个单元。

例如

A  B
i  =rom2num(A1)
i
i
i

这将使B1等于“ 1”。 现在,将鼠标悬停在B1上,右下角是点,向下拖动到B4,您将看到该函数应用于B2-4行。

编辑:

鉴于您的评论和问题的其他信息,我想我知道您要做什么。 基本上,您想利用溢出值到单元格来有效地作用于多个单元格。 是的,这可以通过返回一个double数组来实现。 您的新示例显示了将罗马数字转换为实际数字 ..嗯,这比简单地执行.replace更为复杂,但是一旦弄清楚了,您就应该能够弄清楚如何将这些东西用于您要尝试的工作中如何获得价值以继续努力! 所以这是怎么做的:

function rom2num(inputRange) {
  var cells = [];
  for (var i=0;i<inputRange.length;i++) {
    cells[i] = [String(inputRange[i]).replace(/i/gi,1)];
  }
  return cells;
}

此示例在此迭代范围内的每一行,并简单地将“ i”替换为“ 1”。 然后,它返回值的双精度数组,例如,如果您有

A              B
i, ii, iii     =rom2num(A1:A4)
Godfather II
iv, v, vi
Star Wars V

该函数将返回并溢出单元格,如下所示:

A               B
i, ii, iii      1, 11, 111
Godfather II    Godfather 11
iv, v, vi       1v, v, v1
Star Wars V     Star Wars V

就像我说的那样,您实际上要做的不仅仅是.replace (转到我给您的链接),而是将罗马数字实际转换为数字,但是就您的实际问题而言,这应该可以做到。

编辑2:

实际上,我继续将罗马数字转换功能合并到其中,因为我想看到它。 因此,我认为最好与您分享最终的脚本:

function rom2num(inputRange) {
  var cells = [];
  for (var i=0;i<inputRange.length;i++) {
    cells[i] = [
      String(inputRange[i]).replace(/\b([ivxcldm]+)\b/gi,function(p,p1) {
        return deromanize(p1); 
      })
    ];
  }
  return cells;
}

function deromanize (str) {
    var str = str.toUpperCase(),
        validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/,
        token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
        key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
        num = 0, m;
    if (!(str && validator.test(str)))
        return false;
    while (m = token.exec(str))
        num += key[m[0]];
    return num;
}

与之前相同...列A具有要操作的内容,将=rom2num(A1:A4)放在B列的第一个单元格中。这会将转换后的罗马数字放入B列的每个单元格中,并排成=rom2num(A1:A4)与列A单元格。 但是请记住,实际上并没有更改单个An> Bn单元。它实际上是在获取您指定的范围并将结果溢出到多个单元中。 它有效地完成了您想要的操作,但并非完全相同。

我使用了更简洁的方法:

const ss = SpreadsheetApp.getActiveSpreadsheet()
const sh = ss.getSheetByName('Sheet1')
sh
  .getRange('A:B')
  .createTextFinder('i')
  .replaceAllWith('1')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM