簡體   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