Using onEdit to bind a specific cell change value - google-apps-script

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) ;
}

Related

Find all empty cells in several columns

Is there an easy way to color the rows containing empty cells in specific columns? So far, I only came up with a solution to highlight the cells themselves, but this script also takes some time to run.
Will appreciate any advice or guidance!
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs')
var columns = ['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK'];
for(var col in columns){ //loop to iterate the desired ranges
var range = sheet.getRange(columns[col]);
//range.activate();
var values = range.getValues();
var formulas = range.getFormulas();
//for each row that data is present
for(var i = 0; i < values.length; i++) { //loop to iterate the rows
for( var j = 0; j< values[i].length ; j++){ //loop to iterate the columns
var cell = range.getCell(i+1, j+1);
if ( values[i][j] == "" )
{
cell.setBackground('red');
cell.activate
}
else
{ cell.setBackground('white')
}
Use ConditionalFormatRuleBuilder instead. This will create a Conditional format rule in your Sheet.
Try this.
Code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs');
var ranges = sheet.getRangeList(['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK']);
var rule = SpreadsheetApp.newConditionalFormatRule()
.whenCellEmpty()
.setBackground('red')
.setRanges(ranges.getRanges())
.build();
var sheetRules = sheet.getConditionalFormatRules();
sheetRules.push(rule);
sheet.setConditionalFormatRules(sheetRules);
}
Output:
Conditional Formatting:
Highlighting empty cells using rangeList.setBackgroundColor(color) ​
In my code below, I collected the cell name of the empty cells and use it to create a RangeList. Then I used the RangeList to set the background to red. This reduced the Google Sheet Service calls from thousands to 11.
function columnToLetter(column)
{
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
function highlightEmptyCell(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs')
var rangeList = sheet.getRangeList(['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK']);
var rangeArray = rangeList.getRanges();
var ranges = [];
rangeArray.forEach(range =>{
var data = range.getValues();
for( var i = 0; i < data.length; i++ ){
for( var j = 0; j < data[0].length; j++ ){
if(data[i][j] == ""){
var cellName = columnToLetter(range.getColumn()) + (i + 17)
ranges.push(cellName);
}
}
}
});
sheet.getRangeList(ranges).setBackground("red");
}
Reference:
Class ConditionalFormatRuleBuilder
RangeList.setBackgroundColor(color)

Creating sheets with from master sheet

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();
}

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;
}

Google Spreadsheet setBackgroundColors() "Deprecated"

A gs I have been using in the past to check for duplicates, is no longer working. The script would check all cells in the spread sheet if any were identical it would highlight all their occurrences green. I also had another function that would revert all the cells back to white.
setBackgroundColors() has been deprecated; people have been recommended to now use setBackground(). The script still doesn't work...
Here is my gs, make a copy and fiddle with it. Many Thanks...
https://docs.google.com/spreadsheets/d/1UELTxZRZPKQKU9NsQwNefvdxJDM0xDt8904sZy3etoY/edit#gid=0
Here is the script.
/**
* Retrieves all the rows in the active spreadsheet that contain data and logs the
* values for each row.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
Logger.log(row);
}
};
/**
* Adds a custom menu to the active spreadsheet, containing a single menu item
* for invoking the readRows() function specified above.
* The onOpen() function, when defined, is automatically invoked whenever the
* spreadsheet is opened.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Check Directory",
functionName : "CheckDirectory"
}];
spreadsheet.addMenu("Script Center Menu", entries);
};
function CheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'green';
formats[values[l][1]][values[l][2]] = 'green';
}
}
}
}
dataRange.setBackground(formats);
};
function resetCheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'white';
formats[values[l][1]][values[l][2]] = 'white';
}
}
}
}
dataRange.setBackground(formats);
};
Use setBackgrounds(). With an s since it's a method that applies multiple background colors to multiple cells

How can i set a range to be the last row of data in the spreadsheet? Using Google Apps Script

How can I change my variable "range" to be the last row of data entered into the spreadsheet instead of 'A2:Z2'?
function findFault() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Inspections");
//Set the range to be search through
var range = sheet.getRange('A2:Z2');
//Turn the range into data values
var data = range.getValues();
//Declare fault and the value to search for
var fault = "Fault";
//Iterate through data to find fault
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
if (data[i][j] == fault) {
//log to test if working
Logger.log("Found Fault");
}
}
}
}
I updated my code and got it working. If anyone has tips on making it more efficient please post.
function findFault() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Inspections");
//Get the last row if data
var lastRowNumber = sheet.getDataRange().getNumRows();
var allColumns = sheet.getDataRange().getNumColumns();
//Set the range to be search through
var range = sheet.getRange(lastRowNumber, 1, 1, allColumns);
//Turn the range into data values
var data = range.getValues();
//Declare fault and the value to search for
var fault = "Fault";
//Iterate through data to dinf fault
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
if (data[i][j] == fault) {
//log to test if working
Logger.log("Found Fault");
}
}
}
}