Google App脚本:查找最后一个空白行

时间:2018-12-10 20:28:47

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

我正在尝试完成一个脚本,该脚本会自动隐藏所有“空白”行 除了一个(用于输入新数据)。 实际上,除了我的其中一个名为“ Roster”的页面之外,它已经可以完全正常工作。

如果您想在上下文中查看我的工作表,则这是可编辑的版本: https://docs.google.com/spreadsheets/d/126hhh5su-WgHQQ_RmI8yvlrwITPeEIAegopHAooGaK0/edit?usp=sharing

“ Roster”的问题是我的脚本检查空白行,但没有忽略计算结果为空白的公式。

这是我的“ hider”,对于带有扩展至类似内容底部的公式的工作表都很好 “ =输出!c1,c2,c3等...

function HideRows(SheetName, FirstCol, LastCol, CopyOn) {
  // important variables
  var s = SpreadsheetApp.getActiveSpreadsheet(); // Calls Spreadsheet API
  // set's location for the code to work
  var Width = LastCol - FirstCol;
  // Sheetname called by function
  var sheet = s.getSheetByName(SheetName);
  // Gets total number of Rows and Cols
  var maxRow = sheet.getMaxRows();
  // Gets total Number of Rows and Cols That aren't BLANK
  var LastRow = sheet.getDataRange().getLastRow(); // Gets the total number of Rows with data
  var LastCol = sheet.getDataRange().getLastColumn(); // Gets the total number of Cols with data
  // Gets the Number of blank rows By subtracting the amount "BLANK" Rows from "ALL" Rows
  var numBlank = maxRow - LastRow; // Gets the difference between the Max and Last Row
  var blankRow = maxRow + 1 - numBlank;
  var numRows = numBlank - 1;
  var Blank = blankRow - LastRow;
  var On = CopyOn;
  // Checks For AutoFill Variable
  if (On) {
    CopyPaste(numBlank, LastRow, numRows, sheet, Width, Blank);
  } else {
    NoCopyPaste(sheet, LastRow, maxRow, numRows);
  }
}

function NoCopyPaste(sheet, LastRow, maxRow, numRows) {
  if (sheet.isRowHiddenByUser(LastRow)) {
    sheet.hideRows(maxRow + 1 - numRows, numRows);
    Logger.log(sheet.isRowHiddenByUser(LastRow));
  } else {
    sheet.showRows(LastRow + 1);
    sheet.hideRows(maxRow + 1 - numRows, numRows);
    Logger.log(sheet.isRowHiddenByUser(LastRow));
  }
}

function CopyPaste(numBlank, LastRow, numRows, sheet, Width, Blank) {
  if (numBlank < 1) {
    sheet.showRow(LastRow + 1);
    AutoFill(LastRow, FirstCol, Width);
  } else if (numBlank > 1) {
    sheet.hideRows(maxRow - numRows, numRows);
  } else if (numBlank === 1) {
    sheet.getRange(1, 1);
  }
}

function AutoFill(LastRow, FirstCol, Width) {
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.getRange("A1").offset(LastRow - 3, FirstCol, 1, Width).activate();
  var destinationRange = spreadsheet.getActiveRange().offset(0, 0, 3);
  spreadsheet.getActiveRange().autoFill(destinationRange, SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
  spreadsheet.getCurrentCell().offset(1, 0, 2, 4).activate();
}
HideRows("output", 0, 10, false);

现在我进行了一些研究,并从吉恩那里找到了一个很棒的解决方案    皮埃尔:    https://productforums.google.com/forum/#!topic/docs/-Xr6dud_Nak

它非常适合于名册,并且可以正确标识工作表中的最后一行,但是,它在工作表中查找未定义的工作表,该工作表仅具有文本输出,并且末尾只有一个空单元格(无公式)。

我正在尝试编辑该答案中找到的“ for”语句,以使其适用于两种类型的工作表。

var SheetName = "output";
        function getData() {
        var ss = SpreadsheetApp.getActiveSpreadsheet();
        var sh = ss.getSheetByName(SheetName);
        var data = sh.getDataRange().getValues();
      
      var lastRow = getLastRow(data);
        Logger.log("Last Row is: " + lastRow);
        Logger.log(data);
      }
     
    function getLastRow(data) {
      for (var i = 0; i < data.length; i++) {
           var len = data[i].toString().replace(/,/g, "").length;
        Logger.log([i])
        if ( len === undefined){
           var lastRow = i + 1;
             break;
        } else if (len < 1) { 
             var lastRow = i;  
           }  
      }
      return lastRow;
      Logger.log(lastRow)
    }

这是我的最佳尝试,但仍然无法正常工作  对于没有公式的工作表。 任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我认为您正在为尝试找到一种编程方法来应用到具有多种不同格式且表格之间不一致的电子表格而烦恼。

电子表格还遭受包含冗余数据的困扰,因此可以更好地花费时间对数据进行规范化(构建和利用主文件/数据列表)并使用该数据链接工作表。例如,“ Roster”几乎可以完全包含在下拉列表中。

我采用了构建适用于每张纸的简单例程的方法,或者可以使用so_hide_Various函数进行组合以一次性处理所有纸的方法。

function so_hide_Various() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheetstuff = new Array;
    sheetstuff = [{
            sheetName: "output"
        },
        {
            sheetName: "Roster"
        }
    ];
    // Logger.log("sheetstuff rows: "+sheetstuff.length);// DEBUG
    for (var z = 0; z < sheetstuff.length; z++) {
        var sheet = ss.getSheetByName(sheetstuff[z].sheetName);
        switch (sheetstuff[z].sheetName) {
            case "output": // output style
                so_hide_Output();
                break;
            case "Roster": // Roster style
                so_hide_Roster();
                break;
        }
    }
}

function so_hide_Output() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var SheetName = "output";
    var sh = ss.getSheetByName(SheetName);
    var lrow = sh.getLastRow();
    var maxrow = sh.getMaxRows();
    //Logger.log("the last row is "+lrow+", and the max row is "+maxrow); // DEBUG
    var starthide = lrow + 2;
    sh.showRows(1, maxrow);
    sh.hideRows(starthide, maxrow - starthide + 1);
}

function so_hide_Roster() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var SheetName = "Roster";
    var sheet = ss.getSheetByName(SheetName);
    var Avals = sheet.getRange("B3:B").getValues();
    var Alast = Avals.filter(String).length;
    var maxrow = sheet.getMaxRows();
    var starthide = (Alast + 2 + 1 + 1); // add the two rows because of start on row 3 plus one blank row plus one for first hidden row
    //Logger.log("Alast = "+Alast+", starthide:= "+starthide+", and the max row is "+maxrow);//DEBUG
    var rowstodelete = maxrow - starthide + 1;
    sheet.showRows(1, maxrow);
    sheet.hideRows(starthide, rowstodelete);
}