如何根据我的某个列中的值自动对Google表格进行排序?

时间:2018-03-19 15:10:13

标签: google-apps-script google-sheets

我正在处理Google表格文档(链接在本段末尾),用于跟踪人们借用的附件。我编写了一个公式,用于更新条目的状态,如下所示:良好,逾期,退回,返回延迟和缺失信息。我的目标是每天重新排列行以将过期的项目放在第一位,将状态条目放在第二位,丢失信息第三位,最后返回项目。通过使用内置数据过滤器,我能够做类似的事情。为此,我转到了数据 - >创建过滤器 - >单击状态栏右下角的符号 - >排序Z-A。但是这个解决方案是手动的,因为我不知道(据我所知)使用app脚本运行过滤器功能。此外,它对行进行排序的顺序并不完全是我需要的。我写了下面的应用程序脚本函数试图反击,但它似乎没有像想象的那样工作。

onSetDevices

其余代码可以在共享文档的脚本部分找到。

https://docs.google.com/spreadsheets/d/15qaNHuMoVyEJmwR5pL9ruPFDeiNR60cKWLKxnfjaWko/edit?usp=sharing

如果您对如何完成此类操作或我的代码出错,请告诉我。 谢谢!

2 个答案:

答案 0 :(得分:1)

您需要为Array.prototype.sort()方法定义自定义比较器。当第一个对象在第二个对象之前时,比较器需要返回负数,当两个对象可以互换时,需要返回0,当第一个对象在第二个对象之后时,比较器需要返回正数。 为了避免许多讨厌的案例考虑因素,可以通过定义“查找表”来轻松完成,该查找表返回给定可能输入值的数值:

// Comparison object. Objects to come first should be ranked lower.
var ordering = {
    "Good": 5,                     // Will come last.
    "Missing Info": 2,
    "Overdue": 1,                  // Will come first.
    "Returned": 3,
    "Returned Late": 4,
};

var compareIndex = 1; // Column B data, for example
var sheetData = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn()).getValues();
sheetData.sort(function (row1, row2) {
  // If the compare value is not found in the comparison object, or is convertible to "false" (e.g. 0)
  // then the "|| 400" portion makes it default to a value of 400.
  var v1 = ordering[row1[compareIndex]] || 400;
  var v2 = ordering[row2[compareIndex]] || 400;

  return (v1 - v2);
});
sheet.getRange(2, 1, sheetData.length, sheetData[0].length).setValues(sheetData);

通过更改比较对象中的值,您可以更改行的排序顺序。如果你希望首先获得“好”评级,你会希望“好”的值最低。

另请参阅this one等相关问题。

答案 1 :(得分:0)

虽然与Java脚本数组函数相比,内置电子表格函数可能会很慢,但此自定义构建函数可用于您的测试用例:

function OverdueGoodMissingReturned() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getSheetByName("Main");
  var lr = sh.getLastRow();
  var lc = sh.getLastColumn();
  var irng = sh.getRange(1,9,lr,1).getValues(); //get col I (StatusColumn)
  var irngF = irng.map(flatten); //Flatten the 2D array
  function flatten(e) {return e[0];}
  var lr = irngF.indexOf(''); //Find actualLast Row (This is needed,because you filled all the rows with Data Validations)
  var rng = sh.getRange(2,1,lr-1,lc); //getWholeRange
  rng.sort(9); //Sort by the status Column 9,Default Sort is Good,Missing,Overdue,Returned
  var rv = rng.getValues();
  var irng = sh.getRange(1,9,lr,1).getValues();
  var irngF = irng.map(flatten);
  var O1 = irngF.indexOf('Overdue')+1; // Find first overdue
  var O2 = irngF.lastIndexOf('Overdue')+1; //Find Last overdue
  var mv = sh.getRange(O1+':'+O2); //getRange to move
  sh.moveRows(mv,2); //Move Overdue to Top
  }

注意:如果不使用数据验证填充空行,可能会截断很多getRange调用。 rng.sort也可以缩短为sheet.sort()