I've been trying to find out why, but not knowing for loop enough doesn't let know why this is happening.
I'm doing the following:
getvalues()It's giving me the correct rows where each category found in the data, but when I psh that value into an array, it's pushing one more than it should, resulting in an array bigger than the sheet values.
const categories = catSubSheet.getRange(2, 1, catSubSheet.getLastRow(), 3).getValues();
const subCategories1 = categories.filter(e => e[1] != '').map(function (e) { return e[1] });
const sheetData = sheet.getRange(5, 1, sheet.getLastRow(), 15).getValues();
var sub1Array = [];
var subCategory1 = '';
for (let n = 0; n < subCategories1.length; n++) {
let subs1ToIgnore = [];
subCategory1 = subCategories1[n];
//PUSHES SUBCATEGORIES 1 TO IGNORE IN THE FOLLOWING ITERATION
for (let a = 0; a < subCategories1.length; a++) {
if (subCategories1[a] != subCategory1) {
subs1ToIgnore.push(subCategories1[a])
}
}
let found;
for (let n = 0; n < sheetData.length; n++) {
const rowData = sheetData[n][0]
rowData.toString().trim();
if (rowData !== '' && rowData === subCategory1) {
found = true
startRowsSub1 = n + 5
}
if (found) {
sub1Array.push([subCategory1])
}
if (subs1ToIgnore.indexOf(rowData) > - 1) {
found = false
}
}
}
The data starts in row 5.
Appreciate any help.
Make sure to apply offsets when doing getRange especially when dealing with data not starting at 1st row.
Since your script is pretty clunky, I have overhauled it. See the answer below.
//THIS FUNCTION FORMATS CELL BACKGROUND COLORS AND SPREADS THE FORMULAS FROM ROW 4 (WHICH IS HIDDEN) THROUGH THE SHEET
function formatBOQcells() {
const SS = SpreadsheetApp.getActiveSpreadsheet();
const sheet = SS.getSheetByName('Test')
const catSubSheet = SS.getSheetByName('Categories and Subcategories')
const categories = catSubSheet.getRange(2, 1, catSubSheet.getLastRow() - 1, 3).getValues();
const subCategories1 = categories.filter(e => e[1]).map(function (e) { return e[1] });
// get ColA, transform to 1D array and remove blank cells
const sheetData = sheet.getRange(5, 1, sheet.getLastRow() - 4, 1).getValues().flat().filter(String);
// this will store the current subcategory
var currSubCategory = [''];
// for each sheetData row
const output = sheetData.map(item => {
// check if description a subcategory
if(subCategories1.includes(item)) {
// if subcategory, save it as current subcategory
currSubCategory = [item];
// return its value
return currSubCategory;
}
// if item is this row, write nothing
if(item == 'Sub Total for Pipework') {
return [''];
}
// if item is not a subcategory, assign the current subcategory
return currSubCategory;
});
sheet.getRange(5, 3, output.length, output[0].length).setValues(output);
}