【问题标题】:setValue of filtered row cell in google apps script谷歌应用脚​​本中过滤行单元格的 setValue
【发布时间】:2021-08-24 09:36:12
【问题描述】:

我正在寻找一些关于我正在尝试编写的 Google Apps 脚本的指导。

我有一个包含数千个链接的 Google 表格。我需要检查链接是否仍然“活动”,如果没有将它们标记为“关闭”。为了节省对每一行的迭代,我首先过滤行以获取在row[9] 中设置了“活动”的所有链接。然后我使用 fetch 来获取响应代码,并根据该代码将 row[9] 的值更新为“Still Active”或“Closed”

我知道我可以在任何其他情况下使用这个概念:

SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sites").getRange().setValue();

但是,我发现很难将它与我需要的 filteredRows 结合使用。

表格看起来有点像这样:


| date       | name     | link                      | status |
|------------|--------- |---------------------------|--------|
| 2021-08-24 | Google   | https://www.google.com/   | Active |
| 2021-08-20 | Facebook | https://www.facebook.com/ | Active |
| 2021-08-18 | Twitter  | https://www.twitter.com/  | Closed |
   

当前脚本:

function getStatus() {

    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("Sites");
    var rows = sheet.getDataRange().getValues();
    var filteredRows = rows.filter(function (row) {
        var status = row[9];
        if (status === "Active") {
            return row
        }
    });

    filteredRows.forEach(function(row){

        var link = row[3];
        var status = row[9];
        var options = {
            'muteHttpExceptions': true,
            'followRedirects': false,
            'validateHttpsCertificates': false
        };
        var response = UrlFetchApp.fetch(link, options);

        if (status === "Active") {

            if (response.getResponseCode() == 200) {
              
              row.status.setValue("Still Active!");
              
            }
            else {
              row.status.setValue("Closed!");
            }
            
         }

    })
}

【问题讨论】:

  • 你应该尝试使用像 sheetfu 应用脚本这样的库,这样事情会更干净:github.com/socialpoint-labs/sheetfu-apps-script。这样你的用例就很简单了。
  • 你能分享你的工作表吗?
  • @RafaGuillermo 无法共享工作表,但提供了布局示例。希望这会有所帮助

标签: google-apps-script google-sheets


【解决方案1】:

我建议再使用一个数组indexes,它将包含过滤行的位置:

var indexes = [];
var filteredRows = rows.filter(function (row, i) {
        var status = row[9];
        if (status === "Active") {
            indexes.push(i);
            return row;
        }
    });

然后您可以通过这种方式更改主数组中的行:

indexes.forEach((x,i) => rows[x][9] = filteredRows[i].status);

但实际上我不明白为什么需要过滤行?您可以跳过列 [9] 中没有“活动”的行。

或者您尝试对每个已处理的行使用setValues()?如果您有数千行,这是一个非常糟糕的主意。您需要处理 2d 数组(一个整体)并一次设置所有数千行:

sheet.getDataRange().setValues(rows);

所以毕竟你的代码可能看起来像这样:

function getStatus() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Sites");
  var rows = sheet.getDataRange().getValues();

  var options = {
    'muteHttpExceptions': true,
    'followRedirects': false,
    'validateHttpsCertificates': false
  };

  for (let i in rows) {
    if (rows[i][9] != 'Active') continue; // skip the row if not 'Active'

    var response = UrlFetchApp.fetch(rows[i][3], options);

    if (response.getResponseCode() == 200) { 
      rows[i][9] = "Still Active!";
    } else { 
      rows[i][9] = "Closed!";
    }

  }

  sheet.getDataRange().getValues(rows); // set all values back to the sheet
}

不过,如果您有数千行,则脚本可能会超出时间限制。那就需要其他技巧了。

也许它会起作用。慢慢地(由于 setValue() 为每个更改的行),但您可以运行多次:

function getStatus() {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Sites");
  var rows = sheet.getDataRange().getValues();

  var indexes = [];
  
  var filteredRows = rows.filter(function (row, i) {
    var status = row[9];
    if (status === "Active") {
      indexes.push(i+1); // save the index of filtered row
      return row;
    }
  });

  var options = {
    'muteHttpExceptions': true,
    'followRedirects': false,
    'validateHttpsCertificates': false
  };

  filteredRows.forEach(function (row, i) {

    var link = row[3];
    var status = row[9];
    var response = UrlFetchApp.fetch(link, options);

    if (response.getResponseCode() == 200) {
      sheet.getRange(indexes[i],10).setValue("Still Active!");
    } else {
      sheet.getRange(indexes[i],10).setValue("Closed!");
    }

  })
}

【讨论】:

  • 这对我有用。做得很好,我不介意跑 2-3 次 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 2016-10-08
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
相关资源
最近更新 更多