【问题标题】:Google Apps Script Additional Sorting RulesGoogle Apps 脚本附加排序规则
【发布时间】:2013-04-07 04:57:32
【问题描述】:

我正在开发一个 Google Apps Script 电子表格应用程序,我希望该程序具有的一项功能是根据来自 2 个不同列的数据自动对一系列表单响应进行排序。所以我想按第 16 列中的数据对其进行排序,然后按第 1 列排序。我可以使用以下方法手动实现此功能: https://drive.googleblog.com/2010/06/tips-tricks-advanced-sorting-rules-in.html

目前我正在使用第一列运行Spreadsheet.sort(column, ascending) 函数,但我无法对其进行排序,以便它接受第二列作为附加排序规则。 Google Apps 脚本中是否有可以用来模拟此功能的方法?

【问题讨论】:

    标签: sorting google-apps-script google-spreadsheet-api


    【解决方案1】:

    见文档: https://developers.google.com/apps-script/reference/spreadsheet/range#sort(Object)

    function sortFormResponses() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
    
      // change name of sheet to your sheet name
      var s = ss.getSheetByName("Form Responses");
      var lastCol = s.getLastColumn();
      var lastRow = s.getLastRow();
    
      // assumes headers in row 1
      var r = s.getRange(2, 1, lastRow - 1, lastCol);
    
      // Note the use of an array
      r.sort([{ column: 1, ascending: true }, { column: 16, ascending: true}]);
    
    }
    

    【讨论】:

    • 这是一流的解决方案!我不知道那个方法。感谢您的信息:-)
    • 非常感谢,这正是我想要的。
    • 新文档包含大量新信息和代码示例,非常值得回顾。感谢 Google 员工。
    【解决方案2】:

    您可以在数组级别进行排序,只需将数据从工作表获取到矩阵,然后在多遍中对矩阵进行排序,选择要排序的列。

    类似这样的:

    function test(){
    sortSheetOnColumn(2,3)
    }
    
    function sortSheetOnColumn(col1,col2){
      var sh = SpreadsheetApp.getActiveSheet();
      var data = sh.getDataRange().getValues();// get all data
      var header = data.shift();
      data.sort(function(x,y){  // Note: sort method changes the original array
    //  var xp = Number(x[col2-1]);// use these to sort on numeric values
    //  var yp = Number(y[col2-1]);
      var xp = x[col2-1].toLowerCase();// use these for non-numeric values
      var yp = y[col2-1].toLowerCase(); // I used toLowerCase() for my use case but you can remove it or change it to whatever you need
      Logger.log(xp+'   '+yp); // just to check the sort is OK
      return xp == yp ? 0 : xp < yp ? -1 : 1;// sort on column col ascending
      });
      data.sort(function(x,y){  // Note: sort method changes the original array
    //  var xp = Number(x[col1-1]);// use these to sort on numeric values
    //  var yp = Number(y[col1-1]);
      var xp = x[col1-1].toLowerCase();// use these for non-numeric values
      var yp = y[col1-1].toLowerCase();//
      Logger.log(xp+'   '+yp); // just to check the sort is OK
      return xp == yp ? 0 : xp < yp ? -1 : 1;// sort on column col ascending
      });
    // and at the end take back the headers
      data.unshift(header);
      sh.getDataRange().setValues(data);
    }
    

    或者更好,跟随亚当的评论:

    function sortSheetOnColumn2(col1, col2) {
      var sh = SpreadsheetApp.getActiveSheet();
      var data = sh.getDataRange().getValues();// get all data
      var header = data.shift(), x1, y1, x2, y2;
      col1--;
      col2--;
      data.sort(function(x, y) {
        x1 = x[col1].toLowerCase();
        y1 = y[col1].toLowerCase();
        x2 = x[col2].toLowerCase();
        y2 = y[col2].toLowerCase();
        return x1 == y1 ? (x2 == y2 ? 0 : x2 < y2 ? -1 : 1) : x1 < y1 ? -1 : 1;
      });
      data.unshift(header);
      sh.getDataRange().setValues(data);
    }
    

    但是 Michael 的回答如果更聪明的话使用我不知道的内置 Range.sort 方法(至少是它的扩展可能性)。

    【讨论】:

    • 我不知道它是否会更有效,但我认为您也可以使用单个函数对数组进行排序:data.sort(function(x,y){return x[0] == y[0] ? (x[1] == y[1] ? 0 : x[1] &lt; y[1] ? -1 : 1) : x[0] &lt; y[0] ? -1 : 1;});
    • 嗨,亚当,有趣!但我这样做是为了更清楚地处理排序顺序,即首先是哪一列......要得到一个合乎逻辑的结果似乎很棘手......(对我的观点来说是“合乎逻辑的”;-) - 在你的方法中顺序是什么?
    • 我的逻辑可能有缺陷 Serge,但我试图实现与您相同的顺序;即“col1”优先于“col2”。因此,仅当相应的“col1”值相等时才需要比较“col2”值。同样,我的逻辑可能有漏洞......
    • 我在测试表上试过了,但我不能让它做我想做的事......如果你有时间花点时间,你能用完整的代码添加第二个答案吗?这是一个shared ss 来测试,我的代码在那里
    • 好的,伙计,我在你的 ss 中输入了一个完整的替代函数供你阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多