【问题标题】:Deleting ALL empty rows in a Google Spreadsheet删除 Google 电子表格中的所有空行
【发布时间】:2014-10-15 15:36:12
【问题描述】:

我刚刚开始使用 Google Apps 脚本来管理我正在处理的项目的一些工作表,我是 Javascript 新手,所以如果我的代码中有任何咆哮,请放轻松!

我们有一个名为 forms2mobile 的应用程序,它可以捕获数据并将其放入 Google 电子表格中。它实际上会根据您使用应用程序的哪个部分将不同的数据放入不同的工作表中。

我编写了一个脚本,该脚本从一张表(源)中提取所有数据,并将仅某些列放入第二张表(目标)中。然后它会从源中删除所有行,并从目标中删除所有空白行。

我遇到的问题是从目标中删除空白行。通常,目的地的底部会有空行,而我拥有的代码只会删除包含数据的范围内的空行。所以我总是在底部留下空行。

然后,目标工作表将用作 forms2mobile 的数据源,这当然对空行不满意。

我找到了 getMaxRows() 类,但我不确定如何实现它。如果有人能提出任何建议,那就太好了。

干杯 保罗

    function NEW_copyColumnNumbers( ) {
    var spreadsheet_source = SpreadsheetApp.openById('1a89ZIUcy-8168D1damCV3Q9Ix0arQn9jGS6pgp');
    var spreadsheet_target = SpreadsheetApp.openById('1GQiLt9utSH_6CV__oJwmcLOkI4E9iNIRPWU7Xr');
    var range_input = spreadsheet_source.getRange("A2:CC407");
    var range_output = spreadsheet_target.getRange("A"+(spreadsheet_target.getLastRow()+1));
    var keep_columns = [66,66,10,11,12,13,14,23,26,31,69,71,74,75,80];

    copyColumnNumbers(range_input, range_output, keep_columns);
    clearEmptyRows();
    clearSourceData();
}
function copyColumnNumbers( range_input, range_output, columns_keep_num ) {
    // Create an array of arrays containing the values in the input range.
    var range_values = range_input.getValues();    
    // Loop through each inner array.
    for ( var i = 0, row_count = range_values.length;  i < row_count; i++ ) {
        // Loop through the indices to keep and use these indices to 
       // select values from the inner array.
        for ( j = 0, col_keep_count = columns_keep_num.length; j < col_keep_count; j++ ) {
              // Capture the value to keep
              var keep_val = range_values[i][columns_keep_num[j]];
              // Write the value to the output using the offset method of the output range argument.
              range_output.offset(i,j).setValue(keep_val);
        }
    }
}
function clearEmptyRows() {
  var ss = SpreadsheetApp.openById('1GQiLt9utSH_6CV__oJwmcLOkI4E9iNIRPWU7Xr');
  var s = ss.getActiveSheet();
  var values = s.getDataRange().getValues();
  nextLine: for( var i = values.length-1; i >=0; i-- ) {
    for( var j = 0; j < values[i].length; j++ )
      if( values[i][j] != "" )
        continue nextLine;
    s.deleteRow(i+1);
  }
  //I iterate it backwards on purpose, so I do not have to calculate the indexes after a removal
}
function clearSourceData() {
  var ss = SpreadsheetApp.openById('1a89ZIUcy-8168D1damCV3Q9Ix0arQn9jGS6pgp');
  var s = ss.getActiveSheet();
  var data = s.getDataRange().getValues();
  for(var n =data.length+1 ; n<0 ;  n--){
    if(data[n][0]!=''){n++;break}
  }
  s.deleteRows(2, (s.getLastRow()-1));
}

【问题讨论】:

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


    【解决方案1】:

    这就是它的工作原理:

    function removeEmptyRows(){
      var sh = SpreadsheetApp.getActiveSheet();
      var maxRows = sh.getMaxRows(); 
      var lastRow = sh.getLastRow();
      sh.deleteRows(lastRow+1, maxRows-lastRow);
    }
    

    注意:如果需要,您可以使用 getMaxColumn()getLastColumn()deleteColumns(number, howMany) 以相同的方式处理列

    编辑

    顺便说一句,这也是删除电子表格中空行的另一种方法...如果将两者结合起来,它将完全“清理”您的工作表!

    function deleteEmptyRows(){ 
      var sh = SpreadsheetApp.getActiveSheet();
      var data = sh.getDataRange().getValues();
      var targetData = new Array();
      for(n=0;n<data.length;++n){
        if(data[n].join().replace(/,/g,'')!=''){ targetData.push(data[n])};
        Logger.log(data[n].join().replace(/,/g,''))
      }
      sh.getDataRange().clear();
      sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);
    }
    

    Demo sheet in view only - make a copy to use

    【讨论】:

    • 感谢 Serge,我将 removeEmptyRows() 合并到我自己的脚本中,它就像一个魅力。我也试过你的演示表,它也很有效。但是,当我将整个示例脚本复制到工作表时,它在 sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData); 处失败。我正在使用新版本的 GSheet,我注意到您的 GSheet 是旧版本。 'getRange()' 是不是只能在旧 GSheets 中使用?
    • 根本没有...您可能会收到此错误,因为 targetData 为空且它的长度=0,这不是一个有效值...。添加一个条件以仅在 targetRange.length >0 时执行 getRange .
    【解决方案2】:

    在 Google 表格中删除EmptyRows 和 removeEmptyColumns 的脚本。它将前面提到的所有 Serge 和 apptailor 放在一起。这是sample sheet with the script included File > Make a copy... 以编辑工作表的副本。还有video that shows you how to use this sheet

    //Remove All Empty Columns in the Entire Workbook
    function removeEmptyColumns() {
    var ss = SpreadsheetApp.getActive();
    var allsheets = ss.getSheets();
    for (var s in allsheets){
    var sheet=allsheets[s]
    var maxColumns = sheet.getMaxColumns(); 
    var lastColumn = sheet.getLastColumn();
    if (maxColumns-lastColumn != 0){
          sheet.deleteColumns(lastColumn+1, maxColumns-lastColumn);
          }
      }
    }
    
    //Remove All Empty Rows in the Entire Workbook
    function removeEmptyRows() {
    var ss = SpreadsheetApp.getActive();
    var allsheets = ss.getSheets();
    for (var s in allsheets){
    var sheet=allsheets[s]
    var maxRows = sheet.getMaxRows(); 
    var lastRow = sheet.getLastRow();
    if (maxRows-lastRow != 0){
          sheet.deleteRows(lastRow+1, maxRows-lastRow);
          }
      }
    }
    

    【讨论】:

    • 很好,只是一个快速的建议。这些函数将尝试删除空工作表中的所有行/列,这是您无法做到的。 var lastRow = sheet.getLastRow() || 1个;和 var lastColumn = sheet.getLastColumn() || 1个;将确保至少 1 列/行并防止错误。
    【解决方案3】:

    删除所有空行(自下而上)

    之前

    之后

    function isEmptyRow(row){
      for (var columnIndex = 0; columnIndex < row.length; columnIndex++){
        var cell = row[columnIndex];
        if (cell){
          return false;
        }
      }
      return true;
    }
    
    function removeEmptyLines(sheet){
      var lastRowIndex = sheet.getLastRow();
      var lastColumnIndex = sheet.getLastColumn();
      var maxRowIndex = sheet.getMaxRows(); 
      var range = sheet.getRange(1, 1, lastRowIndex, lastColumnIndex);
      var data = range.getValues();
      sheet.deleteRows(lastRowIndex+1, maxRowIndex-lastRowIndex);
    
      for (var rowIndex = data.length - 1; rowIndex >= 0; rowIndex--){
        var row = data[rowIndex];
    
        if (isEmptyRow(row)){
          sheet.deleteRow(rowIndex + 1);
        }
      }
    
    }
    
    
    function removeEmptyLinesFromAllSheets(){
      SpreadsheetApp.getActive().getSheets().forEach(removeEmptyLines);
    }
    

    只删除数据上下的空行

    之前

    之后

    function isEmptyRow(row){
      for (var columnIndex = 0; columnIndex < row.length; columnIndex++){
        var cell = row[columnIndex];
        if (cell){
          return false;
        }
      }
      return true;
    }
    
    function getFirstNonBlankRowIndex(data){
      for (var rowIndex = 0; rowIndex < data.length; rowIndex++){
        var row = data[rowIndex];
    
        if (!isEmptyRow(row)){
          return rowIndex;
        }
      }
      return 0;
    }
    
    function removePaddedEmptyLines(sheet){
      var lastRowIndex = sheet.getLastRow();
      var lastColumnIndex = sheet.getLastColumn();
      var maxRowIndex = sheet.getMaxRows(); 
      var range = sheet.getRange(1, 1, lastRowIndex, lastColumnIndex);
      var data = range.getValues();
      var firstRowIndex = getFirstNonBlankRowIndex(data);  
      sheet.deleteRows(lastRowIndex+1, maxRowIndex-lastRowIndex);
      sheet.deleteRows(1, firstRowIndex);
    }
    
    
    function removePaddedEmptyLinesFromAllSheets(){
      SpreadsheetApp.getActive().getSheets().forEach(removePaddedEmptyLines);
    }
    

    【讨论】:

    • 如果最后一行为空,这将不起作用。我修正了你的脚本,但由于有字符限制,cmets 不允许我发布我的更正
    【解决方案4】:

    简单说明一下,我添加了这个“if”语句,以防止 Serge insas 的代码在您尝试删除空行时在没有空的底行时引发错误。

    把这个 if 放在最后一行函数 removeEmptyRows() 和它 不会抛出错误:

      if (maxRows-lastRow != 0){
        sh.deleteRows(lastRow+1, maxRows-lastRow);
        }
    

    【讨论】:

      【解决方案5】:

      这段代码我试过了,效果不错,你可以看看试试:

      function DeleteBlankRows(){
          var sh = SpreadsheetApp.getActiveSheet();
          var maxRows = sh.getMaxRows();
          var lastRow = sh.getLastRow();
          for (var Raw = 1; Raw < sh.getLastRow() ; Raw++)
          {
              if( sh.getRange('A'+Raw).getValue() == '')
              {
                  sh.deleteRow(Raw) //deleteRows(lastRow+1, maxRows-lastRow);
              }
          }  
      

      【讨论】:

        【解决方案6】:

        这对我来说非常有效。

        function removeEmptyRows(){
              var spreadsheet = SpreadsheetApp.openById("IDOFYOURSPREADSHEETFOUNDINURL");
              var sh = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
              var maxRows = sh.getMaxRows(); 
              var lastRow = sh.getLastRow();
              sh.deleteRows(lastRow+1, maxRows-lastRow);
            }
        

        【讨论】:

          【解决方案7】:

          此版本允许您指定不想删除的最上面的行,并在 ignoreAfterCol 之后忽略列,以防您在查找空白时不希望考虑某些列:

          function removeEmptyLines(sheet,ignoreFirstRows,ignoreAfterCol){
            sheet=ss.getSheetByName('Sheet12')
            //get data and boundaries
            var allData = sheet.getRange(1,1,sheet.getMaxRows(),ignoreAfterCol).getValues();
            var sheetLength = allData.length;
            while(allData[allData.length-1].toString().replace(/,/g,'')=='') allData.pop();
            var lastPopulatedRow = allData.length;
          
            //delete empty rows from end
            var rowsToDeleteFromEnd = sheetLength - lastPopulatedRow; 
            if(rowsToDeleteFromEnd > 0) sheet.deleteRows(lastPopulatedRow+1,rowsToDeleteFromEnd);
          
            //iterate through rows and delete blanks one by one
            for(var i=lastPopulatedRow-1; i>ignoreFirstRows; i--){
              if(allData[i].toString().replace(/,/g,'')=='') sheet.deleteRow(i+1);
            }
          }
          

          【讨论】:

            【解决方案8】:

            这将有助于准确删除您想要的内容: 加分项:

            • 您可以检查任意多的列来确定某行是否为空

            • 这也会删除包含公式的空白行

            • 提高性能:此脚本根据空行的位置直接删除空行,而无需遍历所有行。

              function deleteBlankRows(start_row=4) {
              var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
              
              //temporarily insert last column to avoid affecting existing data
              sheet.insertColumnsAfter(sheet.getMaxColumns(),1);
              var lastRow = findLastRow();
              var lastCol = sheet.getMaxColumns()
              var temp_col = sheet.getRange(start_row,lastCol,lastRow-start_row,1)
              
              //insert formula to show row position if any row is blank from column A to N (can adjust if needed)
              sheet.getRange(start_row,lastCol).setFormula('=if(countif(A'+start_row+':N'+start_row+',"*?")=0,row(),0)').copyTo(temp_col)
              
              //get a reversed list of rows position excluded non-empty rows
              var rowsPosition = temp_col.getValues().filter(x => x != 0).reverse()
              
              //delete empty rows from bottom to top
              rowsPosition.forEach(function(rowPosition){
                if (Number(rowPosition) > start_row) {
                  sheet.deleteRow(Number(rowPosition))
                }
              })
              
              //finally, delete the temporary column
              sheet.deleteColumn(lastCol)
              }
              
              function findLastRow() {
               const sh = SpreadsheetApp.getActive().getActiveSheet();
               const data = sh.getRange("A:L").getValues();
               const mR = sh.getMaxRows();
               const indexes = [];
               data[0].forEach((_, ci) => {
                  let col = data.map(d => d[ci]);
                  let first_index = col.reverse().findIndex(r => r != '');
                  if (first_index != -1) {
                     let max_row = mR - first_index;
                     indexes.push(max_row);
                  }
               });
               last_row = indexes.length > 0 ? Math.max(...indexes) : 0;
              
               return last_row;
              

              }

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-03
              相关资源
              最近更新 更多