【问题标题】:Delete a row in Google Spreadsheets if value of cell in said row is 0 or blank如果该行中的单元格值为 0 或空白,则删除 Google 电子表格中的一行
【发布时间】:2012-06-15 20:50:21
【问题描述】:

如果在该行中为“C”列输入的值为 0 或空白,我希望能够删除 Google 电子表格中的整行。有没有我可以编写的简单脚本来完成此操作? 谢谢!

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    我可以在不使用脚本的情况下提出一个简单的解决方案!

    假设您要删除 C 列中包含空文本的行。 在工作表 w.r.t 列 C 中对数据进行排序(数据菜单 -> 按 C 列排序工作表,A->Z),因此所有空文本行将一起可用。

    只需选择这些行并右键单击 -> 删除行。 然后你可以根据你需要的列重新排序你的数据。 完成。

    【讨论】:

    • 我不知道为什么我没想到! :-) 谢谢。
    • 太棒了!为我工作
    • 那是KISS 作为答案
    【解决方案2】:
    function onEdit(e) {
      //Logger.log(JSON.stringify(e)); 
      //{"source":{},"range":{"rowStart":1,"rowEnd":1,"columnEnd":1,"columnStart":1},"value":"1","user":{"email":"","nickname":""},"authMode":{}}
      try {
        var ss = e.source; // Just pull the spreadsheet object from the one already being passed to onEdit
        var s = ss.getActiveSheet();
    
        // Conditions are by sheet and a single cell in a certain column
        if (s.getName() == 'Sheet1' &&  // change to your own 
            e.range.columnStart == 3 && e.range.columnEnd == 3 &&  // only look at edits happening in col C which is 3
            e.range.rowStart == e.range.rowEnd ) {  // only look at single row edits which will equal a single cell
          checkCellValue(e); 
        }
      } catch (error) { Logger.log(error); }
    };
    
    function checkCellValue(e) {
      if ( !e.value || e.value == 0) {  // Delete if value is zero or empty
        e.source.getActiveSheet().deleteRow(e.range.rowStart);
      }
    }
    

    现在只查看单个单元格编辑中的值,而不是整个工作表中的值。

    【讨论】:

    • 我从不使用这种“快捷方式”语法,这就是我问的原因......但我的问题很愚蠢,我实际上并没有看到你在使用 values ,我的大脑将其翻译为values.length...我想我有时一定是有点太累了 ;-) ;无论如何,谢谢你的回答,我也不知道最好的方法是什么......我想这或多或少是一个个人喜好问题!
    • 我接受了这个并将 onEdit() 更改为任意函数名称,因为我想在已经存在的数据上运行它,而不是在编辑时运行它,但它有一个奇怪的行为:当我选择它时从脚本管理器中运行它,它会删除 one 行并停止,然后我必须再次运行它。更改存在的行数时会取消循环吗?
    • @BryanP 向后迭代不是更容易吗? for( var row = values.length -1; row >= 0; --row )
    • 是的,BrianP,如果向后迭代,则不需要额外的更正 delete 变量。好吧,也许它在我的脑海中更简单:)
    • @BryanP 您应该避免在 Javascript 中使用 for-in 循环,因为它会遍历所有属性,而不仅仅是您分配的属性。这是一篇讨论它的文章:yuiblog.com/blog/2006/09/26/for-in-intrigue
    【解决方案3】:

    我编写此脚本是为了对我的一个 Google 电子表格执行相同的操作。我希望能够在所有数据都在电子表格中之后运行脚本,所以我让脚本添加了一个菜单选项来运行脚本。

    /**
     * Deletes rows in the active spreadsheet that contain 0 or
     * a blank valuein column "C". 
     * For more information on using the Spreadsheet API, see
     * https://developers.google.com/apps-script/service_spreadsheet
     */
    function readRows() {
      var sheet = SpreadsheetApp.getActiveSheet();
      var rows = sheet.getDataRange();
      var numRows = rows.getNumRows();
      var values = rows.getValues();
    
      var rowsDeleted = 0;
      for (var i = 0; i <= numRows - 1; i++) {
        var row = values[i];
        if (row[2] == 0 || row[2] == '') {
          sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
          rowsDeleted++;
        }
      }
    };
    
    /**
     * Adds a custom menu to the active spreadsheet, containing a single menu item
     * for invoking the readRows() function specified above.
     * The onOpen() function, when defined, is automatically invoked whenever the
     * spreadsheet is opened.
     * For more information on using the Spreadsheet API, see
     * https://developers.google.com/apps-script/service_spreadsheet
     */
    function onOpen() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      var entries = [{
        name : "Remove rows where column C is 0 or blank",
        functionName : "readRows"
      }];
      sheet.addMenu("Script Center Menu", entries);
    };
    

    之前测试电子表格:

    从菜单运行脚本:

    运行脚本后:

    【讨论】:

    • 如果该行完全为空,那将不起作用,因为 .getDataRange() 不会拾取空行。
    • 脚本中心菜单似乎没有添加到我的电子表格中。我对如何做到这一点感到困惑/
    • 我尝试运行以下内容:TypeError: Cannot call method "getDataRange" of null. (line 10, file "Code")。这可能是我对如何跑步的了解的问题;这是我尝试的第一个 Google 脚本。
    • 我正在尝试将其与 .clearRows 一起使用以仅清除而不删除指定的行,但我似乎无法使其工作。你能帮我解决这个问题吗?
    【解决方案4】:

    我在使用脚本时遇到了一些问题,所以我的解决方法是使用“过滤器”工具。

    1. 选择所有电子表格数据
    2. 点击过滤工具图标(看起来像酒杯)
    3. 在您要搜索的列的第一个单元格中单击新可用的过滤器图标。
    4. 选择“按条件过滤”>设置条件(我使用的是“文本包含”>“单词”)

    这将留下包含您搜索的单词的行,并且可以通过在按住 shift 键 > 右键单击​​ > 删除行的同时批量选择它们来删除它们。

    【讨论】:

      【解决方案5】:

      这就是我设法完成的工作。您可以看到我在工作表中向后循环,以便在删除一行时不会跳过下一行。我希望这对某人有所帮助。

        function UpdateLog() {
      
        var returnSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('RetLog');
        var rowCount = returnSheet.getLastRow();
      
        for (i = rowCount; i > 0; i--) {
          var rrCell = 'G' + i;
          var cell = returnSheet.getRange(rrCell).getValue();
          if (cell > 0 ){
            logSheet.
            returnSheet.deleteRow(i);
          }
        }
      }
      

      【讨论】:

        【解决方案6】:

        很简单的请求。试试这个:

         function try_It(){
         deleteRow(2); //// choose col = 2 for column C
         }
        
         function deleteRow(col){ // col is the index of the column to check for 0 or empty
         var sh = SpreadsheetApp.getActiveSheet();
         var data = sh.getDataRange().getValues();
         var targetData = new Array();
         for(n=0;n<data.length;++n){
         if(data[n][col]!='' && data[n][col]!=0){ targetData.push(data[n])};
         }
         Logger.log(targetData);
         sh.getDataRange().clear();
         sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);
         }
        

        EDIT重新阅读问题已输入...我不太清楚...所以如有必要,请随时更准确;)

        【讨论】:

        • 仅供参考,另一个答案更好,因为我的不处理公式(如果 SS 中有公式的话)并且更直接。
        • 我认为这个答案上的代码在时间执行方面是最有效的。这应该在工作表只有单元格值时使用(没有注释、cmets、数据验证、自定义格式......)。
        【解决方案7】:

        有一个更简单的方法:

        1. 使用filtering 仅显示要删除的行。例如,我要删除行的列上有类别,A、B、C。通过过滤界面,我只选择了我要删除的 A 和 B。
        2. 选择所有行并将其删除。在我的示例中,这样做有效地选择了所有 A 行和 B 行并将其删除;现在我的电子表格没有显示任何行。
        3. 关闭过滤器。这会取消隐藏我的 C 行。完成!

        【讨论】:

        • @Serge 我被标题和正文中问题的细微差别愚弄了。将提出修改建议。
        【解决方案8】:

        仔细阅读您的问题,我想出了这个解决方案:

        function onOpen() {
          // get active spreadsheet
          var ss = SpreadsheetApp.getActiveSpreadsheet();
        
          // create menu
          var menu = [{name: "Evaluate Column C", functionName: "deleteRow"}];
        
          // add to menu
          ss.addMenu("Check", menu);
        }
        
        function deleteRow() {
          // get active spreadsheet
          var ss = SpreadsheetApp.getActiveSpreadsheet();
        
          // get active/selected row
          var activeRow = ss.getActiveRange().getRowIndex();
        
          // get content column C
          var columnC = ss.getRange("C"+activeRow).getValue();
        
          // evaluate whether content is blank or 0 (null)
          if (columnC == '' || columnC == 0) {
            ss.deleteRow(parseInt(activeRow));
          }
        }
        

        此脚本将在文件加载时创建一个菜单,并允许您根据 C 列中设置的条件删除一行,或者

        【讨论】:

        • 我想知道 Zack 是想让他的整张表格自动重新排列还是想自己决定?
        【解决方案9】:

        这个简单的代码为我完成了这项工作!

            function myFunction() {
        
              var ss = SpreadsheetApp.getActiveSpreadsheet();  // get active spreadsheet
        
              var activeRow = ss.getActiveRange().getRowIndex();  // get active/selected row
        
        var start=1;
        var end=650;
        var match='';
        var match2=0;   //Edit this according to your choice.
        
             for (var i = start; i <= end; i++) {
              var columnC = ss.getRange("C"+i).getValue();
              if (columnC ==match  || columnC ==match2){ ss.deleteRow(i); }
             }
            }
        

        【讨论】:

          【解决方案10】:

          以下代码能够在特定列 G 中删除包含今天之前 50 天以上的日期的行,将这些行值移动到备份工作表并从源工作表中删除这些行。

          代码更好,因为它一次删除行而不是逐个删除。运行速度更快。

          它不会像一些建议的解决方案那样复制回值(通过推入数组并复制回工作表)。如果我遵循这个逻辑,我就会丢失这些单元格中包含的公式。

          我每天晚上(预定)在没有人使用工作表时运行该功能。

          function delete_old(){
            //delete > 50 day old records and copy to backup
            //run daily from owner login
            var ss = SpreadsheetApp.getActiveSpreadsheet();  
            var bill = ss.getSheetByName("Allotted");
            var backss = SpreadsheetApp.openById("..."); //backup spreadsheet
            var bill2 = backss.getSheetByName("Allotted");
            var today=new Date();
            //process allotted sheet (bills)
            bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
            ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 7, ascending: true});
            var data = bill.getDataRange().getValues();
            var delData = new Array();
            for(n=data.length-1; n>1; n--){
              if(data[n][6] !=="" &&  data[n][6]  < today.getTime()-(50*24*3600*1000) ){  //change the condition as per your situation
                delData.push(data[n]);
              }//if
             }//for
             //get first and last row no to be deleted
             for(n=1;n<data.length; n++){
              if(data[n][6] !=="" &&  data[n][6]  < today.getTime()-(50*24*3600*1000) ){ 
                var strow=n+1 ; //first row
                break
              }//if
             }//for
             for(n=data.length-1; n>1; n--){
              if(data[n][6] !=="" &&  data[n][6]  < today.getTime()-(50*24*3600*1000) ){ 
                var ltrow=n+1 ; //last row
                break
              }//if
             }//for
             var bill2lr=bill2.getLastRow();
             bill2.getRange((bill2lr+1),1,delData.length,delData[0].length).setValues(delData);
             bill.deleteRows(strow, 1+ltrow-strow);
             bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
             ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 6, ascending: true}); //get back ordinal sorting order as per column F
          }//function
          

          【讨论】:

            【解决方案11】:

            有一个简短的方法可以解决这个问题,而不是脚本。 选择整个数据>转到菜单>单击数据选项卡>选择创建过滤器>单击列标题旁边的过滤器>将出现弹出窗口,然后检查要删除的值>单击确定并将过滤后的数据复制到不同的工作表>完成

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-11-13
              • 2022-01-23
              • 2021-07-07
              • 2019-06-18
              • 2018-04-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多