【问题标题】:Google Script 'replace' function with range谷歌脚本“替换”功能与范围
【发布时间】:2013-04-03 00:12:18
【问题描述】:

我正在尝试在 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 行,我不想再添加 50 个额外的实例如果不使用它们的功能。我希望它尽可能自动化。 :-)

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

function copyRange(inputRange) {
return inputRange;
}

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

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

是否可以在不使代码过于臃肿的情况下实现这一目标? (我是一个新手脚本编写者,喜欢简短的脚本,就像我上面的示例一样。)

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

谢谢!

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

【问题讨论】:

  • 那么,如果不是字符串,那么 inputRange 变量中的 是什么?请添加类型(由typeof inputRange 报告)和该变量的内容。这根本不是 Google 脚本问题,只是简单的 JavaScript,但如果不知道该变量中的内容,就很难提供帮助。 :-)
  • 嗨!感谢您及时的回复。我已经编辑了这篇文章,希望能更清楚地说明情况并回答你的问题。谢谢!
  • 哇,现在细节太多了。 :-) 真的,你把这弄得太复杂了。让我们重新开始。你有一个功能。它接受输入并转换为输出。究竟是什么输入?它应该从该输入产生什么输出?为两者提供具体的例子,尽可能多的例子来展示你可能遇到的不同情况,但仅此而已。忘记电子表格 API 和其他一切,这一切都只是分散注意力。达到这个特定功能的最低限度的具体要求,然后你就有了容易解决的问题。
  • 当然,我在这里可能过于简单化了!查看 Crayon 的答案以获取一些有价值的信息。我真正的意思是把这两个问题分开:1)你如何以你需要的方式与电子表格 API 交互,以及 2)你如何编写一个 JavaScript 函数来完成你需要的转换。如果你能把这两个问题分开,可能更容易分析问题。
  • 哈哈感谢您与我交谈并尝试解决我的问题。好吧,在 Google 电子表格文档中,我可以打开一个脚本编辑器。在编辑器中,我可以声明一个函数,它看起来与我上面的第一个代码示例完全一样。然后在电子表格中调用我的函数,我只需键入(在单元格中)=rom2num(输入)。 (输入可以是一些文本或对另一个单元格或另一个单元格范围的引用。

标签: javascript arrays multidimensional-array google-apps-script


【解决方案1】:

我使用了更简洁的方法:

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

【讨论】:

    【解决方案2】:

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

    例如

    A  B
    i  =rom2num(A1)
    i
    i
    i
    

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

    编辑:

    根据您的评论和问题中的其他信息,我想我知道您要做什么。基本上,您想利用将值溢出到单元格来有效地作用于多个单元格。所以是的,这可以通过返回一个双数组来实现。您的新示例显示converting roman numerals to actual numbers..好吧,它比简单地执行.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 列的每个单元格中,并与A 列单元格。但请记住,它实际上并没有更改单个 An > Bn 单元格..它实际上是在获取您指定的范围并将结果溢出到多个单元格中。它可以有效地做你想做的事,但并不完全相同。

    【讨论】:

    • 嗨!感谢您将我指向该页面。它包含一些关于返回数组的信息,这可能是我必须做的。实际上我并没有尝试更改原始数据,我只想检索数据,然后在另一个单元格中输出该数据的变体。不想使用“拖动”方法的原因是原始范围内的内容可能会更改并且包含更多或更少的行。
    • 嘿@user2268171 感谢您的评论并更新您的问题。我想我理解你现在想要做什么,并更新了我的答案以反映它。希望这会有所帮助!
    • @user2268171 我再次更新了我的答案。我很想看到最终的解决方案,所以我继续添加了罗马数字转换功能。既然我这样做了,我想也可以为您省去麻烦。
    • 哇!非常感谢!我试过你的代码,它完全符合我的要求。我需要稍后研究它以找出到底发生了什么。但有一件事,如果数据范围分布在多列上,结果仍然只是一列,但它用逗号分隔内容。我尝试在电子表格中使用 SPLIT() 函数,但由于某种原因它不接受逗号。 :-S 这不是一个真正的问题,因为我的数据只涉及一列,但为了将来的目的,可能需要使其与多列兼容。如果我找到解决方案,我会告诉你的。再次感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多