【问题标题】:Get values skip errors获取值跳过错误
【发布时间】:2020-09-09 22:05:41
【问题描述】:

我目前正在学习谷歌应用脚​​本,遇到了一个小问题。

背景:我正在从 API 获取数据并将其写入电子表格,这在大多数情况下都可以正常工作,然后对数据进行一些处理。

在某些情况下,由于某种原因,导入无法正常工作。 (单元格值:#ERROR!) 对于这种情况,我制作了一个“复制”功能来将 API 数据复制到另一张表,从而跳过错误。因此,如果 1 个导入失败,我可以使用最后一个成功的导入。

问题: 对于一张纸来说,运行时间太高了,所以我从这段代码中改变了:

function copy() {
  var copyWert = ""; 
  for (var i = 3; i < 247; i++) { 
    for (var j = 1; j < 4;j++) {
      copyWert = SpreadsheetApp.getActive().getSheetByName('API').getRange(i, j).getValue();
      if (copyWert == "#ERROR!" || copyWert == "" || copyWert == "#NAME!") {
        
      } else {
        SpreadsheetApp.getActive().getSheetByName('Copy').getRange(i, j).setValue(copyWert);
      }
    }
  }
}

收件人:

function copy() {
  var values = SpreadsheetApp.getActiveSheet().getRange("A2:D300").getValues();
  SpreadsheetApp.getActive().getSheetByName('Copy').getRange("A2:D300").setValues(values);
}

哪种方式更快,但缺少检查。有什么想法吗?

【问题讨论】:

  • 试试这个:function copy1() { const ss=SpreadsheetApp.getActive(); const sh=ss.getSheetByName('API'); const rg=sh.getRange(3,1,245,4); var vA=rg.getValues(); for(var i=0;i&lt;vA.length;i++) { for(var j=0;j&lt;vA[i].length;j++) { if(vA[i][j]=="#ERROR" || vA[i][j]=="" || vA[i][j]=="#NAME") { }else{ sh.getRange(i+3,j+1).setValue(vA[i][j]) } } } }

标签: google-apps-script


【解决方案1】:

我相信你的目标如下。

  • 当值不是"#ERROR!""""#NAME!" 时,您希望将单元格值从API 复制到Copy
  • 您希望使用 Google Apps 脚本实现此目的。

修改点:

  • 当您只想复制没有"#ERROR!""""#NAME!" 的单元格值时,为了降低处理成本,我想使用Sheets API。
    • 在这种情况下,"#ERROR!""""#NAME!" 的单元格值不会被覆盖到 Copy 中的现有单元格中。
  • 当您可以允许覆盖所有单元格时,我认为您的第二个脚本可以通过修改来使用。

模式一:

在这种模式下,当您只想复制没有"#ERROR!""""#NAME!" 的单元格值时,为了降低处理成本,我想使用Sheets API。

示例脚本:

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

function copy() {
  // Ref: https://stackoverflow.com/a/21231012/7108653
  const columnToLetter = column => {
    let temp,
      letter = "";
    while (column > 0) {
      temp = (column - 1) % 26;
      letter = String.fromCharCode(temp + 65) + letter;
      column = (column - temp - 1) / 26;
    }
    return letter;
  };
  
  var spreadsheet = SpreadsheetApp.getActive();
  var values = spreadsheet.getSheetByName('API').getRange("A2:D300").getValues();
  var data = values.reduce((ar, r, i) => {
      r.forEach((copyWert, j) => {
        if (!(copyWert == "#ERROR!" || copyWert == "" || copyWert == "#NAME!")) {
          ar.push({range: `'Copy'!${columnToLetter(j + 1)}${i + 2}`, values: [[copyWert]]});
        }
      });
      return ar;
  }, []);
  Sheets.Spreadsheets.Values.batchUpdate({data: data, valueInputOption: "USER_ENTERED"}, spreadsheet.getId());
}

模式 2:

在此模式中,您的第二个脚本被修改。

示例脚本:

function copy() {
  var spreadsheet = SpreadsheetApp.getActive();
  var values = spreadsheet.getSheetByName('API').getRange("A2:D300").getValues();
  values = values.map(r => r.map(copyWert => (copyWert == "#ERROR!" || copyWert == "" || copyWert == "#NAME!") ? "" : copyWert));
  spreadsheet.getSheetByName('Copy').getRange("A2:D300").setValues(values);
}

参考资料:

【讨论】:

  • 以上脚本请在脚本编辑器中启用V8使用脚本。
  • 我刚刚意识到,这个脚本工作,但正在用数组中的“”替换错误值。这仍然会覆盖复制表中的旧值。
  • @Dewx19 感谢您的回复。我带来的不便表示歉意。我想确认一下您目前的情况。 1.您使用的是哪种模式? 2. 您能否提供用于复制您的问题的示例电子表格?借此,我想确认一下。因为在我的环境中,我无法复制你的情况。我为此道歉。如果您能合作解决您的问题,我很高兴。
  • 嘿@Tanaike 我不能提供任何表格,但可以给你一个例子:Api 看起来像 1123 测试 #ERROR! asdf Copy 看起来像(在脚本运行之前):1123 test asd asdf 在脚本运行后复制:1123 test asdf
  • @Dewx19 感谢您的回复。我可以理解您无法提供示例电子表格。当您展示示例时,请通过包含更多信息将它们添加到您的问题中。因为不幸的是,我无法理解Api looks like 1123 test #ERROR! asdf Copy looks like (before skript run): 1123 test asd asdf Copy after skript run: 1123 test asdf。我为此道歉。而且,我能问一下您正在使用我的示例脚本的哪种模式吗?不幸的是,我不确定您使用的脚本。我为我糟糕的英语水平深表歉意。
猜你喜欢
  • 2021-12-24
  • 2019-12-30
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 2022-01-18
  • 1970-01-01
  • 2023-02-21
  • 2017-02-06
相关资源
最近更新 更多