【问题标题】:Writing Sorted Table Data to the Table in a Separate Format using Google Sheets使用 Google 表格将排序后的表格数据以单独的格式写入表格
【发布时间】:2019-10-04 21:21:37
【问题描述】:

我对 javascript 比较陌生,对谷歌脚本绝对是新手。

我有一个用于输入原始数据的选项卡。我有另一个选项卡对数据进行排序,稍后会在该行旁边写一个批准日期。我希望该日期反映到正确行中的第一个选项卡,并且我还想确保它保留在第二个选项卡中的正确行上(即使在添加和排序新行之后)。

附件是一个只有几行的示例表。实际上我有更多的列,但它们在这里无关紧要。 https://docs.google.com/spreadsheets/d/14dh0IW7vO8c2OLc2O8WE-Ptuh3MJfLWTESVMA_DpOv0/edit?usp=sharing 我的第二个选项卡使用工作表排序功能。但是,当键入日期时,它会产生错误。我打算通过使用 onEdit() 函数并将日期写入第一个选项卡中的正确行,然后清除第二个选项卡中的日期列(以避免错误并保持对齐)来解决此问题。

''javascript
function onEdit() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet2 = ss.getSheetByName("check released");
  var sheet1 = ss.getSheetByName("Log");

  var job2 = sheet2.getRange("A2:A1000").getValues();
  var job1 = sheet1.getRange("A2:A1000").getValues();

  var draw2 = sheet2.getRange("B2:B1000").getValues();
  var draw1 = sheet1.getRange("B2:B1000").getValues();

  var inv2 = sheet2.getRange("C2:C1000").getValues();
  var inv1 = sheet1.getRange("C2:C1000").getValues();

  var dates2 = sheet2.getRange("D2:D1000");
  var dates_values = sheet2.getRange("D2:D1000").getValues();
  var dates1 = sheet1.getRange("D2:D1000");

  var indices = []

  var to_paste = []

  for(var i = 0; i < job2.length; i++) {
    var job2_Value = job2[i][0];
    var draw2_Value = draw2[i][0];
    var inv2_Value = inv2[i][0];
    for(var j=0; j<job2.length; j++) {
      var job1_Value = job1[j][0];
      var draw1_Value = draw1[j][0];
      var inv1_Value = inv1[j][0];
      if((job2_Value != "") && (job1_Value == job2_Value) && (draw1_Value === draw2_Value) && (inv1_Value === inv2_Value)) {
        indices.push([i]); 
      }
    }
  }  

  for(k in indices) {
    to_paste.push([dates2[k]])
  }

  Logger.log(to_paste)
  dates1.setValues(to_paste)
  dates2.clearContent()
  Logger.log("Cleared on check released page")

};
'''

这是我编写的代码,但它不起作用,我不知道为什么。我也不知道在哪里可以找到控制台日志。

【问题讨论】:

  • 我可以问你关于你的问题吗? 1.你的问题是什么? 2. 可以提供it doesn't work的详细信息吗? 3. 你能提供你期望的输出吗?
  • 当您回答@Tanaike 关于“它不起作用”的问题时,如果问题是脚本失败,请将执行脚本复制/粘贴到您的问题中。
  • 问题不在于脚本失败,而是我认为实际算法不正确。我希望索引包含与 dates1 应该的相同记录相关的 dates2 的索引。然后 to_paste 应该在索引的索引处包含 dates2 的内容,然后 to_paste 应该写入 dates2。
  • 链接指向谷歌表格示例。
  • @Tedinoz 有什么建议吗?

标签: javascript google-sheets


【解决方案1】:

您有一张“已发布检查”表,该表从“表“日志”中获取值。您的目标是在“已发布检查”上输入“发布日期”并将其更新为“日志”,然后反映在“检查已发布”。您采用的方法是在“检查已发布”上编辑实际链接的“发布日期”值。毫不奇怪,这并不成功,因为它只是从“日志”中获取日期。

在以下代码中:

  • 我在“已发布支票”上使用了一个帮助列,可以在其中输入日期。
  • onEdit(e) 脚本检测新值,在“日志”上找到等效行。
  • 脚本会更新“日志”上的“日期”列 - 此时,“已发布检查”上的值会自动更新。
  • 然后脚本删除辅助列中的值。

从“日志”到“检查发布”的匹配

从“检查发布”到“日志”的行匹配依赖于几个元素:

  1. 没有记录具有真正唯一的标识符。
  2. 但是,Job、Draw 和 Invoice 编号的值在转换为字符串并连接时会生成一个唯一值,该值可用于比较从“日志”到“已发布支票”的值。
  3. “Log”上的值在循环中进行处理,以创建串联值的一维数组。
  4. 事件对象在“检查已发布”时提供已编辑的行;并且该行中的 Job、Draw 和 Invoice 值被连接起来。
  5. 使用 Javascript indexOf 方法,脚本“找到”“日志”中与已编辑行的唯一连接值匹配的行。

其他注意事项:

  • “日志”和“已发布检查”数据范围的实际大小由使用getlastRow() 确定
  • getRangegetValues 分别针对“日志”和“检查已发布”运行一次
  • 已为变量选择有意义的名称以反映其用途;这有助于阅读和理解代码。

function onEdit(e) {
  // 5824330602
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ui = SpreadsheetApp.getUi();
  var logsheet = "Log";
  var log = ss.getSheetByName(logsheet);
  var checkrsheet = "check released";
  var checkr = ss.getSheetByName(checkrsheet);


  // get Log data
  var logFR = 2;
  var logLR = log.getLastRow();
  var logLC = 4;
  var logRange = log.getRange(logFR,1,logLR-logFR+1,logLC);
  // Logger.log(logRange.getA1Notation());// DEBUG
  var logValues = logRange.getValues();


  // get check released data
  var checkrRange = checkr.getRange(logFR,1,logLR-logFR+1,logLC);
  //Logger.log(checkrRange.getA1Notation());
  var checkrValues = checkrRange.getValues();


  // build array of uniquelogitems
  var logitems=[];
  for (var i=0; i<logValues.length; i++) {
    var logjob = logValues[i][0].toString();
    var logdraw = logValues[i][1].toString();
    var loginv = logValues[i][2].toString();
    var logid = logjob+logdraw+loginv;
    //Logger.log("DEBUG: LOG: Job= "+logjob);
    //Logger.log("DEBUG: LOG: draw= "+logdraw);
    //Logger.log("DEBUG: LOG: inv= "+loginv);
    //Logger.log("DEBUG: LOG: concat= "+logid);
    var logid = logjob+logdraw+loginv;
    logitems.push(logid);
  }
  //Logger.log(logitems); //DEBUG


  // get the event objects
  var editedRow = e.range.getRow();
  var editedCol = e.range.getColumn();
  var editedSheet = e.range.getSheet().getSheetName();
  var editedValue = e.value;
  // Logger.log("DEBUG: row = "+editedRow+", column = "+editedCol+", Sheet = "+editedSheet)


  // apply logic to test whether this edit should be processed
  // Column 5 ("E") is the helper column
  if(editedRow >= logFR && editedRow <=logLR && editedCol === 5 && editedSheet === checkrsheet){
    // the edit is in Column E (Date), between the first and last rows of data, on the "check released" sheet
    //Logger.log("DEBUG: edit is OK. edit row = "+editedRow+". Keep processing");

    var checkrjob = checkrValues[editedRow-2][0].toString();
    var checkrdraw = checkrValues[editedRow-2][1].toString();
    var checkrinv = checkrValues[editedRow-2][2].toString();
    var checkritem = checkrjob+checkrdraw+checkrinv;
    //Logger.log("DEBUG: Checkr: job="+checkrjob+", draw= "+checkrdraw+", inv = "+checkrinv+", Item = "+checkritem);
    var match = logitems.indexOf(checkritem);
    //Logger.log("DEBUG: Matching row = "+match);

    // get the existing date
    var existingdate = logValues[+match+1][3];
    var cell = log.getRange(+match+2,4);
    //Logger.log("DEBUG: the update cell = "+cell.getA1Notation())


    // date field is a date, so update new date
    cell.setValue(editedValue);
    cell.setNumberFormat('mm/dd/yy');
    e.range.clearContent();

    //Logger.log("DEBUG: updated date on Log")
  }
  else{
    // the edit didn't meet the rule
    //Logger.log("DEBUG: edit did NOT meet criteria. Do not proceed")
  }

};

E 列 - 辅助列

【讨论】:

  • 谢谢!这看起来工作得很好!有没有办法只使用一列而不是辅助列?就像工作表在编辑后没有计算并且查询保持不变一样。那可能吗?否则这将起作用。
  • 没有。 tl; dr您描述了关联记录,将内容粘贴到日期1,以及“写”回日期2。这是对日期2的错误理解。 data2 的单元格 A1 包含一个 sort 函数并输出到 A、B、C 列 AND D。如果用户直接在 D 列的单元格中键入日期,则 #REF! 将显示在单元格中A1 和 的所有输出单元格变为空白。 onEdit 记录新日期,但没有相关信息。助手栏是必不可少的(至少在我的经验中)。经过反思,绿色背景应该在辅助列上,而不是 D 列上。
  • 好的,我已经在我的完整电子表格中实现了这一点,而且效果非常好。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 2014-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多