Как фильтровать данные в столбцах с помощью редактора сценариев приложения Google - PullRequest
4 голосов
/ 09 марта 2020

У меня возникают некоторые проблемы, связанные с фильтрацией данных в столбцах с помощью редактора сценариев приложения Google.

enter image description here

Я могу установить Отфильтруйте столбцы с помощью скрипта приложения Google, как показано на скриншоте выше. но проблема в том, когда я пытаюсь получить отфильтрованные данные. он возвращает ряд чисел вместо фактических данных, как показано ниже:

[20-03-09 18:19:48:395 IST] [1,2,4,5,6,8,9,10,11,12,13,14,15,19,20,21,22,23,24,26,27,28,29,30]

Чтобы установить фильтр:

function setFilter() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();

  var filterSettings = {};

  // The range of data on which you want to apply the filter.
  // optional arguments: startRowIndex, startColumnIndex, endRowIndex, endColumnIndex
  filterSettings.range = {
    sheetId: ss.getActiveSheet().getSheetId()
  };

  // Criteria for showing/hiding rows in a filter
  // https://developers.google.com/sheets/api/reference/rest/v4/FilterCriteria
  filterSettings.criteria = {};
  var columnIndex = 2;
  filterSettings['criteria'][columnIndex] = {
    'hiddenValues': ["England", "France"]
  };

  var request = {
    "setBasicFilter": {
      "filter": filterSettings
    }
  };
  Sheets.Spreadsheets.batchUpdate({'requests': [request]}, ss.getId());
}

Чтобы получить отфильтрованные данные:

function getFilteredRows() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ssId = ss.getId();
  var sheetId = ss.getActiveSheet().getSheetId();
  let data = getIndexesOfFilteredRows(ssId,sheetId);
  Logger.log(JSON.stringify(data));
}

function getIndexesOfFilteredRows(ssId, sheetId) {
  var hiddenRows = [];

  // limit what's returned from the API
  var fields = "sheets(data(rowMetadata(hiddenByFilter)),properties/sheetId)";
  var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;  
  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;
} 

Как установить фильтр в столбцах и получить отфильтрованные данные с помощью скрипта приложения Google.
Пожалуйста, помогите мне с этим.

1 Ответ

2 голосов
/ 10 марта 2020
  • В вашем случае скрипт для фильтрации уже сработал. Вам нужен скрипт для извлечения значений из отфильтрованного листа в электронной таблице.
  • Вы хотите добиться этого с помощью API Sheets со скриптом Google Apps.

Если мое понимание верно, как насчет этой модификации? Пожалуйста, подумайте об этом как об одном из нескольких возможных ответов.

В вашем случае, функция getIndexesOfFilteredRows изменена. Используя hiddenByFilter, скрытые строки и показанные строки извлекаются как объект.

Модифицированный скрипт:

function getIndexesOfFilteredRows(ssId, sheetId) {
  var object = {hiddenRows: [], hiddenRowValues: [], shownRows: [], shownRowValues: []};

  // limit what's returned from the API
  var fields = "sheets(data,properties/sheetId)";
  var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;  
  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++) {
        var r = [];
        if (data[0].rowData[j] && Array.isArray(data[0].rowData[j].values)) {
          r = data[0].rowData[j].values.map(function(e) {
            var temp = "";
            if (e.hasOwnProperty("userEnteredValue")) {
              if (e.userEnteredValue.hasOwnProperty("numberValue")) {
                temp = e.userEnteredValue.numberValue;
              } else if (e.userEnteredValue.hasOwnProperty("stringValue")) {
                temp = e.userEnteredValue.stringValue;
              }
            }
            return temp;
          });
        }
        if (r.length > 0) {
          if (rows[j].hiddenByFilter) {
            object.hiddenRows.push(j);
            object.hiddenRowValues.push(r);
          } else {
            object.shownRows.push(j);
            object.shownRowValues.push(r);
          }
        }
      }
    }
  }
  return object;
}

Результат:

Когда вышеуказанный скрипт запускается для на фильтрованном листе возвращается следующий объект, который имеет скрытые номера строк, скрытые значения строк, показанные номера строк и показанные значения строк.

{
    "hiddenRows":[0,1],
    "hiddenRowValues":[["a1","b1","c1"],["a2","b2","c2"]],
    "shownRows":[2,3],
    "shownRowValues":[["a3","b3","c3"],["a4","b4","c4"]]
}

Ссылка:

Если я неправильно понял ваш вопрос, и это не то направление, в котором вы хотите, я приношу свои извинения.

Добавлено:

Как насчет этого примера сценария? В этом примере сценария значения, отфильтрованные с помощью filterValues, могут быть получены как объект. В этом случае результат совпадает с вашим setFilter() и измененным getIndexesOfFilteredRows(). Но фильтр basi c не используется. Поэтому, пожалуйста, будьте осторожны с этим.

function myFunction() {
  var filterValues = ["England", "France"]; // Please set the filter values.
  var column = 3; // In this case, it's the column "C". Please set the column number.
  var sheetName = "Sheet1";  // Please set the sheet name.

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetName);
  var values = sheet.getDataRange().getValues();
  var object = values.reduce(function(o, e, i) {
    if (filterValues.indexOf(e[column - 1]) > -1) {
      o.hiddenRows.push(i + 1);
      o.hiddenRowValues.push(e);
    } else {
      o.shownRows.push(i + 1);
      o.shownRowValues.push(e);
    }
    return o;
  }, {hiddenRows: [], hiddenRowValues: [], shownRows: [], shownRowValues: []});

  Logger.log(object)
}
  • Если вы хотите получить только отфильтрованные значения, этот сценарий может подойти.
  • В этом случае сценарий может работать с и без V8. Но когда V8 включен, скорость l oop будет быстрой. Ссылка
...