----- ПРЕДПОСЫЛКИ ----- В скрипте 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
}
}