How do I use Sheets.Spreadsheets.getByDataFilter from app script for a filter view that is created in spreadsheet? - google-apps-script

I am seeking help with the following case
I have a spreadsheet, and it contains few filter views - f1, f2, ...
I have an app script associated with the spreadsheet. I have enabled Resources > Advanced Google Services to access the Sheets API v4.
Currently, I access that data as
var fruits = Sheets.Spreadsheets.Values.get("1YBPXShvssFpTI-5dPSsy_N_iEVaeHezdxymsdxpTy6w", "Fruits!A:B").values;
And I get the corresponding data back.
I would now, like to only get the data that is used by the filter view, so that I do not bring the entire data which is not necessary and slows down the processing.
I saw that there is something called Sheets.Spreadsheets.getByDataFilter(resource, spreadsheetId), but I am not sure how to create the resource object.
Given my filters, and knowing the spreadsheet Id, how do I only fetch the data based on the filter names that I know?
UPDATE
My latest attempt looks like
var ss = SpreadsheetApp.getActiveSpreadsheet();
function getUnpostedItems() {
Logger.log("This function will prioritize the new items that are added into the inventory");
var sheet = ss.getSheetByName("Items");
var filterSettings = {};
filterSettings.criteria = {};
var condition = {
"condition": {
"type": "LESS_THAN",
"values": [
{ "userEnteredValue": "=NOW()-30" }
]
}
}
filterSettings['criteria'][1] = {
'condition': condition
};
var filterSettings = {
range: {
sheetId: sheet.getSheetId(),
},
}
var req = {
"setBasicFilter": {
"filter": filterSettings
}
}
// var items = Sheets.Spreadsheets.batchUpdate({'requests': [req]}, ss.getId());
var items = ss.getRange("Items!A:B").getValues()
// var items1 = Sheets.Spreadsheets.Values.get("1YBPXShvssFpTI-5dPSsy_N_iEVaeHezdxymsdxpTy6c", "Items!A:B").values
Logger.log("Found items:" + items.length);
return [];
}
But no luck so far!

As per #tanaike's help, I was able to get the following working
function getUnpostedItems() {
Logger.log("This function will prioritize the new items that are added into the inventory");
// var ss = SpreadsheetApp.getActiveSpreadsheet(); // Added
var sheet = ss.getSheetByName("Items"); // Modified
var values = sheet.getDataRange().getValues();
Logger.log("VALUES "+values.length);
//var newCriteria = SpreadsheetApp.newFilterCriteria().whenDateBefore(new Date()).build();
var newCriteria = SpreadsheetApp.newFilterCriteria().whenDateBefore(subDaysFromDate(new Date(), 30)).build();
var range = sheet.getFilter().setColumnFilterCriteria(1, newCriteria).getRange(); //The 1-indexed position of the column.
// values = range.getValues();
// I added below script.
var res = Sheets.Spreadsheets.get(ss.getId(), {
ranges: ["Items"], // <--- Please set the sheet name.
fields: "sheets/data"
});
var values = res.sheets[0].data[0].rowMetadata.reduce(function(ar, e, i) {
if (!e.hiddenByFilter && res.sheets[0].data[0].rowData[i]) {
ar.push(
res.sheets[0].data[0].rowData[i].values.map(function(col) {
return col.userEnteredValue[Object.keys(col.userEnteredValue)[0]];
})
);
}
return ar;
}, []);
Logger.log("VALUES "+values.length);
Logger.log("VALUES "+values);
//Logger.log("Found Items:" + items.length);
return [];
}

Related

How to get unique data of google sheets to json with appscript?

I'm getting values of the sheet in JSON format. My Sheet
I've added this code in appscript to get JSON:
var ss = SpreadsheetApp.openByUrl("Spreadsheet URL");
var sheet = ss.getSheetByName('Sheet1');
function doGet(e){
var action = e.parameter.action;
if(action == 'getItems'){
return getItems(e);
}
}
function getItems(e){
var records={};
var rows = sheet.getRange(2, 1, sheet.getLastRow() - 1,sheet.getLastColumn()).getValues();
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
record['customerName'] = row[0];
record['docketNo']=row[1];
record['docketDate']=row[2];
record['destination']=row[3];
record['weight']=row[4];
data.push(record);
}
records = data;
var result=JSON.stringify(records);
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
Current JSON data:
[
{
"customerName":"cash",
"docketNo":"d87976489",
"docketDate":"2021-08-14T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"cash",
"docketNo":"d87976480",
"docketDate":"2021-08-12T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
I want this JSON data:
[
{
"customerName":"cash",
"docketNo":"d87976489","d87976480",
"docketDate":"2021-08-14T18:30:00.000Z","2021-08-12T18:30:00.000Z",
"destination":"kanpur","kanpur",
"weight":1,1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
I have the same customer names therefore, I want unique data. I've searched many websites & videos but I didn't get one.
Please give me appscript code to get this data!
You can do it with some Javascript acrobatics
Sample:
function makeJsonUnique() {
var json = [
{
"customerName":"cash",
"docketNo":"d87976489",
"docketDate":"2021-08-14T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"cash",
"docketNo":"d87976480",
"docketDate":"2021-08-12T18:30:00.000Z",
"destination":"kanpur",
"weight":1
},
{
"customerName":"abc",
"docketNo":"d87976482",
"docketDate":"2021-09-12T18:30:00.000Z",
"destination":"mumbai",
"weight":2
}
]
var customerNames = json.map(e=>e.customerName)
var uniqueCustomerNames = [...new Set(customerNames)]
var newJSON =[]
uniqueCustomerNames.forEach(function(name){
var tempObj ={}
tempObj.customerName = name
var jsonSubsets = json.filter(function(obj){return obj.customerName == name})
tempObj.docketNo = jsonSubsets.map(obj=>obj.docketNo).join(",")
tempObj.docketDate = jsonSubsets.map(obj=>obj.docketDate).join(",")
tempObj.destination = jsonSubsets.map(obj=>obj.destination).join(",")
tempObj.weight = jsonSubsets.map(obj=>obj.weight).join(",")
console.log(JSON.stringify(tempObj))
newJSON.push(tempObj)
})
console.log(newJSON)
}
Used methods:
map()
filter()
...newSet()
push()
join()

In Google Sheets set dynamic dropdown with Apps Script

I'm trying to set a dynamic dropdown in Google Sheet using Apps Script. I managed to get most parts working except setting the data validation in the cells necessary:
function sheetByName(ssId, sheetName) {
var ss = SpreadsheetApp.openById(ssId);
var sheet = ss.getSheetByName(sheetName);
return sheet;
};
function columnByName(sheet, columnName) {
var data = sheet.getDataRange().getValues();
var column = data[0].indexOf(columnName);
return column;
};
function columnValues(sheet, index) {
var data = sheet.getDataRange().getValues();
var values = [];
for(n=1; n<data.length; ++n) {
values.push(data[n][index]);
}
return values;
}
function columnSetDataValidation(sheet, index, options) {
var data = sheet.getDataRange().getValues();
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(options)
.setAllowInvalid(true)
.build();
for(n=1; n<data.length; ++n) {
var cell = data[n][index];
};
};
function dropDownBedrijven() {
var sheetCollegas = sheetByName("<<ID HERE>>", "Collegas");
var sheetBedrijven = sheetByName("<<ID HERE>>", "Bedrijven");
var getColumnIndexInBedijven = columnByName(sheetBedrijven, "Bedrijf");
var getColumnIndexInCollegas = columnByName(sheetCollegas, "Bedrijf");
var bedrijven = columnValues(sheetBedrijven, getColumnIndexInBedijven).filter(item => item);
columnSetDataValidation(sheetCollegas, getColumnIndexInCollegas, bedrijven);
};
I can't manage to get the function columnSetDataValidation to set data validation in the required cells.
Do you have any idea how to go about it?
You need to use range.setDataValidation(rule) with a range.
In your function columnSetDataValidation you are correctly building the rule, but are failing to assign the rule to a range. You are looping over the values of the range and then changing the value of var cell until the loop ends. Nowhere did you call range.setDataValidation(rule).
Try the following solution:
function columnSetDataValidation(sheet, index, options) {
var range = sheet.getDataRange();
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(options)
.setAllowInvalid(true)
.build();
for(n = 1; n < range.getLastRow(); ++n) {
var cell = range.getCell(n,index);
cell.setDataValidation(rule);
};
};
References:
Range.getCell(row, column)
Range.setDataValidation(rule)
Try this:
function columnSetDataValidation() {
const ss=SpreadsheetApp.getActive();
const sheet=ss.getSheetByName('Sheet1');
const range = sheet.getRange(2,4,sheet.getLastRow()-1);//putting validation in column 4
const options=[1,2,3,4,5];
const rule = SpreadsheetApp.newDataValidation()
.requireValueInList(options)
.setAllowInvalid(true)
.build();
range.setDataValidation(rule);
}

How to filter data in columns using google app script editor

I'm facing some issues related to filter data in the columns using google app script editor.
I'm able to set a filter in columns using google app script as you can see in the above screenshot. but problem is when I'm trying to get the filtered data. it returns some number series instead of actual data as you can see below :
[20-03-09 18:19:48:395 IST] [1,2,4,5,6,8,9,10,11,12,13,14,15,19,20,21,22,23,24,26,27,28,29,30]
To set a filter :
function setFilter() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var filterSettings = {};
// The range of data on which you want to apply the filter.
// optional arguments: startRowIndex, startColumnIndex, endRowIndex, endColumnIndex
filterSettings.range = {
sheetId: ss.getActiveSheet().getSheetId()
};
// Criteria for showing/hiding rows in a filter
// https://developers.google.com/sheets/api/reference/rest/v4/FilterCriteria
filterSettings.criteria = {};
var columnIndex = 2;
filterSettings['criteria'][columnIndex] = {
'hiddenValues': ["England", "France"]
};
var request = {
"setBasicFilter": {
"filter": filterSettings
}
};
Sheets.Spreadsheets.batchUpdate({'requests': [request]}, ss.getId());
}
To get the filtered data:
function getFilteredRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssId = ss.getId();
var sheetId = ss.getActiveSheet().getSheetId();
let data = getIndexesOfFilteredRows(ssId,sheetId);
Logger.log(JSON.stringify(data));
}
function getIndexesOfFilteredRows(ssId, sheetId) {
var hiddenRows = [];
// limit what's returned from the API
var fields = "sheets(data(rowMetadata(hiddenByFilter)),properties/sheetId)";
var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].properties.sheetId == sheetId) {
var data = sheets[i].data;
var rows = data[0].rowMetadata;
for (var j = 0; j < rows.length; j++) {
if (rows[j].hiddenByFilter) hiddenRows.push(j);
}
}
}
return hiddenRows;
}
How to set a filter in columns and get the filtered data using google app script.
Please help me with this.
In your case, the script for filtering has already worked. You want the script for retrieving the values from the filtered sheet in the Spreadsheet.
You want to achieve this using Sheets API with Google Apps Script.
If my understanding is correct, how about this modification? Please think of this as just one of several possible answers.
In your case, the function of getIndexesOfFilteredRows is modified. Using hiddenByFilter, the hidden rows and shown rows are retrieved as an object.
Modified script:
function getIndexesOfFilteredRows(ssId, sheetId) {
var object = {hiddenRows: [], hiddenRowValues: [], shownRows: [], shownRowValues: []};
// limit what's returned from the API
var fields = "sheets(data,properties/sheetId)";
var sheets = Sheets.Spreadsheets.get(ssId, {fields: fields}).sheets;
for (var i = 0; i < sheets.length; i++) {
if (sheets[i].properties.sheetId == sheetId) {
var data = sheets[i].data;
var rows = data[0].rowMetadata;
for (var j = 0; j < rows.length; j++) {
var r = [];
if (data[0].rowData[j] && Array.isArray(data[0].rowData[j].values)) {
r = data[0].rowData[j].values.map(function(e) {
var temp = "";
if (e.hasOwnProperty("userEnteredValue")) {
if (e.userEnteredValue.hasOwnProperty("numberValue")) {
temp = e.userEnteredValue.numberValue;
} else if (e.userEnteredValue.hasOwnProperty("stringValue")) {
temp = e.userEnteredValue.stringValue;
}
}
return temp;
});
}
if (r.length > 0) {
if (rows[j].hiddenByFilter) {
object.hiddenRows.push(j);
object.hiddenRowValues.push(r);
} else {
object.shownRows.push(j);
object.shownRowValues.push(r);
}
}
}
}
}
return object;
}
Result:
When above script is run for the filtered sheet, the following object which has the hidden row numbers, hidden row values, shown row numbers and shown row values is returned.
{
"hiddenRows":[0,1],
"hiddenRowValues":[["a1","b1","c1"],["a2","b2","c2"]],
"shownRows":[2,3],
"shownRowValues":[["a3","b3","c3"],["a4","b4","c4"]]
}
Reference:
DimensionProperties
If I misunderstood your question and this was not the direction you want, I apologize.
Added:
How about this sample script? In this sample script, the values filtered with filterValues can be retrieved as an object. In this case, the result is the same with your setFilter() and the modified getIndexesOfFilteredRows(). But the basic filter is not used. So please be careful this.
function myFunction() {
var filterValues = ["England", "France"]; // Please set the filter values.
var column = 3; // In this case, it's the column "C". Please set the column number.
var sheetName = "Sheet1"; // Please set the sheet name.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
var values = sheet.getDataRange().getValues();
var object = values.reduce(function(o, e, i) {
if (filterValues.indexOf(e[column - 1]) > -1) {
o.hiddenRows.push(i + 1);
o.hiddenRowValues.push(e);
} else {
o.shownRows.push(i + 1);
o.shownRowValues.push(e);
}
return o;
}, {hiddenRows: [], hiddenRowValues: [], shownRows: [], shownRowValues: []});
Logger.log(object)
}
If you want to retrieve only the filtered values, this script might be suitable.
In this case, the script can run with and without V8. But when V8 is enabled, the loop speed will be fast. Ref

I want to write a script to read and log values of a specific row and copy them to a new sheet

I want to build a script to automate creating a form out of specific values.
What I need to do is:
Ask the user which row is relevant for the form, enter the row in a text box
Log value of column A of that row (Date)
Check that row from column C-ZZZ for values (numbers)
if there is a cell with a value, log the value. If the cell is empty ignore it
If there is a value in a cell additionally log values of row 1-10 of that column (numbers + strings)
create a new sheet
copy logged values in a specific order into that new sheet (other order than in the first sheet)
I searched for scripts that offer any resemblance of what I want to do, but I only managed to copy values of a specific row and output them into a new sheet without any formatting
Ask user for a row (NaN error message doesn't work):
function tourzettelZeile() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var rowIdxStr = Browser.inputBox("For which row do you want to make the list?");
if (rowIdxStr == 'cancel') {
return;
}
var rowIdx = parseInt(rowIdxStr);
if (rowIdx == NaN) {
Browser.msgBox("Numbers only or 'cancel'");
return;
}
}
My attempt at logging and pasting data:
function readData(spreadsheetID)
{
var spreadsheetId = '1KdZNvKgwL6NMuF0FYGB8jBhRVpbwv954D_UcBZ22eh0';
var plakatMenge = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK15:DK900');
var plakatFormat = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK4');
var plakatName = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK15:DK1');
var plakatiererName = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!FK66');
var plakatInfo = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!DK7');
var plakatGebiet = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!FL66');
var auftragDatum = Sheets.Spreadsheets.Values.get(spreadsheetId, 'PlakatTool2019!A66');
Logger.log(plakatMenge.values);
Logger.log(plakatFormat.values);
Logger.log(plakatName.values);
Logger.log(plakatiererName.values);
Logger.log(plakatInfo.values);
Logger.log(plakatGebiet.values);
Logger.log(auftragDatum.values);
Browser.msgBox(plakatMenge + plakatFormat + plakatName + plakatiererName + plakatInfo + plakatGebiet + auftragDatum);
//Neues Sheet erstellen
var requests = [{
'addSheet': {
'properties': {
'title': 'Tourzettel',
'gridProperties': {
'rowCount': 80,
'columnCount': 14
},
'tabColor': {
'red': 1.0,
'green': 0.3,
'blue': 0.4
}
}
}
}];
var response =
Sheets.Spreadsheets.batchUpdate({'requests': requests}, spreadsheetId);
Logger.log('Created sheet with ID: ' +
response.replies[0].addSheet.properties.sheetId);
//writeValues
// Specify some values to write to the sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
// ss is now the spreadsheet the script is associated with
var sheet = ss.getSheets()[5];
var values = [
[plakatMenge.values, "Gebiet", plakatFormat.values, plakatName.values, plakatiererName.values, plakatInfo.values, plakatGebiet.values, auftragDatum.values]
];
var range = sheet.getRange("A1:H1");
range.setValues(values);
}
Both these scripts don't do the right thing and are not combined (info on which row to check does nothing)
This function attempts to do the first five items in your list:
Feel free to use and debug it because I have not debugged it at all.
function readAndLog() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var row=SpreadsheetApp.getUi().prompt('Enter Row Number').getResponseText();
if(typeof(row)!=Number) {
throw("Invalid Response: terminating script");
return;
}else{
Logger.log(sh.getRange(row,1).getValue());
var vA=sh.getRange(row,3,1,sh.getLastColumn()-3).getValues();
var rA=[];
for(var i=0;i<vA.length;i++) {
if(vA[0][1] && typeOf(vA[0][i])==Number) {
rA.push({col:i+1,val:vA[0][i]});
Logger.log('column: %s, value: %s',rA[i].col,rA[i].val);
var cA=sh.getRange(1,rA[i].col,10,1).getValues();
for(var j=0;j<cA.length;j++) {
Logger.log('col: %s, row: %s value: %s',rA[i].col, j+1, cA[0][j]);
}
}
}
}
}
Thanks, that helped a lot. I had to get rid of this part:
if(typeof(row)!=Number) {
throw("Invalid Response: terminating script");
return;
}else{
As it gave me an error, I wasn't able to solve.
I added a bit to the code:
function Tourzettel(){
readAndLog();
newSheet();
logOutput();
}
function readAndLog() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var row=SpreadsheetApp.getUi().prompt('Gib die Zeile mit dem Datum für die Tour ein').getResponseText();
Logger.log(sh.getRange(row,1).getValue());
var vA=sh.getRange(row,3,1,sh.getLastColumn()-3).getValues();
var rA=[];
for(var i=0;i<vA.length;i++) {
if(vA[0][1] && typeOf(vA[0][i])==Number) {
rA.push({col:i+1,val:vA[0][i]});
Logger.log('column: %s, value: %s',rA[i].col,rA[i].val);
var cA=sh.getRange(1,rA[i].col,10,1).getValues();
for(var j=0;j<cA.length;j++) {
Logger.log('col: %s, row: %s value: %s',rA[i].col, j+1, cA[0][j]);
}
}
}
}
// Create new sheet
function newSheet() {
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName("TourzettelV2");
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName("TourzettelV2");
}
// Log in das neue Sheet schreiben
function logOutput() {
var stringToWrite = Logger.log;
SpreadsheetApp.getActive().getSheetByName('TourzettelV2').getRange("A1").setValue(stringToWrite);
}
My problem now is the function logOutput, because Logger.log doesn't seem to work. It outputs:
function log() {
[native code, arity=0]
}
Not sure what exactly it logged there, but it doesn't look like cell values. I do want every single logged value to be put into a seperate cell.
To fix the NaN error try this:
if (isNan(rowIdx)) {
Browser.msgBox("Numbers only or 'cancel'");
return;
}
The other part is a little hard to follow. If you want to pass the row index number to the second function, you could try adding this line to the first function:
readData(rowIdx);
And the second function would then be
function readData(rowIdx) {
...
}
And it can then use the rowIdx variable in the script. I'm assuming the 2nd function does not need the spreadsheetID passed to it as it is provided in the first line of the function. (Or is that there because you were testing?)

Google script duplicate and rename sheets based on list

I have a table that has three columns of employee info. The first column has the employe names. I want to write a google apps script that will duplicate a pre-formatted template sheet and re-name it with the employee name. At the end of the script each employee will have their own sheet named after them.
Here is the code I have so far, I am using some functions from the Google scripts tutorial, but I am at a loss on how to proceed further. EDITED, I have gotten a little further, this code worked once but now is getting hung on setName:
//Create new sheets for each employee in the list
function createEmployeeSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// Get the range of cells that store employee data.
var employeeDataRange = ss.getRangeByName("EmployeeRef");
// For every row of employee data, generate an employee object.
var employeeObjects = getRowsData(sheet, employeeDataRange);
for (i=0; i < employeeObjects.length; i++) {
var EmployeeName = employeeObjects[i].name;
ss.setActiveSheet(ss.getSheetByName("Template"));
SpreadsheetApp.getActiveSpreadsheet().duplicateActiveSheet();
var first = ss.getSheetByName("Copy of Template 1");
first.setName(EmployeeName);
}
}
After visiting this Q&A I figured out a far simpler method:
function createEmployeeSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the range of cells that store employee data.
var employeeDataRange = ss.getRangeByName("EmployeeRef");
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;
}
You can do more simple by using the copyTo() function.
Also make sure you have unique EmployeeNames.
So your code would look like:
function test() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var employeeObjects = [
{"name": "Peter" },
{"name": "Alice" },
{"name": "Frank" }
]
var template = ss.getSheetByName('Template');
for ( var i=0; i < employeeObjects.length; i++) {
var EmployeeName = employeeObjects[i].name;
// get the sheets to check you are not creating a duplicate sheet
var sheets = ss.getSheets();
var ok = true;
// loop through the sheets and check a duplicate exist
for ( var j=0; j<sheets.length;j++ ) {
if ( sheets[j].getName() == EmployeeName ) {
ok = false;
Logger.log('duplicate');
}
}
if ( ok ) {
template.copyTo(ss).setName(EmployeeName);
} else {
// do whatever you need to do if employee name is duplicate
}
}
}