Copy 2D array to another sheet - javascript

I want to copy the values of the cells from several 2D array, which are in the middle of the final sheet( generated by a functions, with the help of several sheet that contains data ) to another sheet that will give back this data after the execution of the funcions to avoid crushing the data, because i didnt found solution for my last questions .
Thanks for your help.

Not quite sure if this is what your after but I found this on the Google developers site:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheets()[0];
var destination = ss.getSheets()[1];
var range = source.getRange("B2:D4");
// This copies the data in B2:D4 in the source sheet to
// D4:F6 in the second sheet
range.copyValuesToRange(destination, 4, 6, 4, 6);
https://developers.google.com/apps-script/reference/spreadsheet/range#copyValuesToRange(Sheet,Integer,Integer,Integer,Integer)
Hope this helps.

I've put together a quick example that might help. The data in the example I want to find is '2b2' located in the second sheet of a four sheet spreadsheet. I want to copy the column it is in to the 4th sheet. It's not pretty but it does the job. :-)
function testCopy() {
//get the active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create an array of all the sheets in our spreadsheet
var sheets = ss.getSheets();
// Declare the destination sheet to copy the data to
var destination = sheets[3];
//create an index for the sheet that hold the data we want to copy
var targetSheet = 0;
//loop through each of the sheets to check for the data we are looking for
for (var i = 0; i < sheets.length -1; i++) {
// Create a 2D array that holds all of the data we want to test from the sheet
var rowData = sheets[i].getRange('A1:C3').getValues();
//Loop through each row of data in the 2D array
for (j = 0; j < rowData.length; j++) {
// Create an array of the cells in the row
var cells = rowData[j];
//loop through each of the cells
for (k = 0; k < cells.length; k++) {
// check to see if the cell has the data we are looking for and if so set the
// target sheet index to the current sheet
if (cells[k] == '2b2'){
targetSheet = i;
}
}
}
}
//set the range of the data we want copy for this example a single column
var copyRange = sheets[targetSheet].getRange('B1:B3');
// copy the data to the destination sheet into D4:D6
copyRange.copyValuesToRange(destination, 4, 4, 4, 6);
}
Don't quite know what has happened to the indentation. :-(

Related

Move a static range of data to another sheet while getting other fields into columns next to the destination (Google Sheets)

The challenge has been getting cell values from the document header together with a range underneath this header to Sheet2, having it as a table, so that later, I can filter, update and delete records via scripts.
So far, I got the below code copying what's within the range underneath the header:
function copyrange() {
var sourceSheet = 'NewItem';
var destinationSheet = 'DW';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var LastRowSource = sheet.getLastRow();
var LastColumnSource = sheet.getLastColumn();
var values = sheet.getRange(11,1,LastRowSource,LastColumnSource).getValues();
var csh = ss.getSheetByName(destinationSheet);
var data = [];
var j =[];
//var itemheader = [sheet.getRange("C4:4").getValues(),sheet.getRange("A3:3").getValues(),sheet.getRange("i3:3").getValues(),sheet.getRange("i4:4").getValues(),sheet.getRange("c5:5").getValues(),sheet.getRange("e5:e").getValues(),sheet.getRange("i5:5").getValues(),
// sheet.getRange("C7:7").getValues(),sheet.getRange("c8:8").getValues(),sheet.getRange("c9:9").getValues(),sheet.getRange("e7:7").getValues(),sheet.getRange("e8:8").getValues(),sheet.getRange("i7:7").getValues(),sheet.getRange("i8:8").getValues(),
// sheet.getRange("e9:9").getValues()];
for (var i = 1; i < values.length; i++) {
if ( values[i][0] != '') {
data.push(values[i]);
//sheet.deleteRow(i+1)
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,17,data.length,data[0].length).setValues(data);
Now, getting different cell values from the header into a row and copying it to Sheet2 as many times/rows as there is in the range copied by the above script seems impossible to me.
Here is a link to a practical example:
https://docs.google.com/spreadsheets/d/1GlD_VIOFHj7PGfCCnfVZqdZbE22aVoUw91BSCZecsRc/edit?usp=sharing
Thanks a lot for your help. Believe me, I've hit my head against the wall enough with this one before I turn to you guys!

How do I perform row call using Google App Script

I have done a bit of research on how I can perform a rowcall using google app script but have a little challenge and will appreciate any assitance on this.
So this code looks at the first column and gets the values to be used in renaming new tabs
function newSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var templateSheet = ss.getActiveSheet();
var sheet1 = ss.getSheetByName("main")
var getNames = sheet1.getRange("A2:A").getValues().filter(String).toString().split(",");
for (var i = 0; i < getNames.length; i++) {
var copy = ss.getSheetByName(getNames[i]);
if (copy) {
Logger.log("Sheet already exists");
} else {
templateSheet.copyTo(ss).setName(getNames[i]);
ss.setActiveSheet(ss.getSheetByName(getNames[i]));
ss.moveActiveSheet(ss.getNumSheets());
}
}
}
The sheet
What I would like to do and is becoming a challenge, is While creating a new tab with a name then, I would like to copy the entire row to the new tab/sheet. e.g for the sheet Levi only the raw with Levi Data be copied to the sheet.
At the moment my code copies the entire source sheet to the new tabs/sheets. I will really appreciate any help with this
Proposed solution:
Now you are using the main sheet as a template so when you use it with the function .copyTo you will copy the whole content.
You will have to get the whole row corresponding to the index of the given name.
Approach
You will need an extra filtering to get the correct row values you want to put in the new sheet.
I will filter the name column (column A) and get the index of the name in the loop.
(I am assuming you can have some gaps so the index of the for loop would not be enough).
Once i found the corresponding index i will need to increment it by one because row indexing starts from 1 in Google Spreadsheets.
Now i can easily get the row using the function .getRange(row, column, numRows, numColumns).
I am using the function .getLastColumn() to compute the numColumns parameter.
Now I can use the function .appendRow() to insert the row in the new sheet I just created with the .insertSheet() function.
Sample Code:
function newSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var templateSheet = ss.getActiveSheet();
var sheet1 = ss.getSheetByName("main")
var getNames = sheet1.getRange("A2:A").getValues().filter(String).toString().split(",");
for (var i = 0; i < getNames.length; i++) {
var copy = ss.getSheetByName(getNames[i]);
if (copy) {
Logger.log("Sheet already exists");
} else {
//The copyTo function will copy the entire sheet
//templateSheet.copyTo(ss).setName(getNames[i]);
var rowIndex = sheet1.getRange("A:A").getValues().flatMap(value => value[0]).indexOf(getNames[i]) + 1;
var rowValues = sheet1.getRange(rowIndex, 1, 1, sheet1.getLastColumn()).getValues();
ss.insertSheet(getNames[i]).appendRow(rowValues[0]);
ss.setActiveSheet(ss.getSheetByName(getNames[i]));
ss.moveActiveSheet(ss.getNumSheets());
}
}
}
Edit
In the case the names are repeated you will have to filter the column and extract the corresponding indexes.
First you will have to get a set for your getNames variable. (otherwise you will have repetitions).
var getNames = [...new Set(sheet1.getRange("A2:A").getValues().filter(String).toString().split(","))];
Then you will have to map the row indexes to the names in the column A.
Now you can filter by the getNames values and you will obtain the row indexes.
In the end you can append to the new sheet the rows at the corresponding indexes.
var rowIndexes = sheet1.getRange("A:A").getValues()
.map((value, index) => [value[0], (index + 1)])
.filter(value => value[0] === getNames[i]);
var namedSheet = ss.insertSheet(getNames[i]);
rowIndexes.map(index => {
var rowValues = sheet1.getRange(index[1], 1, 1, sheet1.getLastColumn()).getValues();
namedSheet.appendRow(rowValues[0]);
});
References:
Class Sheet

Comparing two columns, same row, for first value that doesn't match

I have two sheets, one is a mirror sheet, "Sheet2," that I use to store the values of the other sheet, "Sheet1." My goal is to have a function compare the two sheets for differences. The best way i could think of was by comparing column A from Sheet1 to column A from Sheet2. I found a few functions that compared 2 columns but it did it looking for values from one column and finding it in the other column. Or by returning all the values in those cells that had a matching value, regardless of what row it was in. But I don't want the values in the cells, necessarily. I want to find the first row where the two columns stop matching. I'm fairly new to Javascript so I still can't comprehend the whole for (var j = 0; j < range.length; j++) stuff.
But I'm sure I will need to know how to use it for this function I need. Here's what I tried using but instead of giving me row ranges, it gave me an array of values that were the same, if I changed it to if(lookup[i][0]!==range[j][0]){ it gave me all the possible combinations that weren't matching. This is from stackoverflow.com/questions/42044903
function findDifference() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s=ss.getSheetByName("Sheet1")
var lr=s.getLastRow()
var lookup = s.getRange(2,1,lr-1,2).getValues();
var s1=ss.getSheetByName("Sheet2")
var lr1=s1.getLastRow()
var range = s1.getRange(2,1,lr1-1,2).getValues();
var lookupRange = [];
for (var i = 0; i < lookup.length; i++) {
for (var j = 0; j < range.length; j++) {
var test=lookup[i][0]
if(lookup[i][0]!==range[j][0]){
lookupRange.push([range[j][0],range[j][1],lookup[i][0],lookup[i][1],]);
}}}
s1.getRange(10,1,lookupRange.length,4).setValues(lookupRange);
}
I feel like there's a very similar function for what I'm trying to do that already exists, but I can't seem to find it or come up with how it would work because I'm new and don't know all the tricks.
Something like:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s1=ss.getSheetByName("Sheet1")
var s2=ss.getSheetByName("Sheet2")
var ColumnA1 = s1.getRange('A:A').getValues()
var ColumnA2 = s2.getRange('A:A').getValues()
var Row = Function()
///Some function I can't think of using where
if(ColumnA1 + Row !== ColumnA2 + Row){
???.getRow()
}
The code that you had was "kinda' helpful but it did not solve your particular question. On the other hand, your if(ColumnA1 + Row !== ColumnA2 + Row){ wasn't really helpful either.
Regrettably you DO need to "comprehend the whole for (var j = 0; j < range.length; j++) stuff", though it isn't actually that complicated.
In the following answer, there are basically three elements.
setup sheet1, and get the data
setup sheet2, and get the data
loop through the rows and compare the value on a given line from one sheet to the other.
the for statement signifies the loop
i is simply a counter variable
i=0 means that the starting value is zero. In javascript arrays, zero always the first value set.
i < Sheet1Data.length signifies how many time the loop will run. In this case, it will run while i is less then the number of lines in the array. Remember, i starts with zero, so "less than" the totoal number of lines will be fine.
i++ means that each time the code loops, it increments i by one.. So, i starts with 0, then 1, 2, 3 and so on.
How to find the first row where the two columns stop matching
View the Logs (View > Logs).
You can see on line 32 and 38 of the code Logger.log statements. These record the line number and whether the line values in each sheet match.
function so56195933() {
// setup Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// setup Sheet1
var s1 = ss.getSheetByName("Sheet1")
var s1LastRow = s1.getLastRow();
//Logger.log("DEBUG: Sheet 1 Last row = "+s1LastRow);
var Sheet1DataRange = s1.getRange(1,1,s1LastRow);
var Sheet1Data = Sheet1DataRange.getValues();
//Logger.log("DEBUG: Sheet 1 data range = "+Sheet1DataRange.getA1Notation());
var Sheet1length = Sheet1Data.length;
//Logger.log("DEBUG: Sheet1 length = "+Sheet1length);
// setup Sheet2
var s2=ss.getSheetByName("Sheet2")
var s2LastRow=s2.getLastRow();
//Logger.log("DEBUG: Sheet 2 Last row = "+s2LastRow);
var Sheet2DataRange = s2.getRange(1,1,s2LastRow);
var Sheet2Data = Sheet2DataRange.getValues();
//Logger.log("DEBUG: Sheet 2 data range = "+Sheet2DataRange.getA1Notation());
var Sheet2length = Sheet2Data.length;
//Logger.log("DEBUG: Sheet2 length = "+Sheet2length);
// Loop through rows compare value per each sheet
for (var i = 0; i < Sheet1Data.length; i++) {
var s1data = Sheet1Data[i][0];
var s2data = Sheet2Data[i][0];
//Logger.log("DEBUG: Line: "+i+", s1data: "+s1data+" Vs s2data: "+s2data);
if (s1data !=s2data){
// sheets values don't balance
Logger.log("Line: "+i+". Sheets are NOT equal. Sheet1 = "+s1data+", Sheet2 = "+s2data);
return false;
}
else
{
// sheets values balance
Logger.log("Line: "+i+". Sheets are equal, value: "+s1data);
}
}
}
This is my test data

Duplicate sheets based on values count in dynamic range and rename it with the same range values

I want help for google script in spreadsheets.
I want to duplicate sheet named template, with names in range J1:N1 which is on the same spreadsheet in 'base' sheet. Also in range J1:N1 maybe different count values. is it possible to change number of duplicated sheets by values which in the range. For example if in this range 3 values copy template sheet 3 times...
After this I want to rename this duplicates with values in J1:N1 values, and copy the name of duplicated sheets on B2 cell on every duplicate. After all shi process hide template sheet.
This is link to spreadsheet:
https://docs.google.com/spreadsheets/d/1R-1mrfPwXGrJp3aVhGBFlalPnJ5r28cW9HuTu2OLmHc/edit?usp=sharing
I used this code, but its create only 1 sheet and with number. I need exactly the name for per sheet which is in the range:
function makeCopies() {
//getting active spreadsheet
var activeSreadsheet = SpreadsheetApp.getActiveSpreadsheet();
//getting basic sheet
var basicSheet = activeSreadsheet.getSheetByName("base");
//getting active spreadsheet
var activeSreadsheet2 = SpreadsheetApp.getActiveSpreadsheet();
//getting template sheet
var templateSheet = activeSreadsheet2.getSheetByName("template");
//setting template sheet as active
activeSreadsheet2.setActiveSheet(templateSheet);
//getting values from selected range
var rangeArr = basicSheet.getRange("J1:N1").getValues();
//going through range values
for(i = 0; i < rangeArr.length; i++){
//preparing name for new sheet
var name = (i + 2) + '. ' + rangeArr[i][0];
//making duplicate of base sheet
var newSheet = SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
//setting new name for duplicated sheet
newSheet.setName(name)
}
};
I found this code too, but it didnt exactly what i want:
function createEmployeeSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store employee data.
var employeeDataRange = ss.getRangeByName("group");
var employeeObjects = employeeDataRange.getValues();
var template = ss.getSheetByName('Template');
for (var i=0; i < employeeObjects.length; i++) {
// Put the sheet you want to create in a variable
var sheet = ss.getSheetByName(employeeObjects[i]);
// Check if the sheet you want to create already exists. If so,
// log this and loop back. If not, create the new sheet.
if (sheet) {
Logger.log("Sheet " + employeeObjects[i] + "already exists");
} else {
template.copyTo(ss).setName(employeeObjects[i]);
}
}
return;
This code creates dynamic count of sheets from range and 1 additional which can't rename because in range its empty cell.
Thanks in advance!

I want to hide Columns on each sheet according to a value in Cells in row 1

I get an error every time I try this here is what I am using. I get this error:
TypeError: Cannot find function hideColumns in object Sheet,Sheet,Sheet,Sheet,Sheet."
I am not very familiar with scripts and cant seem to get this to work.
function Hide() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// look at all sheets
var sheet = ss.getSheets();
// get data
var data = ss.getDataRange();
// get number of columns
var lastCol = data.getLastColumn()+1;
Logger.log(lastCol);
// itterate through columns
for(var i=1; i<lastCol; i++) {
if(data.getCell(1, i).getValue()[0] == '*') {
sheet.hideColumns(i);
}
}
}
Could some one help me?
I am assuming, you are using this reference. I guess, you want to do the following:
Iterate all the columns in the data range.
If the value of the first row of column equals * then hide that column.
I am not familiar with Google Apps Services, but I think your code should look like this:
function Hide() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// look at all sheets
//var sheet = ss.getSheets();
// get data
var data = ss.getDataRange();
//get the sheet this range belongs to.
var sheet = data.getSheet();
// get number of columns
var lastCol = data.getLastColumn()+1;
Logger.log(lastCol);
// itterate through columns
for(var i=1; i<lastCol; i++) {
if(data.getCell(1, i).getValue()[0] == '*') {
sheet.hideColumns(i);
}
}
}
Since .getSheets return an Array of Sheet objects you can not call that function.

Categories