首页 > 解决方案 > AppScript 在匹配时删除部分文本

问题描述

我正在寻求有关 Google Docs and Scripts 的帮助。我有一个工作流列表,显示分配给任务的员工姓名。还有另一个字段表示员工的休息日。我想要一个可以运行的脚本,该脚本将删除被确定为当天关闭的个人的姓名。可能有多个人关闭,因此需要包含一系列单元格以供参考。结果看起来像这样。

[要求的结果1

我遇到的问题是我什至无法成功找到任何代码作为起点。我到处都看过一些片段,但没有什么是完整的,我什至无法确定一个起点。我相当技术,但不熟悉脚本编写。我一直找不到像这样的像样的文章,所以如果可能的话,我请求帮助。谢谢!

这是我目前在第 27 行获得非法参数时尝试的代码。我会将它链接到一个按钮。负责每日更新工作表的个人将进行所有每日更改,然后单击按钮清除任何删除线并根据新名称输入(如果有)启动。

样品表链接在这里。

https://docs.google.com/spreadsheets/d/1chSTd7Zy1qqu32qu4spSJJanwTI1SnH6rJtoMxb7iEc/edit?usp=sharing

function myFunction() 
{
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange('B:B').activate();
  spreadsheet.getActiveRangeList().setFontLine(null);



  const sheetName = "Sheet1";  // Please set the sheet name.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const range = sheet.getRange('B2:B')

  const textsForStrikethrough = sheet.getRange("A15:A20").getValues().flat(); // Added

    const modify = range.getValues().reduce((ar, e, r) => {
    e.forEach((f, c) => {
      textsForStrikethrough.forEach(g => {
        const idx = f.indexOf(g);
        if (idx > -1) ar.push({start: idx, end: idx + g.length, row: r, col: c});
      });
    });
    return ar;
  }, []);
  const textStyle = SpreadsheetApp.newTextStyle().setStrikethrough(true).build();
  const richTextValues = range.getRichTextValues();
  modify.forEach(({start, end, row, col}) => richTextValues[row][col] = richTextValues[row][col].copy().setTextStyle(start, end, textStyle).build());
  range.setRichTextValues(richTextValues);
}

标签: google-apps-scriptgoogle-sheets

解决方案


我相信你的目标如下。

  • 您希望使用 Google Apps 脚本将删除线反映到单元格中的部分文本,如下所示。(示例图片来自您的问题。)

在这种情况下,我想建议使用 RichTextValueBuilder。示例脚本如下。

示例脚本:

function myFunction() {
  const textsForStrikethrough = ["John"];  // Please set the texts you want to reflect the strikethrough.
  const sheetName = "Sheet1";  // Please set the sheet name.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const range = sheet.getDataRange();
  const modify = range.getValues().reduce((ar, e, r) => {
    e.forEach((f, c) => {
      textsForStrikethrough.forEach(g => {
        const idx = f.indexOf(g);
        if (idx > -1) ar.push({start: idx, end: idx + g.length, row: r, col: c});
      });
    });
    return ar;
  }, []);
  const textStyle = SpreadsheetApp.newTextStyle().setStrikethrough(true).build();
  const richTextValues = range.getRichTextValues();
  modify.forEach(({start, end, row, col}) => richTextValues[row][col] = richTextValues[row][col].copy().setTextStyle(start, end, textStyle).build());
  range.setRichTextValues(richTextValues);
}

结果:

运行上述脚本时,将获得以下结果。

输入情况:

这是脚本运行前的示例输入情况。

在此处输入图像描述

输出情况一:

在这种情况下,const textsForStrikethrough = ["John"];用于输入情况。

在此处输入图像描述

输出情况2:

在这种情况下,const textsForStrikethrough = ["John", "Amy"];用于输入情况。

在此处输入图像描述

笔记:

  • 在此示例脚本中,从工作表中检索所有值并搜索文本并反映删除线。所以当你想在特定范围内使用这个脚本时,请const range = sheet.getDataRange();根据你的情况进行修改。
    • 例如,从您的示例图像中,当您要使用此脚本到“B”列时,请将其修改为const range = sheet.getRange("B1:B" + sheet.getLastRow());.

参考:

添加:

关于您的以下第二个问题

太棒了!我只有其他请求,我们将如何将其修改为引用一系列其他单元格以查找名称的位置?名称列表每天都在变化,因此希望所有输入都能够通过简单更改工作表上的名称来更新,而不是修改代码。因此,可以在单元格 A10:A15 中输入名称。提取该名称列表并更新“textsForStrikethrough”逻辑。

在这种情况下,我认为首先,如何检索单元格“A10:A15”的值,并将它们用作textsForStrikethrough

示例脚本 2:

function myFunction2() {
  // const textsForStrikethrough = ["John"];  // Please set the texts you want to reflect the strikethrough.
  const sheetName = "Sheet1";  // Please set the sheet name.

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const range = sheet.getDataRange();
  
  const textsForStrikethrough = sheet.getRange("A10:A15").getValues().flat(); // Added
  
  const modify = range.getValues().reduce((ar, e, r) => {
    e.forEach((f, c) => {
      textsForStrikethrough.forEach(g => {
        const idx = f.indexOf(g);
        if (idx > -1) ar.push({start: idx, end: idx + g.length, row: r, col: c});
      });
    });
    return ar;
  }, []);
  const textStyle = SpreadsheetApp.newTextStyle().setStrikethrough(true).build();
  const richTextValues = range.getRichTextValues();
  modify.forEach(({start, end, row, col}) => richTextValues[row][col] = richTextValues[row][col].copy().setTextStyle(start, end, textStyle).build());
  range.setRichTextValues(richTextValues);
}
  • 在此脚本中,工作表中单元格“A10:A15”的值sheetName用作textsForStrikethrough.

笔记:

  • 很遗憾,我无法了解您的实际情况。因此,当上述脚本无法用于您的实际情况时,您能否提供您的示例电子表格来复制问题?借此,我想确认一下。

推荐阅读