Отфильтруйте один массив, используя второй массив, и отобразите результаты в электронной таблице. - PullRequest
0 голосов
/ 06 октября 2018

----- ПРЕДПОСЫЛКИ ----- В скрипте Google Sheets / Apps я пытаюсь переместить некоторые данные транзакции с одного листа и упорядочить их на другом листе со строками промежуточных итогов для каждой учетной записи клиента (называемой "Units ") с общим итогом внизу.

У меня есть транзакции, организованные в массив объектов как ключ: пары значений (" транзакции ", ключи - заголовки, некоторые значения - строки, другие - числа), и у меня есть блоки во втором массиве, называемые «unitList».Я хочу выполнить итерацию по каждому элементу в массиве unitList и перетащить каждую транзакцию с соответствующим блоком на мой «targetSheet», а затем добавить строку промежуточных итогов для каждого блока.

----- ОБНОВЛЕНИЕ 10/7/ 2018 15:49 EST -----

Спасибо всем за ваш вклад - я воспользовался вашим советом и отказался от библиотеки, которую использовал, и вместо этого нашел лучшие функции getRowsData и appendRowsData, которые я поместил непосредственно в мой кодпроект. Это исправило проблему фильтра массива (проверено журналированием filterResults), НО, теперь, когда я вызываю appendRowsData (), я получаю эту ошибку:

Координаты или размеры диапазонаявляются недействительными(строка 73, файл «Просмотр транзакций»)

Строка 73 - строка ниже, в функции appendRowsData.Любая помощь в том, как это исправить, будет принята с благодарностью.

var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);

Вот мой проект полностью:

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

  // Label each sheet
  var dashboard = ss.getSheetByName('Dashboard');
  var unitsSheet = ss.getSheetByName('Unit Ref Table');
  var transactionsSheet = ss.getSheetByName('Transactions Ref Sheet');
  var targetSheet = ss.getSheetByName('Target Sheet');

  // Returns true if the cell where cellData was read from is empty.
  // Arguments:
  //   - cellData: string
  function isCellEmpty(cellData) {
    return typeof(cellData) == "string" && cellData == "";
  }

  // Define function that converts arrays into JSON
  //   For every row of data in data, generates an object that contains the data.
  //   Names of object fields are defined in keys.
  // Arguments:
  //   - data: JavaScript 2d array
  //   - keys: Array of Strings that define the property names for the objects to create  
  function getObjects(data, keys) {
    var objects = [];
    for (var i = 0; i < data.length; ++i) {
      var object = {};
      var hasData = false;
      for (var j = 0; j < data[i].length; ++j) {
        var cellData = data[i][j];
        if (isCellEmpty(cellData)) {
          continue;
        }
        object[keys[j]] = cellData;
        hasData = true;
      }
      if (hasData) {
        objects.push(object);
      }
    }
    return objects;
  }

  // Define function that pulls spreadsheet data into arrays, then converts to JSON using getObjects function
  function getRowsData(sheet) {    
    var headersRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
    var headers = headersRange.getValues()[0];
    var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getLastRow(), sheet.getLastColumn());
    return getObjects(dataRange.getValues(), headers);
  }

  // Define function appendRowsData that uses getLastRow to fill in one row of data per object defined in the objects array.
  //   For every Column, it checks if data objects define a value for it.
  // Arguments:
  //   - sheet: the sheet object where the data will be written
  //   - objects: an array of objects, each of which contains data for a row

  function appendRowsData(sheet, objects) {
    var headersRange = sheet.getRange(7, 1, 1, 9);
    var firstDataRowIndex = sheet.getLastRow() + 1;
    var headers = headersRange.getValues()[0];
    var data = [];
    for (var i = 0; i < objects.length; ++i) {
      var values = []
      for (j = 0; j < headers.length; ++j) {
        var header = headers[j];
        values.push(header.length > 0 && objects[i][header] ? objects[i][header] : "");
      }
      data.push(values);
    }
    var destinationRange = sheet.getRange(firstDataRowIndex, 1, objects.length, 9);
    destinationRange.setValues(data);
  }

  // Call getRowsData on transactions sheet
  var transactions = getRowsData(transactionsSheet);

  // Get array of units
  var unitList = unitsSheet.getRange("B2:B").getValues();

  // Iterate through the unitList and pull all transactions with matching unit into the target sheet
  for (var i=0; i < unitList.length; i++) {
    var subTotal = 0;
    var grandTotal = 0;
    var filterResults = transactions.filter(function(x) {
      return x['Unit'] == unitList[i];      
    })

    Logger.log(filterResults); // This brings the correct results!  

    // Display matching transactions
    appendRowsData(targetSheet, filterResults);

    // Grand total at the bottom when i=units.length

  }
}
...