Creating sheets with from master sheet - google-apps-script

I have a sheet named form responses which gets input from google
forms,Then I created sheets with names from Column C which is
employee code and append all the respective rows from form responses
to the newly created sheets.
Now I have sheets with name as employee code ( which is in column c of the sheet). Then I want to create secondary sheets from this master sheet(sheets with name as employee code) whose name is using the column E value as attached to the Employee code.for eg : if Emp code is 10003825 and value in column E is ASR, the sheet name should be 10001515ASR.
In Column E there are only 4 values ADC,ASR ACC,RSR. let the master sheet(sheets with name as employee code) retain ADC rows always while when other rows containing ASR,ACC,RSR comes append the respective row to the newly created sheet(ie if ASR the row goes to 10001515ASR).
I have shown my present sheet and expected output
The code I developed is shown below:
function switchSheet(){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheets = activeSpreadsheet.getSheets();
for (var i = 1; i < sheets.length; i++) {
var p = sheets[i].getSheetName();
sheetCreateChannel(p);
}
}
function sheetCreateChannel(ss){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = activeSpreadsheet.getSheetByName(ss);
var getNames = sheet1.getDataRange().getValues();
getNames.shift();
var sheets = activeSpreadsheet.getSheets();
var sheetsObj = {};
for (var i = 0; i < sheets.length; i++) {
sheetsObj[sheets[i].getSheetName()] = sheets[i];
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
if (r[4].toString()== "ASR"&& !((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "ASR");
sheetsObj[ss+"ASR"] = newSheet;
}
else if (r[4].toString()== "ACC"&&!((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "ACC");
sheetsObj[ss+"ACC"] = newSheet;
}
else if (r[4].toString()== "RSR"&& !((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "RSR");
sheetsObj[ss+"RSR"] = newSheet;
}
else {
break;
}
}
}
var deleteRows = 0;
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
if (r[4].toString() != "") {
if ((ss+(r[4])) in sheetsObj) {
var Q =ss+(r[4]);
sheetsObj[Q].appendRow(r);
}
deleteRows = i + 2;
}
}
sheet1.getRange(2, 1, deleteRows - 1, sheet1.getLastColumn()).clearContent();
}

This code works fine for my above issue
function sheetCreate(){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = activeSpreadsheet.getSheetByName("Form Responses 1");
var getNames = sheet1.getDataRange().getValues();
getNames.shift();
var sheets = activeSpreadsheet.getSheets();
var sheetsObj = {};
for (var i = 0; i < sheets.length; i++) {
sheetsObj[sheets[i].getSheetName()] = sheets[i];
}
var deleteRows = 0;
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
var N=r[2].toString()+r[4].toString();
if (N != "") {
if (N in sheetsObj) {
sheetsObj[N].appendRow(r);
} else {
var newSheet = activeSpreadsheet.insertSheet((N));
var cell1 = newSheet.getRange("A1").setValue("Timestamp");
var cell2 = newSheet.getRange("B1").setValue("Score");
var cell3 = newSheet.getRange("C1").setValue("Employee ID");
var cell4 = newSheet.getRange("D1").setValue("Name of the ATCO");
var cell5 = newSheet.getRange("E1").setValue("The channel on which duty is performed ");
var cell6 = newSheet.getRange("F1").setValue("DATE on which duty is performed");
var cell7 = newSheet.getRange("G1").setValue("Total duration of duty done");
newSheet.appendRow(r);
sheetsObj[N] = newSheet;
}
deleteRows = i + 2;
}
}
sheet1.getRange(2, 1, deleteRows - 1, sheet1.getLastColumn()).clearContent();
}

Related

Google Sheet : The result could not be auto-expanded. Please insert new columns (1)

This script import opportunities that we get. It populates rows which then calculates some numbers such as interest and stuff. However, I now have errors when populating my cells (#REF error, see pictures below). Nothing has changed so my first guess is it has do with the processing of the sheet which has become too heavy.
`
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createAddonMenu();
menu.addItem('Créer étude', 'init');
menu.addToUi();
}
function init() {
ss = SpreadsheetApp.getActiveSpreadsheet();
identifyJe();
sheetMaker = ss.getActiveSheet();
currentRow = ss.getActiveCell().getRowIndex();
ssEtudes = SpreadsheetApp.openById(getSheetEtudesId());
var ui = SpreadsheetApp.getUi();
var respon se = ui.alert(
'Ligne sélectionnée : ' + currentRow + '. Exécuter ?',
ui.ButtonSet.OK_CANCEL
);
if (response !== ui.Button.OK) return;
doEtude();
doContrat();
doPhases();
}
function doEtude(nomEtude) {
var etudeData = [];
for (var i = 0; i < etudeNamedRanges.length; i++) {
var column = ss.getRangeByName(etudeNamedRanges[i]).getColumn();
etudeData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('etudes');
var rowToAppend = getFirstEmptyRow(destSheet, 0);
for (var i = 0; i < etudeData.length; i++) {
var column = ssEtudes.getRangeByName(etudeNamedRanges[i]).getColumn();
destSheet.getRange(rowToAppend, column).setValue(etudeData[i]);
}
}
function doContrat() {
var contratData = [];
for (var i = 0; i < contratNamedRanges.length; i++) {
var column = ss.getRangeByName(contratNamedRanges[i]).getColumn();
contratData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('contrats');
var rowToAppend = getFirstEmptyRow(destSheet, 11);
for (var i = 0; i < contratData.length; i++) {
destSheet.getRange(rowToAppend, i + 4).setValue(contratData[i]);
}
}
function doPhases() {
var phasesCoords = getPhasesCoords();
var phasesData = [];
for (var i = 0; i < phasesCoords.length; i++) {
var phaseData = getPhaseData(phasesCoords[i]);
phaseData.unshift(i + 1);
phasesData.push(phaseData);
}
var destSheet = ssEtudes.getSheetByName('phases');
var rowToAppend = getFirstEmptyRow(destSheet, 9);
var columns = [];
for (var nPhase = 0; nPhase < phasesData.length; nPhase++) {
var phaseData = phasesData[nPhase];
for (var i = 0; i < phaseData.length; i++) {
if (columns[i] === undefined)
columns[i] = ssEtudes.getRangeByName(phasesNamedRanges[i]).getColumn();
destSheet
.getRange(rowToAppend + nPhase, columns[i])
.setValue(phaseData[i]);
}
}
}
`
Type of formula
The results
The error, which translates into The result could not be auto-expanded. Please insert new columns (1).
The results actually appear for some time and disappear after a few seconds, constantly. Does it have something to do with the size of the spreadsheet ?

Google script to auto populate a form with conditional logic failing due to variable not being defined (even though it looks defined to me)

Below is a script written by Jordan Rhea and provided via github.
I am trying to follow its logic so that I can understand how to approach automatically populating a form with questions that have conditional logic flowing to different sections of a Google Form.
The code is breaking at line 35 "ReferenceError: form is not defined (line 35, file "RosterMaker")
Line 35 = var classSection = form.addPageBreakItem().setTitle(className).setGoToPage(FormApp.PageNavigationType.SUBMIT);
I'm sure this is a simple error, but I cannot figure it out.
var ssID = "something";
var formID = "something"
//SpreadsheetApp.openById(ssID).getSheetByName("db_type");
function rosterMaker() {
//spreadsheet id of the rosters
var SHEET_ID = SpreadsheetApp.getActive();
var ss = SpreadsheetApp.openById(ssID);
var form = FormApp.openById((formID));
//get only the sheets with 'Roster' in the title
var sheets = ss.getSheets()
.filter(function(sheet) {return sheet.getName().match(/Roster/gi);});
//add multiple choice item
var classSelect = form.addMultipleChoiceItem()
.setTitle('Choose a class');
Logger.log(classSelect);
//get the class choices for the multiple choice item
var classChoices = getClasses(sheets);
//assign the choices to the classSelect variable
classSelect.setChoices(classChoices);
}
function getClasses(sheets) {
var classChoices = [];
for(var i = 0; i < sheets.length; i++) {
var className = sheets[i].getName();
var classSection = form.addPageBreakItem()
.setTitle(className)
.setGoToPage(FormApp.PageNavigationType.SUBMIT);
var students = getStudents(sheets[i]);
var studentSelect = form.addCheckboxItem()
.setTitle(className + ' absent')
.setHelpText('Select the students who are absent from this class');
var studentChoices = [];
for(var j = 0; j < students.length; j++) {
studentChoices.push(studentSelect.createChoice(students[j]));
}
studentSelect.setChoices(studentChoices);
classChoices.push(classSelect.createChoice(className, classSection));
}
return classChoices;
}
function getStudents(sheet) {
var studentValues = sheet.getDataRange().getValues();
var students = [];
for(var i = 1; i < studentValues.length; i++) {
students.push(studentValues[i].join(' '));
}
return students;
}
Test this:
var ssID = "something";
var formID = "something";
function rosterMaker() {
var SHEET_ID = SpreadsheetApp.getActive();
var ss = SpreadsheetApp.openById(ssID);
var form = FormApp.openById((formID));
var sheets = ss.getSheets().filter(function(sheet) {return sheet.getName().match(/Roster/gi);});
var classSelect = form.addMultipleChoiceItem().setTitle('Choose a class');
var classChoices = getClasses(sheets,form);//modified
classSelect.setChoices(classChoices);
}
function getClasses(sheets,form) {//modified
var classChoices = [];
for(var i = 0; i < sheets.length; i++) {
var className = sheets[i].getName();
var classSection = form.addPageBreakItem().setTitle(className).setGoToPage(FormApp.PageNavigationType.SUBMIT);
var students = getStudents(sheets[i]);
var studentSelect = form.addCheckboxItem().setTitle(className + ' absent').setHelpText('Select the students who are absent from this class');
var studentChoices = [];
for(var j = 0; j < students.length; j++) {
studentChoices.push(studentSelect.createChoice(students[j]));
}
studentSelect.setChoices(studentChoices);
classChoices.push(classSelect.createChoice(className, classSection));
}
return classChoices;
}
function getStudents(sheet) {
var studentValues = sheet.getDataRange().getValues();
var students = [];
for(var i = 1; i < studentValues.length; i++) {
students.push(studentValues[i].join(' '));
}
return students;
}

Using onEdit to bind a specific cell change value

This is my script. I need to populate the values in I2:I range when the cell value of C2 changes. I have created an array_temp but these are not getting pasted in I2. Can anybody please help me throw some light on it?
function onEdit(e) {
var spreadsheet = SpreadsheetApp.getActive();
var ss = e.getSheetByName('UserInterface');
var count = ss.getRange("H2").setFormula('=countif(TalukaName!B:B,UserInterface!C2)').getValue();
var DistrictName = ss.getRange('C2').getValue();
var matchindex = ss.getRange('H3').setFormula('=match(C2,TalukaName!B:B,0)').getValue();
var indexvalue = ss.getRange('H4').setFormula('=index(TalukaName!B:B,H3)').getValue();
var array = [] ;
ss.getRange('F2').clearcontent;
var ssTaluka= e.getSheetByName('TalukaName');
var range = ssTaluka.getDataRange();
var data = range.getValues();
for (var i = 0; i < count; i++) {
array[i]= data[i + matchindex - 1][0];
}
var array_temp = [];
for (var j = 0; j < array.length; j++) {
array_temp.push([
array[j]
])
}
ss.getRange('I2:I').clearContent();
ss.getRange('I2:I'+ (count+1)).setValues(array_temp) ;
}

First cell in active row during script execution

I am using the code below to view through a sheet, and change the first cell background to red if any other cells are red. What I would like, is to change the first cell in each row to red, only if that row contains a red cell. This code works through the spreadsheet, but only makes cell A1 red. How do I get it to affect the first cell of each row independently?
function MakeRed(){
var book = SpreadsheetApp.getActiveSpreadsheet();
var sheet = book.getActiveSheet();
var first_column = "B";
var first_row = 1;
var last_row = sheet.getLastRow();
var last_column = sheet.getLastColumn();
var active_row = 1;
var range_input = sheet.getRange(1,1,last_row,last_column);
var range_output = sheet.getRange("A1");
var cell_colors = range_input.getBackgroundColors();
var color = "#ff0000";
var count = 0;
for(var r = 0; r < cell_colors.length; r++) {
for(var c = 0; c < cell_colors[0].length; c++) {
if(cell_colors[r][c] == color) {
count++;
range_output.setBackground("#ff0000");
} else {
count--;
if (count == 0) {
range_output.setBackground("#ffffff");
}
}
}
}
}
I would suggest you do the whole stuff in the array of background colors you already have instead of calling a spreadsheet service each time the condition is true.
Code becomes simpler because I used the indexOf array method in the condition
function MakeRed(){
var book = SpreadsheetApp.getActiveSpreadsheet();
var sheet = book.getActiveSheet();
var first_column = "B";
var first_row = 1;
var last_row = sheet.getLastRow();
var last_column = sheet.getLastColumn();
var active_row = 1;
var range_input = sheet.getRange(1,1,last_row,last_column);
var range_output = sheet.getRange("A1");
var cell_colors = range_input.getBackgroundColors();
var color = "#ff0000";
var count = 0;
for(var r = 0; r < cell_colors.length; r++) {
Logger.log(cell_colors[r].indexOf(color));// just to check, you can remove this of course ...
if(cell_colors[r].indexOf(color)>-1) {
count++;
cell_colors[r][0]=color;
} else {
count--;
if (count == 0) {
cell_colors[r][0]="#ffffff";
}
}
}
range_input.setBackgroundColors(cell_colors);// update sheet colors
}
EDIT : I don't really understand the idea behind the "count" thing... it works the same way without it (code below) :
function MakeRed(){
var book = SpreadsheetApp.getActiveSpreadsheet();
var sheet = book.getActiveSheet();
var first_column = "B";
var first_row = 1;
var last_row = sheet.getLastRow();
var last_column = sheet.getLastColumn();
var active_row = 1;
var range_input = sheet.getRange(1,1,last_row,last_column);
var range_output = sheet.getRange("A1");
var cell_colors = range_input.getBackgroundColors();
var color = "#ff0000";
for(var r = 0; r < cell_colors.length; r++) {
Logger.log(cell_colors[r].indexOf(color))
if(cell_colors[r].indexOf(color)>-1) {
cell_colors[r][0]=color;
} else {
cell_colors[r][0]="#ffffff";
}
}
range_input.setBackgroundColors(cell_colors);// update sheet colors
}
edit 2 : this version will reset col A to white if no other red cell is in the row
function MakeRed(){
var book = SpreadsheetApp.getActiveSpreadsheet();
var sheet = book.getActiveSheet();
var first_column = "B";
var first_row = 1;
var last_row = sheet.getLastRow();
var last_column = sheet.getLastColumn();
var active_row = 1;
var range_input = sheet.getRange(1,1,last_row,last_column);
var range_output = sheet.getRange("A1");
var cell_colors = range_input.getBackgroundColors();
var color = "#ff0000";
for(var r = 0; r < cell_colors.length; r++) {
var rowWoColA = cell_colors[r].slice(1);
if(rowWoColA.indexOf(color)>-1) {
cell_colors[r][0]=color;
} else {
cell_colors[r][0]="#ffffff";
}
}
range_input.setBackgroundColors(cell_colors);// update sheet colors
}
Change var range_output = sheet.getRange("A1"); to the range you want edit.
You could do this in the loop:
for(var r = 0; r < cell_colors.length; r++) {
for(var c = 0; c < cell_colors[0].length; c++) {
if(cell_colors[r][c] == color) {
count++;
// Assuming you only want to change bg color of the first column on each row
sheet.getRange(r,1).setBackground("#ff0000");
} else {
count--;
if (count == 0) {
sheet.getRange(r,1).setBackground("#ffffff");
}
}
}
}

Google Docs - Scripts, copy cell from one sheet to another sheet

I need to copy a cell from a sheet to corresponding cell in another sheet
From here:
to here:
My sheet can be viewed here.
Please report back if this is not achieving what you require.
function updateVerified() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getRange('Calculates!D5:K').getValues();
var respSheet = ss.getSheetByName('Responses');
var respTs = respSheet.getRange('A2:A').getValues();
var respRange = respSheet.getRange('F2:F');
var respValues = respRange.getValues();
var convTs = [], temp;
for (var i = 0; i < respTs.length; i++) {
convTs[i] = respTs[i][0] ? respTs[i][0].getTime() : '';
}
for (var j = 0; j < source.length; j++) {
if (!source[j][0]) break;
temp = convTs.indexOf(source[j][0].getTime());
if (temp > -1) respValues[temp][0] = source[j][7];
}
respRange.setValues(respValues);
}