Search column and display row - google-apps-script

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.

Related

Showing result from specific column in Google App script

I am building dependent down, I would like to get the result from column "D" after I choose select data from Column A to C.
Here is my script
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate()
.setTitle("A")
.addMetaTag('viewport','width=device-width , initial-scale=1')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
function getData() {
//
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("B")
var data = sheet.getDataRange().getDisplayValues().slice(1)
var result = data.getRange(row,4);
var obj ={}
data.forEach(([colA,colB,colC])=>{
const firstCol = obj[colA]
if(!firstCol){
obj[colA] = {}
obj[colA][colB] = [colC]
}else{
const secondCol = firstCol[colB]
if(!secondCol){
firstCol[colB] = [colC]
}else{
secondCol.push(colC)
}
}
})
Logger.log(obj)
return obj
}```
I would like to get the sciprt to show data from Column "D"

Google Sheets Script: Insert New Row In Named Range

I use Named Ranges a lot, for sheets Data Validation etc. I'm adding 'Saved Comparisons' (cell H3) to a stock comparison sheet:
Although untested yet, I've almost created a function to Save or Update the current comparison to a Named Range Compare_Saved:
However, I'm stuck at how to add a New Row to the Named Range, and/or then select the required Row in the Range to update it. The problem is described in the indented section of the code below, commented with // ***** (may need to scroll down to see it):
function compareSaveNew() { compareSave('new'); } // button call
function compareSaveUpdate() { compareSave('update'); } // button call
function compareSave(mode){
const srcSheet = 'Compare';
const dataSheet = 'Data';
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sSrc = ss.getSheetByName(srcSheet);
const sData = ss.getSheetByName(dataSheet);
const ui = SpreadsheetApp.getUi();
var promptMsg='', data, rv, rUpdate;
// Check/confirm if adding new, or updating
if ( mode == 'update' && src.getRange('Compare_SavedUsed') == 'Select Comparison' ) {
promptMsg = 'A Saved Comparison has not been selected. Cancel, or enter a New Name: ';
} else if ( mode == 'new' && src.getRange('Compare_SavedUsed') != 'Select Comparison' ) {
promptMsg = 'A Saved Comparison has been selected. Cancel and use [UPDATE],\nOR\n' +
'enter a New Name if you want to Save a new Comparison based on this one: ';
} else {
promptMsg = 'New Name for Saved Comparison: ';
}
var newName = ui.prompt('New Name for Saved Comparison: ');
if (!newName) {return;} // Exit, Save/Update cancelled
// Check newName is unique
data = sData.getRange('Compare_Saved');
for(var i = 0; i<data.length;i++){
if( data[i][0] == newName ) { rv = true; break; }
}
if (rv) {ui.alert('"' + newName + '" aleady exists.'); return;} // Exit, new name exists
// *****
// Create New row in Named Range
if (mode=='new') {
// add row to range - how ???
}
// Get new/existing row as range from Named Range to update
// var rUpdate = sData.getRange( ??? );
// *****
var newSave=[];
newSave.push([
newName,
'', // left blank, so name can overflow to this col in Data sheet
sSrc.getRange('Compare_Period'),
sSrc.getRange('Compare_Frequency'),
sSrc.getRange('Compare_From'),
sSrc.getRange('Compare_To'),
sSrc.getRange('Compare_Index'),
sSrc.getRange('Compare_Stock1'),
sSrc.getRange('Compare_Stock2'),
sSrc.getRange('Compare_Stock3'),
sSrc.getRange('Compare_Stock4')
]);
rUpdate.setValues(newSave);
return true;
}
Apologies if this post is a bit verbose, but any pointers would be appreciated.
How about remove() and addNew() namedRanges
Adapted code I found by #Cooper (thanks!) for my specific needs, which returns new row num, or row num to be updated, depending on mode:
function compareAddOrFindRowInNR(namedRange,newName,mode){
// Purpose: Add a new row in Named Range and return row num, OR return existing row num
// Credit: #Cooper at https://stackoverflow.com/a/60011251/190925
const ss = SpreadsheetApp.getActiveSpreadsheet();
// Get the NR
var nrAll = ss.getNamedRanges()
for (var i=0; i<nrAll.length; i++) {
if( nrAll[i].getName() == namedRange ) {
var nr = nrAll[i];
var h = nr.getRange().getHeight(); Logger.log('h: '+h)
var row= nr.getRange().getRow(); Logger.log('row: '+row)
var w = nr.getRange().getWidth(); Logger.log('w: '+w)
var col= nr.getRange().getColumn(); Logger.log('col: '+col)
var sh = nr.getRange().getSheet(); Logger.log('sh: '+sh)
// Create new row in NR, or find existing row
if (mode=='new') {
var updateNR = sh.getRange(row,col,h+1,w);
ss.setNamedRange(namedRange,updateNR); // doesn't set Sheet?
var rowUpdate = row+h;
} else {
data = nr.getRange().getValues();
for (var i=0; i<data.length; i++) {
Logger.log(data[i][0]);
if( data[i][0] == newName ) {
var rowUpdate = row+i;
break;
}
}
}
break;
}
}
Logger.log('rowUpdate: '+rowUpdate);
return rowUpdate;
}

Replace character using google apps script

I have a column which is a date in string format with this format
2020-02-23T12:14:06+0000
And i want to remove the T and replace it with space and also just completely remove the last part (+0000)
I have tried this
var A1 = CONTENT.getRange("B:B").getValue();
var A1String = A1.toString().replace("T*", "");
but it doesn't work.
Any ideas?
This is the original script in which i want to incorporate it into.
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('sheetname');
var range = sheet.getRange("A:C");
var response = UrlFetchApp.fetch("API CALL");
var dataAll = JSON.parse(response.getContentText());
var dataSet = dataAll.data;
var rows = [],
data;
for (i = 0; i < dataSet.length; i++) {
data = dataSet[i];
rows.push([new Date(),data.created_time,data.message,data.permalink_url,
data.reactions.summary.total_count
,data.comments.summary.total_count,data.insights.data[1].values[0].value,data.insights.data[2].values[0].value,data.insights.data[3].values[0].value,data.insights.data[0].values[0].value['link clicks'],data.insights.data[0].values[0].value['photo view'],data.insights.data[0].values[0].value['other clicks'],data.insights.data[0].values[0].value['video play'],data.insights.data[4].values[0].value,data.insights.data[5].values[0].value,data.insights.data[6].values[0].value,data.insights.data[7].values[0].value["like"],data.insights.data[7].values[0].value["love"],data.insights.data[7].values[0].value["wow"],data.insights.data[7].values[0].value["haha"],data.insights.data[7].values[0].value["sorry"]]); //your JSON entities here
}
Logger.log(rows)
//sheet.getRange(getlastRow() + 1, 1, rows.length, 2).setValues(rows);
sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, 22).setValues(rows);
/**
* Removes duplicate rows from the current sheet.
*/
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheetname');
var data = sheet.getDataRange().getValues();
data.reverse(); //reverses the row order.
var last=sheet.getLastRow();
var newData = new Array();
for(i in data){
//Logger.log(i);
var row = data[i];
//Logger.log(row[5]);
var duplicate = false;
for(j in newData){
//Logger.log(newData[j][3]);
if(row[3] == newData[j][3]){
duplicate = true;
}
}
if(!duplicate){
newData.push(row);
}
}
newData.reverse(); // reverses your data back to its original order.
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
//
//
If you want to remove always the same thing (i.e. "T" and "+0000"), you could use the following script:
The result obtained: 2020-02-23 12:14:06
CODE:
// ---------- Menu ----------
// Add a Menu named Format Date to run the script
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Format Date')
.addItem('Go!', 'FormatDate')
.addToUi();
}
function FormatDate() {
var ss = SpreadsheetApp.getActiveSheet(),
array = [];
ss.getRange("B2:B") // Choose the range here
.getValues()
.forEach(function (dates) {
// "T" is replaced with a space: " " and "+0000" is replace with empty:""
[["T", " "], ["+0000", ""]]
.map(function (a, i) {
return dates = replace(dates.toString(), a[0], a[1])
})
array.push([dates])
});
// You can set a different column to write the data
// Or keep B2:B to overwrite your data
ss.getRange("B2:B")
.setValues(array)
}
function replace(d, a, r) {
return d.indexOf(a) > -1 ? d.split(a)
.join(r) : d;
}
Credit: got inspired by JPV's code to a different question long time ago

How to check if the value exist in google spreadsheet or not using 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

Removing 'undefined' from output before writing to Google Sheets

My script below returns 'undefined' to the Google Sheet when I add dfStatus.error.count to the array to be written.
function getDatafeedStatus() {
var d = new Date();
var ar = [];
for (var a in FEEDS) {
for (var i = 0; i < FEEDS[a].length; i++) {
try {
var dfStatus = ShoppingContent.Datafeedstatuses.get(a, FEEDS[a][i]);
// see https://developers.google.com/shopping-content/v2/reference/v2/datafeedstatuses for detail on this API call
ar.push([d, a, FEEDS[a][i], dfStatus.processingStatus, dfStatus.lastUploadDate, dfStatus.itemsValid, dfStatus.errors.count]);
} catch (e) {
Logger.log(e.message); // check View > Logs after running the script if a feed does not appear to be fetching correctly
}
}
}
appendArrayToSheet(ar, 'status');
}
/**
* Add an array to the bottom of a sheet. If the sheet doesn't exist, it is created.
* #param {array} ar - the array to write
* #param {string} sheetName - the name of the sheet to which to write
*/
function appendArrayToSheet(ar, sheetName){
if (ar.length !== 0 && ar[0].length !== 0){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sheetName);
if (sheet == null) {
sheet = ss.insertSheet();
sheet.setName(sheetName);
};
var range = sheet.getDataRange();
var row = range.getLastRow() + 1;
var newRange = sheet.getRange(row, 1, ar.length, ar[0].length);
newRange.setValues(ar);
}
Any ideas whats wrong with it? I must say I'm not a JavaScript expert. I'm trying modify the code which is already used somewhere else.