How to check if the value exist in google spreadsheet or not using apps script - google-apps-script

How to check if the value is exist in google spreadsheet or not using apps script
I want to check if the Sam exist in the entire spreadsheet or not using apps script. If exist I want to perform task...
function doGet(e) {
return HtmlService.createHtmlOutput("Hi there");
}
function doPost(e) {
// this is where telegram works
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var userName = data.message.from.username;
if(/^#/.test(text)) {
var sheetName = text.slice(1).split(" ")[0];
var sheet = SpreadsheetApp.openById(ssId).getSheetByName(sheetName) ? SpreadsheetApp.openById(ssId).getSheetByName(sheetName) : SpreadsheetApp.openById(ssId).insertSheet(sheetName);
var comment = text.split(" ").slice(1).join(" ");
sheet.appendRow([userName,new Date(),id,name,comment,answer]);
}
//check if user is new in group
// this gets the range
var range = SpreadsheetApp.getActiveRange().getValues();
var searchString = "marsad01";
var isSearchStringInRange = range.some( function(row){
return row[0] === searchString
});
if(isSearchStringInRange){
// do something
sendMessage(id, answer, name);
}else{
sendGreetingMessage(id, answer, name);
}
}
is there any way how to do this

Depending on if you want to select the range or just always use the whole A:A column. In the former case, do this:
// this gets the range
var range = SpreadsheetApp.getActiveRange().getValues();
// this is what you are searching for
var searchString = "Sam";
// this is whether what you are searching for exists
var isSearchStringInRange = range.some( function(row){
return row[0] === searchString
});
// then you can proceed to do something like
if( isSearchStringInRange ){
// do something
}

Answer:
You can define a textFinder and run it over your data range.
Code:
function findSam() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var range = sheet.getDataRange();
var textFinder = range.createTextFinder('Sam');
var locations = [];
var occurrences = textFinder.findAll().map(x => x.getA1Notation());
if (occurrences == []) {
// do something if "Sam" not in sheet
}
else {
// do stuff with each range:
}
}
This code will:
Find all cells that contain "Sam" in the first sheet of the Spreadsheet
Append the Range object that contains "Sam" to an array of ranges
Map the array of ranges to an array of A1 notations which are all the cells which contain "Sam".
From here you can do what you wish with the ranges. If "Sam" is not in the sheet then occurrences will be an empty array and you can do here what you wish.
References:
Class TextFinder | Apps Script | Google Developers

Related

How to clear only "Column A" with Google Apps Script before updating with latest content in the same column

I would like to clear the contents of "column A" before "Update" function fills the latest data in the same column. The idea is remove any redundant data that is not required.
Usecase: Update all the tabs in one Index sheet, if people delete a sheet - that should not reflect in this Index sheet. Here is the code I have used after some research. I am new to this so need some help.
EDIT: Also how to exclude certain "Sheets" from the "Update" function so it doesn't show up in the Index column?
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Index Menu')
.addItem('Create Index', 'createIndex')
.addItem('Update Index', 'updateIndex')
.addToUi();
}
// function to create the index
function createIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
// check if sheet called sheet called already exists
// if no index sheet exists, create one
if (ss.getSheetByName('index') == null) {
var indexSheet = ss.insertSheet('Index',0);
}
// if sheet called index does exist, prompt user for a different name or option to cancel
else {
var indexNewName = Browser.inputBox('The name Index is already being used, please choose a different name:', 'Please choose another name', Browser.Buttons.OK_CANCEL);
if (indexNewName != 'cancel') {
var indexSheet = ss.insertSheet(indexNewName,0);
}
else {
Browser.msgBox('No index sheet created');
}
}
// add sheet title, sheet names and hyperlink formulas
if (indexSheet) {
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
}
// function to update the index, assumes index is the first sheet in the workbook
function updateIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var indexSheet = sheets[0];
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
// function to clear index
function clearContentsOnly() {
var range = SpreadsheetApp
.getActive()
.getSheetByName("Index")
.getRange(4,2,2,2);
range.clearContent();
}
// function to print out the index
function printIndex(sheet,names,formulas) {
sheet.getRange(1,1).setValue('Task Index').setFontWeight('bold');
sheet.getRange(7,1,formulas.length,1).setFormulas(formulas);
}
// function to create array of sheet names and sheet ids
function sheetNamesIds(sheets) {
var indexSheetNames = [];
var indexSheetIds = [];
// create array of sheet names and sheet gids
sheets.forEach(function(sheet){
indexSheetNames.push([sheet.getSheetName()]);
indexSheetIds.push(['=hyperlink("https://docs.google.com/spreadsheets/d/XXXX/edit#gid='
+ sheet.getSheetId()
+ '","'
+ sheet.getSheetName()
+ '")']);
});
return [indexSheetNames, indexSheetIds];
} ```
clear contents of column A
sheet.getRange(1,1,sheet.getLastRow()).clearContent();
if you have header rows and you specify the start row:
const sr = 2;
sheet.getRange( sr, 1, sheet.getLastRow() - sr + 1).clearContent();
function updateIndex() {
// Get all the different sheet IDs
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var indexSheet = sheets[0]; //better to use the name of the index sheet - as the sheet position may get changed easily by the user
indexSheet.GetRange("A2:A").clearContent(); //add this line
var namesArray = sheetNamesIds(sheets);
var indexSheetNames = namesArray[0];
var indexSheetIds = namesArray[1];
printIndex(indexSheet,indexSheetNames,indexSheetIds);
}
Make sure you create a Sheet with the name "Index" and then the following code will update column A with all Sheets and directly link to the respective sheet. It will add new sheets with the name and url below existing entries. And if a sheet has changed its name (but not its id), then it will update the sheet name.
function updateIndex(){
const ACTIVE = SpreadsheetApp.getActive()
const spreadsheetURL = ACTIVE.getUrl()
const currentIndexSheet = ACTIVE.getSheetByName("Index")
// Empty the sheet
currentIndexSheet.getRange("A1:A").clearContent()
// We will populate this with all rows
let outputRows = []
// List Sheets which should not be listed
let skipSheets = ["Index", "Another Sheet to Skip"]
// Add Header Row
outputRows.push(['="Linked Sheet"'])
// Get all Sheet and add them to the outputRows using a Hyperlink
ACTIVE.getSheets().forEach( sheet => {
// Skip certain sheets which are defined above
if( skipSheets.indexOf(sheet.getName()) != - 1) return
outputRows.push([`=HYPERLINK("${spreadsheetURL}#gid=${sheet.getSheetId()}", "${sheet.getName()}")`])
})
// Write everything to Index
currentIndexSheet.getRange(1,1, outputRows.length).setFormulas(outputRows)
}

Google Sheets - Modify Code To Act Dynamically When Using Slice

I am using the splice Script to run code over numerous tabs
function Slice_TABS() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets().slice(7); // get 8th sheet onwards
sheets.forEach(ss=>{
Donor();
})}
and am trying to use the below code to bring filtered results up to 10 per SKU. When i name the sheet the code works fine but i need it to run on the ActiveSpreadsheet. I am getting the following error
" Type Error: sheet.getRange is not a function" (BOLD Below)
function GetNSKUSAG11() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheets();
*//Building the matching set.
**var matchingValues = sheet.getRange('AF3:AF').getValues().filter(value => value[0] !=
'').map(nonBlankValue => [nonBlankValue[0], 0]);***
//Filtering out the desired number of values
var values = sheet.getRange("LOCATIONS!$A$3:$B").getValues().filter(value =>
advancedFilter(value[0], matchingValues));
let cols = values[0].length;
let rows = values.length;
//Printing out the found rows starting from AI
sheet.getRange(2, 36, rows, cols).setValues(values);
}
function advancedFilter(value, toMatch) {
let matched = toMatch.filter(couple => couple[0] === value);
if (matched.length > 0) {
if (matched[0][1]<10) { //Here you can decide when to stop returning SKUs
matched[0][1] += 1;
return true;
}
}
return false;
}
I think I am close.
Answer to this question - thanks to Tanaike is
Change the code as per below
var sheet = ss.getSheets()
to
var sheet = ss.getActiveSheet()

Search column and display row

I need to publish individual's exam result from this google sheet. Spreadsheet. I've found a code that can do this if I run the app URL with "?id=1" like but it displays only the name. I need to show the marks (Column C to G) also. The code I used is
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1L1Qu6QCaDucr4Jy5eOAnQkX-wpYjz6eevqAMzBc72iQ/edit#gid=0");
var sheet = ss.getSheetByName("Sheet1");
function doGet(e){
return search(e) ;
}
function doPost(e){
return search(e) ;
}
function search(e){
var id = e.parameter.id;
var values = sheet.getRange(2, 1, sheet.getLastRow(),sheet.getLastColumn()).getValues();
for(var i = 0;i<values.length; i++){
if(values[i][0] == id ){
i=i+2;
var name = sheet.getRange(i,3).getValue();
return ContentService.createTextOutput(name).setMimeType(ContentService.MimeType.TEXT);
}
}
return ContentService.createTextOutput("Id not found").setMimeType(ContentService.MimeType.TEXT);
}
How can I show the whole row instead of a single cell?
This works for me like a charm
/**
*
* #param {*} e
*/
function search(e) {
var id = e.parameter.id;
var values = sheet
.getDataRange()
.getValues()
.filter(function(row) {
return row[0] == id;
});
var content = JSON.stringify(values);
return ContentService.createTextOutput(content).setMimeType(
ContentService.MimeType.TEXT
);
}
I can expand the sheet as I need and I don't need charge the script at the same time
If you expect to return "Id not found" try
var content = values.length ? JSON.stringify(values) : "Id not found";
instead.

Cell reference out of range, google sheets

I'm getting this error while running this sheet.
Cell reference out of range (line 81, file "genreportSE")
I don't know why it says it's 'out of range'.
I tried to used 'copyvalues'. I saw a script where you can't really "print" a range, but you can create another spreadsheet, copy that range, then print that sheet and delete it.
How should I accomplish this?
function genreportSE() { // This function let us read the value of a cell from a sheet and change the value of another cell in a different sheet
var ss = SpreadsheetApp.getActive(); //ss stands for spreadsheet, this is the active spreadsheet
var clientsheet = ss.getSheetByName('Clientes SE');
var gensheet = ss.getSheetByName('Generador SE');
var clienttable = clientsheet.getDataRange();
var numberofservices = clienttable.getNumRows(); //The number of services in the Clientes sheet
var error1;
var error2;
var rangetocheck1;
var rangetocheck2;
var client;
var clientname;
var i=0;
var reportswitherrors = []; //Array for faulty reports
var email ='jvaldez#galt.mx';
var subject = "Reporte de producción y consumo - " + (new Date()).toString();
var body = "TEXT" ;
for (i=0;i<=2;i++){
gensheet.getRange('B2').setValue(clientsheet.getRange(i+2,1).getValue()); //This will change the cell "B2" in "Generador SE" to the current service number for the report generation
Utilities.sleep(3000); //A timer to let the importdata function get the data from the SE server in miliseconds
client = gensheet.getRange('B4').getValue;
clientname = String(client);
rangetocheck1 = gensheet.getRange('B8:C14').getValues(); //Data range that could present calculation errors ********
rangetocheck2 = gensheet.getRange('H8:H14').getValues(); //Data range that could present calculation errors ********
if(String(rangetocheck1).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck1
error1 = false;
} else {
error1 = true;
};
if(String(rangetocheck2).indexOf('#N/A') == -1) { //This checks if there are any errors in rangetocheck2
error2 = false;
} else{
error2 = true;
};
if(error1||error2){
reportswitherrors.push(clientsheet.getRange(i+2,1).getValue()); //This appends the current service number to the faulty services array
} else {
// Convert individual worksheets to PDF
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
newSpreadsheet.getSheetByName('Sheet1').activate();
var newsheet = newSpreadsheet.getSheetByName('Sheet1');
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)
var pdf = DriveApp.getFileById(newSpreadsheet.getId()).getAs('application/pdf').getBytes();
var attach = {fileName:'Weekly Status.pdf',content:pdf, mimeType:'application/pdf'};
MailApp.sendEmail(email, subject, body, {attachments:[attach]});
DriveApp.getFileById(newSpreadsheet.getId()).setTrashed(true);
}
};
Logger.log(reportswitherrors);
}
It appears that you've got your row & column dimensions flipped between function calls. (Because Google decided to be inconsistent with the order of them...)
This line calls create(name, rows, columns):
var newSpreadsheet = SpreadsheetApp.create("Spreadsheet to export",15,60);
You've created a spreadsheet with 15 rows and 60 columns.
A bit further along, probably on line 81, copyValuesToRange(sheet, column, columnEnd, row, rowEnd) gets invoked:
var genRange = gensheet.getRange('A1:H50').copyValuesToRange(newsheet,0,10,0,55)

Create a new sheet in a Google Sheets with Google Apps Script

How to create a new sheet in a Google Sheets with Google Apps Script?
I know it seems obvious but I just want to create a new sheet with a specific name.
Surprisingly I didn't find any clear and quick answer.
So here is my code:
function onOpen() {
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName("Name of your new sheet");
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName("Name of your new sheet");
}
Finally, note that this new sheet will be automatically the active one.
Here is a simple example:
var name = (new Date()).toLocaleDateString();
SpreadsheetApp.getActiveSpreadsheet().insertSheet(name);
I'd recommend this method.
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.insertSheet('My New Sheet');
Where 'My New Sheet' is the name you want it to be.
Here's the way I did it...
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var newSheet = activeSpreadsheet.insertSheet();
newSheet.setName("whatever");
I have been looking at the answers and although they answer the question of how to create a sheet and give it a name, none shows how to make that name variable by passing it as a parameter
This is an example of a function passing a variable to the createNewSheet function:
(The function that has to be executed is setNameAndCreateSheet)
function createNewSheet(sheetName){
// The sheetName parameter has to be passed to the function when it's called
let activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let newSheet = activeSpreadsheet.insertSheet();
newSheet.setName(sheetName); // We sheet will be called as the string of the parameter
}
function setNameAndCreateSheet(){
// This will get the email of the user executing the script
const userEmail = Session.getEffectiveUser().getEmail();
// This will get the current date
const date = Utilities.formatDate(new Date(), "GMT-3", "dd/MM/yyyy");
// We are making the string that will be passed to the createNewSheet function
const sheetName = date + " - " + userEmail;
// sheetName will return something like: "04/11/2021 - youremail#gmail.com"
// This will execute the function that creates the sheet, and the name will be settled to the parameter passed (sheetName)
createNewSheet(sheetName);
}
In this example, the parameter passed to the createNewSheet function is the concatenation of these two strings (date - useremail), but it could be anything.
This function does that with more options, where you can select:
The new sheet name
Add the sheet to which spreadsheet
After (or before) which sheet (index or name)
Choose to add a counter or delete if the new name is already used before.
function addSheet(shName, ss, aftr, bfr, delMode) {
var sh = null;
// Define the optional argument ss (Spreadsheet) if missing
if (ss == null) ss = SpreadsheetApp.getActiveSpreadsheet();
// If no new name is given, use "Sheet" and deactivate delete mode
if (shName == null) {
delMode = null
shName = "Sheet"
}
if (delMode == null) {
// If delete mode is inactive, use a counter if the name already exists (like "Sheet (2)")
var n = 1;
var nShName = shName;
while (ss.getSheetByName(nShName) != null) {
n += 1;
nShName = shName + ' (' + n + ')';
}
shName = nShName;
} else {
// otherwise, delete on sight!
sh = ss.getSheetByName(shName);
if (sh != null) ss.deleteSheet(sh);
}
// Where to add the new sheet:
if (aftr == null) {
if (bfr == null) {
// If both after and before arguments are missing, add the new sheet to the end of sheets list.
n = ss.getSheets().length;
// Uncomment the next one if you want it to be added after the active sheet
// n = ss.getActiveSheet().getIndex();
} else if (typeof(bfr) == 'string') {
// If before argument was given as string (Sheet name), try to find it.
n = getSheetOrder(bfr) - 1
} else {
// otherwise use the given number
n = bfr - 1
}
} else if (typeof(aftr) == 'string') {
// If after argument was give as string (Sheet name), try to find it.
n = getSheetOrder(aftr);
} else {
// otherwise use the given number
n = aftr;
}
// Note: if both after and bfr are given, bfr is ignored.
// Fix the case where only before argument is gevin as a string,but no sheet with that name is found
if (n < 0) n = 0;
// Fix the case where the numbers given were too high
if (n > ss.getSheets().length) n = ss.getSheets().length;
// Do the action!
return ss.insertSheet(shName, n);
}
function getSheetOrder(shName, ss) {
// returns 0 if sheet is missing, or the sheet index if found.
if (ss == null) ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getSheetByName(shName);
if (sh == null) return 0;
return sh.getIndex();
}
Tests:
addSheet() adds a sheet named "Sheet" (or "Sheet (2)", "Sheet (3)",...) to the end of the file (or after the active sheet if you edit the code)
addSheet("My Sheet", null, 3, null, 1) adds a sheet names "My Sheet" after the third sheet in the active spreadsheet, and deletes the old sheet with the same name if found.