查找和替换范围内单元格的多个字符串的最有效方法是什么?

What is the most efficient way of finding and replacing multiple strings of a cell in a range?

**背景**

现在我有一些代码可以完成这项工作,但我认为这不是“正确的”也不是有效的方法,因为总共将设置大约 40 个“开关”:

 function printCombo()  {
//general set up
  const ss=SpreadsheetApp.getActive();
  const psh=ss.getSheetByName('Print Sheet');
  const scanrange= psh.getRange("Range to be scanned");

//set constants and text they are being replaced with
  const 1A = scanrange.createTextFinder('1A');
  1A.replaceAllWith('1 A');
  const 2B = scanrange.createTextFinder('2B');
  2B..replaceAllWith('2   B');
  const 3C = scanrange.createTextFinder('3C');
  3C.replaceAllWith('');
  const 4D = scanrange.createTextFinder('4D');
  4D.replaceAllWith('4 ]D[ 4');
  const xy = scanrange.createTextFinder('xy');
  4D.replaceAllWith('xy's replacement');
}

此外,如果有任何关于此类主题的初学者指南,请告诉我,因为在脚本编码逻辑和操作顺序方面,我仍然是初学者

谢谢!!

Bonus Question: Is there a way to make it so that if a cell is "Bold"/ some other form of styling, it places a ][ around whatever character of that cell is bolded? for example "3B" would become "3 ]B[" instead of "3 B" <= this would be the end game of this replacement process, and make me have to list less switches, but if that's too complicated then no worries.

我相信你的目标如下。

  • 您想减少脚本的处理成本。
  • 在您的情况下,您想用大约 40 种模式替换文本。

修改点:

  • 我认为const 1A =const 2B =等变量不能用。请注意这一点。
  • 关于4D.replaceAllWith('xy's replacement');,在这种情况下,xy's replacement不包括在内。请注意这一点。
  • 关于2B..replaceAllWith('2 B');..不正确。
  • 为了减少你脚本的处理成本,在这个回答中,我想建议使用Sheets API。使用 Sheets API 时,一次 API 调用即可完成约 40 种模式的文本替换。这样一来,我认为可以降低工艺成本。

当以上几点反映到你的脚本中,就会变成下面这样。

修改后的脚本:

在您使用此脚本之前,please enable Sheets API at Advanced Google services

function printCombo() {
  //general set up
  const ss = SpreadsheetApp.getActive();
  const psh=ss.getSheetByName('Print Sheet');
  const scanrange= psh.getRange("Range to be scanned");

  // I modified below script.
  // Please set the replace patterns for this object. This object uses your patterns.
  const replacePatterns = [
    { search: '1A', replace: '1 A' },
    { search: '2B', replace: '2   B' },
    { search: '3C', replace: '' },
    { search: '4D', replace: '4 ]D[ 4' },
    { search: 'xy', replace: "xy's replacement" }
  ];
  const sheetId = psh.getSheetId();
  const startRowIndex = scanrange.getRow() - 1;
  const endRowIndex = startRowIndex + scanrange.getNumRows();
  const startColumnIndex = scanrange.getColumn() - 1;
  const endColumnIndex = startColumnIndex + scanrange.getNumColumns();
  const requests = replacePatterns.map(({ search, replace }) => ({ findReplace: { range: { sheetId: sheetId, startRowIndex: startRowIndex, endRowIndex: endRowIndex, startColumnIndex: startColumnIndex, endColumnIndex: endColumnIndex }, find: search, replacement: replace } }));
  Sheets.Spreadsheets.batchUpdate({ requests: requests }, ss.getId());
}
  • 当上述脚本为 运行 时,scanrange 的单元格值将使用 replacePatterns 的替换模式替换。

注:

  • 关于你的Bonus Question,在这种情况下,我认为可能需要使用上述修改的其他过程。所以在这种情况下,我想向 post 推荐它作为新问题。

参考文献:

已添加:

根据您的以下回复,

this is an awesome solve, however with this being a script that I would need to be able for people to quickly understand and use, is there any way to do this sort of setup without activating the advanced sheets API situation?

下面的示例脚本怎么样?

function printCombo() {
  //general set up
  const ss = SpreadsheetApp.getActive();
  const psh=ss.getSheetByName('Print Sheet');
  const scanrange= psh.getRange("Range to be scanned");

  // I modified below script.
  // Please set the replace patterns for this object. This object uses your patterns.
  const replacePatterns = [
    { search: '1A', replace: '1 A' },
    { search: '2B', replace: '2   B' },
    { search: '3C', replace: '' },
    { search: '4D', replace: '4 ]D[ 4' },
    { search: 'xy', replace: "xy's replacement" }
  ];
  replacePatterns.forEach(({ search, replace }) => scanrange.createTextFinder(search).replaceAllWith(replace));
}