【问题标题】:Filter data by column K in Google Script Editor (Google Sheets)在 Google 脚本编辑器(Google 表格)中按 K 列过滤数据
【发布时间】:2017-09-17 06:27:58
【问题描述】:

在此示例中,我将一组来自 Google 表格 (4Cat) 的数据输入到另一个表格 (ImportFeeder) 中,并在其中运行我的 Google 脚本。

在下面脚本的末尾,如何插入过滤器脚本以按第 K 行对数据进行排序? (仅显示 iPad 产品)

function myFunction() {
var sss = SpreadsheetApp.openById('1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s'); //replace with source ID
var ss = sss.getSheetByName('4cat'); //replace with source Sheet tab name
var range = ss.getRange('A:I'); //assign the range you want to copy
var data = range.getValues();

var tss = SpreadsheetApp.openById('1u7547KaniKHLUJn2v-ezN4l8ZcxE4viCFcoxsA904MI'); //replace with destination ID
var ts = tss.getSheetByName('Sheet1'); //replace with destination Sheet tab name
ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);

var range = ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length)
var rawData = range.getValues()     // get value from spreadsheet 2
var data = []                       // Filtered Data will be stored in this array
for (var i = 0; i< rawData.length ; i++){
if(rawData[i][10] == "iPad")            // Check to see if column K says ipad if not skip it
{
data.push(rawData[i])
}
}
}

(无法读取未定义的属性长度)

4Cat 样本数据https://docs.google.com/spreadsheets/d/1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s/edit?usp=sharing */

喂食

ImportFeeder https://docs.google.com/spreadsheets/d/1u7547KaniKHLUJn2v-ezN4l8ZcxE4viCFcoxsA904MI/edit?usp=sharing

必需 - 成功的工作表到工作表导入,在 Google 脚本中按行 K 过滤数据。在脚本顶部添加一个 clear() 表单函数,因为这将每天运行,并且每天导入之前需要清除表单。

【问题讨论】:

  • 您要过滤或排序?过滤器删除除特定值以外的所有内容或按字母顺序排序?
  • 这是我通过谷歌脚本需要的过滤器,不是排序
  • 您是否只想将第一个电子表格中的特定数据子集复制到第二个电子表格(k 列中有 iPad 的)?
  • 谢谢杰克。没有整套数据进入进纸器表。然后整个工作表按 K 列排序,仅显示 iPad 产品
  • 我添加了一个关于最终代码应该是什么样子的编辑

标签: javascript google-apps-script filter google-sheets-api


【解决方案1】:

为什么不使用自定义过滤功能? 添加了.toLowerCase() 以匹配“ipad”不区分大小写。

function myFunction() {
var sss = SpreadsheetApp.openById('1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s'); //replace with source ID
var ss = sss.getSheetByName('4cat');   //replace with source Sheet tab name
var range = ss.getRange('A:V');        //assign the range you want to copy
var rawData = range.getValues()        // get value from spreadsheet 1
var data = rawData.filter(isColKiPad); // Filtered Data will be stored in this array
var tss = SpreadsheetApp.openById('1u7547KaniKHLUJn2v-ezN4l8ZcxE4viCFcoxsA904MI'); //replace with destination ID
var ts = tss.getSheetByName('Sheet1'); //replace with destination Sheet tab name
ts.getRange(2,1,ts.getLastRow() - 1,ts.getLastColumn()).clear(); // Assuming header is in the first row, clears sheet but header
ts.getRange(2, 1, data.length, data[0].length).setValues(data);
};
// Change both to ts.getRange(1,1,[...] if there's no header row
function isColKiPad(arr) {
  return arr[10].toLowerCase() == "ipad";
};

您是否考虑过使用电子表格公式?您可以尝试结合使用=IMPORTRANGE(spreadsheet_key, string_range)QUERY(data, query, [header]) 来导入已过滤的范围:

=QUERY(IMPORTRANGE("1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s";"4cat!A:V");"SELECT * WHERE Col11 = 'iPad'")

你甚至不需要用这种方式清理你的工作表。

【讨论】:

    【解决方案2】:

    您可以将其添加到您的原始代码中:

    filterByText(rawData, 10, iPad);
    

    只要在 myFunction 函数之后添加此函数,它就会起作用:

    function filterByText(data, columnIndex, values) {
        var value = values;
        if (data.length > 0) {
            if (typeof columnIndex != "number" || columnIndex > data[0].length) {
                throw "Please, can you choose a valid column index?";
            }
            var r = [];
            if (typeof value == "string") {
                var reg = new RegExp(escape(value).toUpperCase());
                for (var i = 0; i < data.length; i++) {
                    if (columnIndex < 0 && escape(data[i].toString()).toUpperCase().search(reg) != -1 || columnIndex >= 0 && escape(data[i][columnIndex].toString()).toUpperCase().search(reg) != -1) {
                        r.push(data[i]);
                    }
                }
                return r;
            } else {
                for (var i = 0; i < data.length; i++) {
                    for (var j = 0; j < value.length; j++) {
                        var reg = new RegExp(escape(value[j]).toUpperCase());
                        if (columnIndex < 0 && escape(data[i].toString()).toUpperCase().search(reg) != -1 || columnIndex >= 0 && escape(data[i][columnIndex].toString()).toUpperCase().search(reg) != -1) {
                            r.push(data[i]);
                            j = value.length;
                        }
                    }
                }
                return r;
            }
        } else {
            return data;
        }
    }
    

    上面是 Google Apps 脚本的 ArrayLib 库 filterByText method 使用的 code。我实际上只是复制了它并使投掷更友好。

    您的完整代码可能如下所示:

    function myFunction() {
      var sss = SpreadsheetApp.openById('1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s'); //replace with source ID
      var ss = sss.getSheetByName('4cat'); //replace with source Sheet tab name
      var range = ss.getRange('A:I'); //assign the range you want to copy
      var data = range.getValues();
    
      var tss = SpreadsheetApp.openById('1u7547KaniKHLUJn2v-ezN4l8ZcxE4viCFcoxsA904MI'); //replace with destination ID
      var ts = tss.getSheetByName('Sheet1'); //replace with destination Sheet tab name
      ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
    
      var range = ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length)
      var rawData = range.getValues()     // get value from spreadsheet 2
      var data = filterByText(rawData, 10, iPad); // rawData is now sorted.
      range.clear();
    
      var powerRange = ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length);
    
      powerRange.setValues(data);
    } 
    
    function filterByText(data, columnIndex, values) {
        var value = values;
        if (data.length > 0) {
            if (typeof columnIndex != "number" || columnIndex > data[0].length) {
                throw "Please, can you choose a valid column index?";
            }
            var r = [];
            if (typeof value == "string") {
                var reg = new RegExp(escape(value).toUpperCase());
                for (var i = 0; i < data.length; i++) {
                    if (columnIndex < 0 && escape(data[i].toString()).toUpperCase().search(reg) != -1 || columnIndex >= 0 && escape(data[i][columnIndex].toString()).toUpperCase().search(reg) != -1) {
                        r.push(data[i]);
                    }
                }
                return r;
            } else {
                for (var i = 0; i < data.length; i++) {
                    for (var j = 0; j < value.length; j++) {
                        var reg = new RegExp(escape(value[j]).toUpperCase());
                        if (columnIndex < 0 && escape(data[i].toString()).toUpperCase().search(reg) != -1 || columnIndex >= 0 && escape(data[i][columnIndex].toString()).toUpperCase().search(reg) != -1) {
                            r.push(data[i]);
                            j = value.length;
                        }
                    }
                }
                return r;
            }
        } else {
            return data;
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以在 sorting in a range here 上找到文档。使用 getRange 排序选择一个范围,然后像这样排序函数

      var range = ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length)
      // Use the below line instead, if you want to sort whole sheet, not just the newly entered data! 
      // var range = ts.getDataRange()     
      range.sort(11)         // sort based on column number 11
      

      编辑 1: 要仅根据要复制到新工作表的列过滤值,您需要修剪从不需要的所有值的工作表中获得的数据。

      var rawData = range.getValues()     // get value from spreadsheet1
      var data = []                       // Filtered Data will be stored in this array
      for (var i = 0; i< rawData.length ; i++){
       if(rawData[i][10] == "iPAD")            // Check to see if column K says ipad if not skip it
       {
       data.push(rawData[i])
       }
      }
      // Now you can paste array data to your new spreadsheet like before. 
      

      编辑 2:这是最终代码的样子,

      function myFunction() {
      var sss = SpreadsheetApp.openById('1kL96dRm3Z8XBtMXnSzUARxR1b34-njlkZQ1sU0c3g1s'); //replace with source ID
      var ss = sss.getSheetByName('4cat'); //replace with source Sheet tab name
      var range = ss.getRange('A:V');      //assign the range you want to copy
      var rawData = range.getValues()     // get value from spreadsheet 1
      var data = []                       // Filtered Data will be stored in this array
      for (var i = 0; i< rawData.length ; i++){
      if(rawData[i][10] == "iPad")            // Check to see if column K says ipad if not skip it
      {
      data.push(rawData[i])
      }
      }
      var tss = SpreadsheetApp.openById('1u7547KaniKHLUJn2v-ezN4l8ZcxE4viCFcoxsA904MI'); //replace with destination ID
      var ts = tss.getSheetByName('Sheet1'); //replace with destination Sheet tab name
      ts.getRange(ts.getLastRow()+1, 1, data.length, data[0].length).setValues(data);
      
      }
      

      【讨论】:

      • 使用编辑 2 获取此错误,-------- 类型错误:无法从未定义中读取属性“长度”。 (第 15 行,文件“代码”)
      • 哪一行是no: "15"
      • 还可以尝试将这一行 if(rawData[i][10] == "iPAD") 更改为 if(rawData[i][10] == "iPad") 请注意将大写字母更改为小写字母
      • 好的,现在正在导入,所以差不多了。但是第 J 行之后的所有内容都没有导入或过滤器在 [结果] 中启动:docs.google.com/spreadsheets/d/…
      • 修改了上面的代码,包括范围(“A:V”),应该照顾它
      猜你喜欢
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      相关资源
      最近更新 更多