问题
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