is it possible to know the rows result of a filter in a Google Spreadsheet?

好久不见. 提交于 2020-01-07 03:29:22

问题


I want to know the rows result of a filter in Google App Script but I dont achieve obtain them, I always obtain all the rows of the selection or the sheet. I've investigated and it seems that it is impossible with this API. Do you know if it is true or if exist another way to obtain these rows?. Thx

function docReport() {
  try {
    splashScreen("Generando informe...");    
    var activeSheet = SpreadsheetApp.getActiveSheet();    
    var numberOfColumns = activeSheet.getLastColumn();
    var numberOfRows = activeSheet.getLastRow(); 
    var activeRow = activeSheet.getRange(1, 1, numberOfRows, numberOfColumns).getValues();

    var docReport =  DocumentApp.create(REPORT_FILE_NAME);
    var bodyReport = docReport.getBody();
    bodyReport.setAttributes(stylePage);

    for (var row = 1; row < numberOfRows; row++) {
      if (!isEmpty(activeRow[row], numberOfColumns)) {
        var image = UrlFetchApp.fetch(IMG_BBVA);
        /*var paragraph = bodyReport.appendParagraph("");
        paragraph.addPositionedImage(image).setHeight(100).setWidth(98);
        paragraph.appendText("\r\n");
        paragraph.setAttributes(styleTitle);*/

        //bodyReport.appendImage(image).setHeight(100).setWidth(98); //Incluimos la imagen de cabecera   

        bodyReport.appendParagraph("").addPositionedImage(image).setHeight(100).setWidth(98).setLayout(DocumentApp.PositionedLayout.WRAP_TEXT);
        bodyReport.appendParagraph("          SERVICIOS JURÍDICOS").setAttributes(styleTextBlue); 
        bodyReport.appendParagraph(DATE_REPORT + "\r\n\r\n").setAttributes(styleDate); 

        for (var col = 1; col < numberOfColumns; col++) { //Ignoramos la columna 1 que es el contador
          if (activeRow[row][col] != "") { //Si el valor es vacio no lo imprimimos
            if (activeRow[0][col] == "NORMA")
              bodyReport.appendParagraph(String(activeRow[row][col]).trim()).setAttributes(styleTextNorma); //Incluimos contenido
            else { 
              bodyReport.appendParagraph(activeRow[0][col] + ":").setAttributes(styleTitle); //Incluimos título
              bodyReport.appendParagraph(String(activeRow[row][col]).trim()).setAttributes(styleText); //Incluimos contenido
            }
            bodyReport.appendParagraph("");
          }
        }
        bodyReport.appendPageBreak(); 
      }
    } 
    bodyReport.appendPageBreak();     
    docReport.saveAndClose();
    MailApp.sendEmail(Session.getActiveUser().getEmail(), "Informe " + REPORT_FILE_NAME + " generado", 
                      'Se ha creado un nuevo informe "' + REPORT_FILE_NAME + '" en su unidad Google Drive: \n\r' + docReport.getUrl());   
    SpreadsheetApp.flush();
    SpreadsheetApp.getUi().alert('Se ha creado un nuevo informe "' + REPORT_FILE_NAME + '" en su unidad Google Drive \r\n');
  } catch(e) {
    Logger.log("ERROR in function createPdf \r\nMessage: " + e.message + "\r\nFile gs: " + e.fileName + "\r\nLine: " + e.lineNumber)
    Logger.log("\r\nUser: " + Session.getActiveUser().getEmail() + ", Date: " + Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd'_'HH:mm:ss"));
    MailApp.sendEmail(EMAIL_DEV, SUBJECT_MAIL, Logger.getLog());   
  } 
}

回答1:


No it isn't possible a Spreadsheet filter is a specific "view" that can't be retrieved in app script. Nevertheless it's possible to rebuild manually the filter view if you know the parameters of it. Use a getDataRange().getValues() that will retrieve all the data and then apply a filter function on this table.




回答2:


Finally I've be able achieve my goal but it is not an usual solution, but it works. Before process the sheet I select all the rows and I put background color, Google Spreadsheet only set the background color to the filtered rows. Then, I process all the sheet but I know the rows filtered because I ask about its background. I hope this solution likes and be useful for you. Thanks.

function docReport() {
  try {
    splashScreen("Generando informe...");    
    var activeSheet = SpreadsheetApp.getActiveSheet();    
    var numberOfColumns = activeSheet.getLastColumn();
    var numberOfRows = activeSheet.getLastRow(); 
    var activeRow, rowRange;
    var titleRow = activeSheet.getRange(1, 1, 1, numberOfColumns).getValues();

    //Set los fondos a otro color para identificar las líneas a las líneas que tienen filtro
    activeSheet.setActiveSelection("2:" + activeSheet.getLastRow()).setBackground("#fffff9"); 

    var docReport =  DocumentApp.create(REPORT_FILE_NAME);
    var bodyReport = docReport.getBody();
    bodyReport.setAttributes(stylePage);

    for (var row = 2; row <= numberOfRows; row++) { //Empieza en 2 ya que no incluyo la fila de los títulos
      rowRange = activeSheet.getRange(row, 1, 1, numberOfColumns);
      if (rowRange.getBackground() == "#fffff9") { //If it has #fffff9 background, it means that it is a filtered row
        activeSheet.setActiveSelection(row + ":" + row).setBackground("#ffffff"); //Volvemos a dejar los fondos en blanco
        activeRow = rowRange.getValues();
        if (!isEmpty(activeRow[0], numberOfColumns)) {
          var image = UrlFetchApp.fetch(IMG_BBVA);
          bodyReport.appendParagraph("").addPositionedImage(image).setHeight(100).setWidth(98).setLayout(DocumentApp.PositionedLayout.WRAP_TEXT);
          bodyReport.appendParagraph("          S.J.").setAttributes(styleTextBlue); 
          bodyReport.appendParagraph(DATE_REPORT + "\r\n\r\n").setAttributes(styleDate); 

          for (var col = 1; col < numberOfColumns; col++) { //Ignoramos la columna 1 que es el contador
            if (activeRow[0][col] != "") { //Si el valor es vacio no lo imprimimos
              if (col == COLUMN_NORMA)
                bodyReport.appendParagraph(String(activeRow[0][col]).trim()).setAttributes(styleTextNorma); //Incluimos contenido
              else { 
                bodyReport.appendParagraph(titleRow[0][col]).setAttributes(styleTitle); //Incluimos título
                bodyReport.appendParagraph(String(activeRow[0][col]).trim()).setAttributes(styleText); //Incluimos contenido
              }
              bodyReport.appendParagraph("");
            }
          }
          bodyReport.appendPageBreak(); 
        }
      }
    } 
    activeSheet.setActiveSelection("2:" + activeSheet.getLastRow()).setBackground("#ffffff"); //Volvemos a dejar los fondos en blanco menos primera fila
    bodyReport.appendPageBreak();     
    docReport.saveAndClose();
    MailApp.sendEmail(Session.getActiveUser().getEmail(), "Informe " + REPORT_FILE_NAME + " generado", 
                      'Se ha creado un nuevo informe "' + REPORT_FILE_NAME + '" en su unidad Google Drive: \n\r' + docReport.getUrl());   
    SpreadsheetApp.flush();
    SpreadsheetApp.getUi().alert('Se ha creado un nuevo informe "' + REPORT_FILE_NAME + '" en su unidad Google Drive \r\n');
  } catch(e) {
    Logger.log("ERROR in function createPdf \r\nMessage: " + e.message + "\r\nFile gs: " + e.fileName + "\r\nLine: " + e.lineNumber)
    Logger.log("\r\nUser: " + Session.getActiveUser().getEmail() + ", Date: " + Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd'_'HH:mm:ss"));
    MailApp.sendEmail(EMAIL_DEV, SUBJECT_MAIL, Logger.getLog());   
  } 
}



回答3:


There's a solution posted in Google Issue Tracker and endorsed by Google:

You can use the new Google Sheets advanced service to get the filtered rows, clear all filters,... See this blog post for more info: https://gsuite-developers.googleblog.com/2017/04/using-google-sheets-filters-in-add-ons.html

for (var i = 0; i < sheets.length; i++) {
    if (sheets[i].properties.sheetId == sheetId) {
      var data = sheets[i].data;
      var rows = data[0].rowMetadata;
      for (var j = 0; j < rows.length; j++) {
        if (rows[j].hiddenByFilter) hiddenRows.push(j);
      }
    }
  }
  return hiddenRows;
}



来源:https://stackoverflow.com/questions/42325829/is-it-possible-to-know-the-rows-result-of-a-filter-in-a-google-spreadsheet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!