首页 > 解决方案 > 在一个范围内查找和替换多个单元格字符串的最有效方法是什么?

问题描述

**背景 **

现在我有一些代码可以完成工作,但我不认为这是“正确”或有效的方法,因为总共将设置大约 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');
}

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

谢谢!!

额外的问题:有没有办法使它,如果一个单元格是“粗体”/某种其他形式的样式,它会在该单元格的任何字符周围放置一个 ][ 加粗?例如“3 B ”会变成“3 ]B[”而不是“3 B”<=这将是这个替换过程的最终结果,让我不得不列出更少的开关,但如果这太复杂了,那就不用担心.

标签: google-apps-scriptgoogle-sheetsreplacerangereplaceall

解决方案


我相信你的目标如下。

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

修改点:

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

当以上几点反映到您的脚本时,它变成如下。

修改后的脚本:

在使用此脚本之前,请在 Advanced Google services 中启用 Sheets API

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,在这种情况下,我认为可能需要使用上述修改的其他过程。因此,在这种情况下,我建议将其作为新问题发布。

参考:

添加:

从您的以下回复中,

这是一个很棒的解决方案,但是这是一个我需要能够让人们快速理解和使用的脚本,有没有办法在不激活高级工作表 API 的情况下进行这种设置?

下面的示例脚本怎么样?

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));
}

推荐阅读