0

再会。请告诉我如何将此脚本转换为使用 Google 表格 api v4 并降低请求的成本。正确理解我需要挖掘到一边: https ://developers.google.com/sheets/api/samples/conditional-formatting?hl=en#add_a_conditional_formatting_rule_to_a_set_of_ranges ?

下面的示例代码

while (folders.hasNext()) {
      var folder = folders.next().getId();
      var sheet1 = SpreadsheetApp.openById(folder);
      var sheet = sheet1.getActiveSheet();
      var r1 = sheet.getRange('Q4:Q');var r2 = sheet.getRange('S4:S'); 
      var rule = SpreadsheetApp.newConditionalFormatRule()
        .setGradientMaxpoint("#06ff00")
        .setGradientMidpointWithValue("#ffef00", SpreadsheetApp.InterpolationType.PERCENTILE, "50")
        .setGradientMinpoint("#ff0000")
        .setRanges([r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,
        r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,
        r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,
        r31,r32,r33,r34,r35,r36,r37,r38,r39,r40,
        r41,r42,r43,r44,r45,r46,r47,r48,r49,r50,
        r51,r52,r53,r54,r55,r56,r57,r58,r59,r60,
        r61,r62,r63,r64,r65])
        .build()
      var rules = sheet.getConditionalFormatRules();
      rules.push(rule);
      sheet.setConditionalFormatRules(rules);
      }

我将不胜感激任何帮助

4

2 回答 2

1

回答

我了解您希望使用Sheet API v4而不是电子表格服务降低请求成本。我不知道使用这种方式会降低多少成本,但我会向你解释如何做到这一点。

如何在 Sheets API v4中应用条件格式规则

  • 使用方法batchUpdate。它需要一个request body你可以定义的地方Conditional Format RulespreadsheetIdrequest body您可以使用该部分轻松构建该部分Try this API,它可以帮助您放置和定义您需要的所有参数。

  • request body使用AddConditionalFormatRuleRequest对象定义。它有两个字段,一个rule描述条件格式,一个index定义rule应该插入的位置。

  • 使用ConditionalFormatRule对象定义rule字段。它需要两个字段,the和 the或 the (您只能选择一个)。rangesgradientRuleboolearnRule

    • range使用GridRange对象定义。

    • 用它的三个字段定义梯度minpoint规则:midpointmaxpoint。这些中的每一个都由一个InterpolationPoint对象定义。

最后,您的代码将类似于以下内容:

function main(){
  // start here
  var folders = // your definition
  const gridRangeList = createGridRange() // create the GridRange object
  while (folders.hasNext()) {
      var spreadsheetId = folders.next().getId();     
      applyConditionalFormating(spreadsheetId, gridRangeList) // apply the conditional format
  }
}

function createGridRange(){
  const ranges = ["Q4:Q", "S4:S"]
  const temp = SpreadsheetApp.create("temp")
  const rangeList = temp.getSheets()[0].getRangeList(ranges).getRanges()
  const gridRangeList = rangeList.map(r => ({startRowIndex: r.getRow() - 1, startColumnIndex: r.getColumn() - 1, endColumnIndex: r.getColumn() + r.getNumColumns() - 1}))
  DriveApp.getFileById(temp.getId()).setTrashed(true) // move the file to the trash
  return gridRangeList
}

function applyConditionalFormating(spreadsheetId, gridRangeList){
  const request = {
    "requests": [
      {
        "addConditionalFormatRule": {
          "rule": {
            "gradientRule": {
              "maxpoint": {
                "type": "MAX",
                "color": {red:6/255,green:255/255,blue:0}
              },
              "midpoint": {
                "type": "PERCENTILE",
                "value": "50",
                "color": {red:255/255,green:239/255,blue:0}
              },
              "minpoint": {
                "type": "MIN",
                "color":{red:255/255,green:0,blue:0}
              }
            },
            "ranges": [gridRangeList]
        },
        "index": 0
        }
      }
    ]
  }
  Sheets.Spreadsheets.batchUpdate(request,spreadsheetId)
}

参考

于 2021-01-15T15:36:22.827 回答
0

我相信你的目标如下。

  • 您想降低脚本的处理成本。

修改点:

  • 当我看到您的脚本时,似乎通过一次调用将具有多个范围的条件格式规则添加到 Google 电子表格中的工作表中。在这种情况下,即使将此脚本转换为 Sheets API 而不是电子表格服务,处理成本也可能不会发生很大变化。所以请测试以下修改后的脚本。
  • 作为修改点,我建议如下。
    • 在您的脚本中,范围是在循环中声明的。将其转换为 Sheets API 时,可以在循环之外创建范围。
    • 使用 Drive API 检索文件列表时,处理成本会有所降低。

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

修改后的脚本:

在使用此脚本之前,请在 Advanced Google services 中启用 Sheets API 和 Drive API。并且,请设置 和 的topFolderId变量rangesranges来自您的脚本。当您想要更多范围时,请将它们添加到数组中。

function myFunction() {
  var topFolderId = "###";  // Please set the top folder ID of the folder including the Spreadsheet.

  // Retrieve file list using Drive API v3.
  const headers = {authorization: `Bearer ${ScriptApp.getOAuthToken()}`};
  const q = `'${topFolderId}' in parents and mimeType='${MimeType.GOOGLE_SHEETS}' and trashed=false`;
  const url = `https://www.googleapis.com/drive/v3/files?pageSize=1000&q=${q}&fields=${encodeURIComponent("nextPageToken,files(id)")}`;
  let pageToken = "";
  let files = [];
  do {
    const res = UrlFetchApp.fetch(url + "&pageToken=" + pageToken, {headers: headers, muteHttpExceptions: true});
    if (res.getResponseCode() != 200) throw new Error(res.getContentText());
    const obj = JSON.parse(res.getContentText());
    files = files.concat(obj.files);
    pageToken = obj.nextPageToken || "";
  } while(pageToken);

  // Create range list.
  const ranges = ["Q4:Q", "S4:S"]; // Please set the ranges as A1Notation. These ranges are used for addConditionalFormatRule.
  const temp = SpreadsheetApp.create("temp");
  const rangeList = temp.getSheets()[0].getRangeList(ranges).getRanges();
  const gridRangeList = rangeList.map(r => ({startRowIndex: r.getRow() - 1, startColumnIndex: r.getColumn() - 1, endColumnIndex: r.getColumn() + r.getNumColumns() - 1}));
  DriveApp.getFileById(temp.getId()).setTrashed(true);

  // Request Sheets API for a sheet in each Spreadsheet.
  files.forEach(({id}) => {
    const sheet1 = SpreadsheetApp.openById(id);
    const gr = gridRangeList.map(({startRowIndex, startColumnIndex, endColumnIndex}) => ({sheetId: sheet1.getSheetId(), startRowIndex, startColumnIndex, endColumnIndex}))
    const requests = {addConditionalFormatRule:{rule:{gradientRule:{maxpoint:{color:{red:6/255,green:255/255,blue:0},type:"MAX"},midpoint:{color:{red:255/255,green:239/255,blue:0},type:"PERCENTILE",value:"50"},minpoint:{color:{red:255/255,green:0,blue:0},type:"MIN"}},ranges:[gr]},index:0}};
    Sheets.Spreadsheets.batchUpdate({requests: requests}, id);
  });
}

参考:

于 2021-01-15T12:58:42.433 回答