Proposed Script
function createReport() {
// Initilaize Sheets, Ranges, Values
let file = SpreadsheetApp.getActive();
let sheet1 = file.getSheetByName("Blad1");
let range1 = sheet1.getDataRange();
let values1 = range1.getValues();
let sheet2 = file.getSheetByName("Blad2");
let range2 = sheet2.getDataRange();
let values2 = range2.getValues();
// Deal with headers
let langs = values2[0];
values1.shift(); // to remove headers
// Creating array of sub arrays with info to paste into report
// In this format:
// [[Column to paste in, Input 1, Input 2, Input 3]]
let output = [];
values1.forEach((row, i) => {
let outputRow = [];
let whichCol = langs.findIndex((i) => i == row[3]) + 1;
outputRow.push(whichCol);
for (let i = 0; i < 3; i++) {
outputRow.push(row[i]);
}
output.push(outputRow);
});
// With output array, pasting into report
output.forEach((entry) => {
let col = entry.shift();
// Find where the next free slot is in column
let occupiedRange = sheet2
.getRange(1, col)
.getDataRegion(SpreadsheetApp.Dimension.ROWS)
let height = occupiedRange.getHeight();
// Transposing array
set = entry.map((val) => [val]);
// Inserting Values to Report
let outRange = sheet2.getRange(height + 1, col, 3, 1);
outRange.setValues(set);
});
}
Source Data in Blad1
Destination Template and script in action in Blad2
Explanation
You'll notice its quite a bit longer than your script! What you are trying to do is deceptively complex, which is why I hesitated to answer fully as this script is so far removed from what you initially posted that it almost seemed like it was a "give me the code" question. Though you are new on the site and I had already written out most of the code, so what the hell. In future please try to include more info in your original question, your attempts and research. I have tried to keep it an concise as possible, but there may be certain syntax that you haven't come across, like forEach
and map
.
The script first gets the data with getValues
that returns 2D arrays of the values.
I take out the headers on the source data, and use the headers on the target data to find the column index where the source data will end up. So ENG
is index 1, and X
index 2 etc.
For each row in the source data it transforms it into an intermediary array (which is not necessary, but I think its clearer to understand each step). The intermediary array is composed of sub arrays representing each "set". Each sub array has this format [Column_Index, Input1, Input2, Input3]
.
Once this has been build, each of those sub arrays can be gone through to insert them into the output sheet, which I have called the "Report".
Within this process is the need to get the first unoccupied row of the target column. So if ENG
already has 3 sets that have been filled in, the script needs to know where the next set starts. It does this by using getDataRegion(SpreadsheetApp.Dimension.ROWS)
then getHeight() + 1
to find the starting row for the set to be inserted.
Also within this final process is the need to transform the array from this format:
[1,2,3]
Which Apps Script understands as a row, to a column, which would be this:
[[1],[2],[3]]
which was done with map
.
I encourage you to use Logger.log
to log a bunch of the values and inspect the output so that you can understand the script and adapt it to your needs. I have tried to name everything in a "friendly" manner.
References
A2:C4
toF2:H4
. Can you provide an example of what the output would actually look like? Have you used Apps Script or JavaScript before? Do you know how to use conditional statements? – iansedano