In case of my current codes for doing MANUAL ENTRY, when I select a subject, a date and input maximum 4 student IDs at a time (e.g. 1802001, 1802002, 1802004 for example) an
Right now your code is combining the id with the email pattern. So for the code to work in both cases you'll need to have a check in place to identify when to concatenate the ID with the email pattern and when to substitute the ID with the whole email address. (I am assuming the whole email address is in the StudentList sheet in column F.)
If the whole email is always listed, even when it is based on the student ID, I would do away with the concatenation of the ID and email pattern entirely and just use the substitution of ID with whole email address.
Here are the steps that need to be implemented in your code:
EDIT
Here is the example sheet with changes to the code:
https://docs.google.com/spreadsheets/d/146vRZ1QDGpnzhxnAuQ03qX4jTORZdj_piueW7ORfYDY/edit?usp=sharing
Here is the code for onePeriodm()
:
function onePeriodm(){
//For protecting dashboard while scripts running
var spreadsheet = SpreadsheetApp.getActive();
//### new code ##########################################
var studentListSheet = spreadsheet.getSheetByName("StudentList");
var studentList = studentListSheet.getDataRange().getValues();
var studentEmail = null;
var tempEmail = null;
//### end new code ######################################
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetw = dashboard.getRange("A8");
var sheetw2 = dashboard.getRange("G8");
sheetw.setValue('Class Attendance is restricted now. Try Again Later!').setFontColor('Red');
var rangem = dashboard.getRange("A4:K6");
var timeZone = Session.getScriptTimeZone();
var stringDate = Utilities.formatDate(new Date(), timeZone, 'dd/MM/yy HH:mm');
//var me2 = Session.getEffectiveUser();
var me2 = Session.getActiveUser().getEmail();
var description = 'Scripts running on ' + stringDate + ' by ' + me2;
//var me = Session.getEffectiveUser();
//var description = 'Scripts are running by ' + me;
var protectionm = rangem.protect().setDescription(description);
protectionm.removeEditors(protectionm.getEditors());
protectionm.addEditor(me2);
if (protectionm.canDomainEdit()) {
protectionm.setDomainEdit(false);
}
//Refreshing sheet with removing unprotectd data
var spreadsheet = SpreadsheetApp.getActive();
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetName = dashboard.getRange("F5").getValue();
var sheet = spreadsheet.getSheetByName(sheetName);
//For removing unprotected rows of data from a particular sheet
// 1. Retrieve data range.
const dataRange = sheet.getDataRange();
// 2. Create an object from the protected range. This is used for removing from the cleared rows.
const protectedRanges = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE).map(e => {
const r = e.getRange();
const start = r.getRow();
return {start: start, end: r.getNumRows() + start - 1};
});
// 3. Create range list for clearing rows using the object.
let rangeList = [];
for (let r = 2; r <= dataRange.getNumRows(); r++) {
let bk = false;
for (let e = 0; e < protectedRanges.length; e++) {
if (protectedRanges[e].start == r) {
r = protectedRanges[e].end;
bk = true;
break;
}
}
if (!bk) rangeList.push(`A${r}:${r}`);
}
// 4. Delete the rows without the rows of the protected ranges.
if (rangeList.length > 0) sheet.getRangeList(rangeList).getRanges().reverse().forEach(r => sheet.deleteRow(r.getRow()));
//sheet.getRangeList(rangeList).getRanges().reverse().forEach(r => sheet.deleteRow(r.getRow()));
//for one period manual entry
const srcSheetName = "Dashboard";
// 1. Retrieve values from the source sheet.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const srcSheet = ss.getSheetByName(srcSheetName);
const [
[, , , , , emailPattern],
,
[courseCatalogId, dateString, ...studentIds],
] = srcSheet.getRange("F3:K5").getDisplayValues();
// 2. Retrieve current values
const dstSheet = ss.getSheetByName(courseCatalogId);
const dstCurrentValues = dstSheet
.getRange(`A2:C${dstSheet.getLastRow()}`) // expanded to include email column
.getDisplayValues(); // not flattening since we have multiple columns now
// 3. Convert the values for putting to the destination sheet.
// Do not include if there is already an email for this date in current values
const dstValues = studentIds.reduce((array, studentId) => {
const existingEntry = dstCurrentValues.find(
(row) => row[0] === dateString && +row[1] === +studentId //(row) => row[0] === dateString && row[2] === studentId + emailPattern //############# code change
);
//### new code ##########################################
tempEmail = studentList.filter(function(a){return (+a[3]) == (+studentId);})[0];
if (tempEmail != undefined && tempEmail != null &&tempEmail != ""){
studentEmail = tempEmail[5];
}else{
studentEmail = studentId + emailPattern;
}
//### end new code ######################################
if (studentId != "" && !existingEntry)
array.push([
dateString,
Number(studentId),
studentEmail,//studentId + emailPattern //############# code change
,
,
courseCatalogId,
]);
return array;
}, []);
// 4. Put the converted values to the destination sheet.
const index = dstCurrentValues.map((row) => row[0]).lastIndexOf(dateString);
const row = index + 2;
if (dstValues.length > 0){
dstSheet.insertRowsAfter(row, dstValues.length);
dstSheet.getRange(row + 1, 1, dstValues.length, dstValues[0].length).setValues(dstValues);
}
//dstSheet.insertRowsAfter(row, dstValues.length);
//dstSheet.getRange(row + 1, 1, dstValues.length, dstValues[0].length).setValues(dstValues);
protectionm.remove();
SpreadsheetApp.flush();
srcSheet.getRange("F5").setValue("All");
srcSheet.getRange("K6").setValue("Please Select");
srcSheet.getRange("G5:K5").clearContent();
srcSheet.getRange('G5').clearDataValidations();
//srcSheet.getRange('G5').setValue(new Date()).setNumberFormat("yyyy-mm-dd");
}
Your task can be fulfilled by using an onEdit
trigger.
// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0
function onEdit(e) {
let currentSheet = e.range.getSheet().getName();
let valsToSearchIn = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SHEET_WHERE_THE_IDS_ARE').getRange(ROW, COL, NO_ROWS, NO_COLS).getValues();
if (currentSheet == 'SHEET_WHERE_YOU_INPUT_THE_IDS') {
let inputValue = e.value;
for (let i = 0; i < valsToSearchIn.length; i++)
if (valsToSearchIn[i][0] == inputValue)
e.range.setValue(SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SHEET_WHERE_YOU_INPUT_THE_IDS').getRange(i + ROW, COL).getValue());
else
SpreadsheetApp.getUi().alert('Please input a valid student id!');
}
}
The above code works by identifying the sheet in which an edit has been by making use of the e
event object. If the name of this sheet is the same name as SHEET_WHERE_YOU_INPUT_THE_IDS
, then the value which has been inputted is stored in the inputValue
variable. Afterwards, it searches in the valsToSearchIn
array - which is the array in which the student ids are stored, for the inputValue
and if the search is successful, the corresponding email address will be set in the edited range. If the id is not found, then an alert will be displayed to the user.
Please bear in mind that you will have to adjust the code above (especially the ranges and the names of the sheets) in order to fit with your requirements.
onEdit(e)
triggerSHEET_WHERE_THE_IDS_ARE
SHEET_WHERE_YOU_INPUT_THE_IDS
onEdit(e)
triggerSHEET_WHERE_YOU_INPUT_THE_IDS
Apps Script Event Objects;
Apps Script onEdit(e).