In Google Sheets, if you want to have the dynamic dropdown, that is data validation based on the some other (adjacent) cell, then it is possible using Google Apps Script.
Consider the following example:
Screenshot of Sheet "ROI" which has the data from which we have to get the value of dependent data validation:
Screenshot of Sheet "Sales" in which Data Validation is required:
Following is the script code which will get us the desired dynamic data validation (drop down):
//////////////////////////////////////////////////////
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getActiveSheet();
if( activeSheet.getName() === 'Sales' ) {
var activeCell = activeSheet.getActiveCell();
var activeRow = activeCell.getRow();
if( activeRow >= 3 ) {
var activeColumn = activeCell.getColumn();
if( activeColumn === 5 || activeColumn === 6 ) {
var activeCellValue = activeCell.getValue();
var v = ss.getSheetByName('ROI').getDataRange().getValues();
if( activeColumn === 5 ) {
var f = v.filter(function (currentValue,index,arr) {
return arr[index][0] === activeCellValue
});
var option = f.map(function (currentValue,index,arr) {
return arr[index][1]
});
}
else if( activeColumn === 6 ) {
var prevCellValue = activeSheet.getRange(activeRow,activeColumn-1).getValue();
var f = v.filter(function (currentValue,index,arr) {
return arr[index][0] === prevCellValue && arr[index][1] === activeCellValue
});
var option = f.map(function (currentValue,index,arr) {
return arr[index][2]
});
}
var dv = SpreadsheetApp.newDataValidation();
dv.setAllowInvalid(false);
//dv.setHelpText("Some help text here");
dv.requireValueInList(option, true);
activeSheet.getRange(activeRow,activeColumn+1).setDataValidation(dv);
}
}
}
};
//////////////////////////////////////////////////////
iGoogleDrive
Friday, July 26, 2019
Monday, June 3, 2019
Google Apps Script to delete all the filter views in a spreadsheet
If you have created lots of filter views in a Google Spreadsheet and find it hard to delete all of them one by one manually then you can use the following Google Apps Script code to delete all filter views in one go!
function deleteAllFilterViews() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var id = ss.getId();
var myFilterViews = Sheets.Spreadsheets.get(id, {
ranges: 'Sheet1',
fields: 'sheets/filterViews/filterViewId',
}).sheets[0].filterViews;
Sheets.Spreadsheets.batchUpdate({
requests: myFilterViews.map(function(e) {
return { deleteFilterView: { filterId: e['filterViewId'] } };
}),
},id);
};
Note:
Paste the above code in the script editor of your spreadsheet and run the function "deleteAllFilterViews"You will need to enable "Google Sheets API", it can be done by navigating to "Resources" > "Advanced Google services..." in the script editor of your spreadsheet.
Also you will need to enable the service in GCP Console:
https://console.cloud.google.com/apis/
function deleteAllFilterViews() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var id = ss.getId();
var myFilterViews = Sheets.Spreadsheets.get(id, {
ranges: 'Sheet1',
fields: 'sheets/filterViews/filterViewId',
}).sheets[0].filterViews;
Sheets.Spreadsheets.batchUpdate({
requests: myFilterViews.map(function(e) {
return { deleteFilterView: { filterId: e['filterViewId'] } };
}),
},id);
};
Note:
Paste the above code in the script editor of your spreadsheet and run the function "deleteAllFilterViews"You will need to enable "Google Sheets API", it can be done by navigating to "Resources" > "Advanced Google services..." in the script editor of your spreadsheet.
Also you will need to enable the service in GCP Console:
https://console.cloud.google.com/apis/
Friday, September 15, 2017
Convert ##m ##s formatted text to a number in seconds
Question:
Hello!
I'm hoping to find some way to convert this data into numbers so I can use those numbers for other formulas. I have checked the reporting system of the program I am pulling this info from and I have no choice but to pull this data in this format.
Here's the raw data:
Solution:
If you have following data in Sheet1:
Then you can try the following formula in cell B2 of "Sheet2":
=ARRAYFORMULA(IFERROR(REGEXEXTRACT(Sheet1!B2:C4,"(\d+)m")*60)+IFERROR(REGEXEXTRACT(Sheet1!B2:C4,"(\d+)s")))
Hello!
I'm hoping to find some way to convert this data into numbers so I can use those numbers for other formulas. I have checked the reporting system of the program I am pulling this info from and I have no choice but to pull this data in this format.
Here's the raw data:
Name | Response Time | Duration |
Agent A | 1m 58s | 19m 27s |
Agent B | 1m 3s | 18m 7s |
Agent C | 49s | 16m 27s |
and I would like to automatically convert it to this format:
Name | Response Time | Duration |
Agent A | 118.00 | 1167 |
Agent B | 63.00 | 1087 |
Agent C | 49.00 | 987 |
Can someone suggest a formula to do this? I have attempted to change the cells from "Automatic" to "Duration" or "Number", and nothing actually converts the numbers at all.
Solution:
If you have following data in Sheet1:
Then you can try the following formula in cell B2 of "Sheet2":
=ARRAYFORMULA(IFERROR(REGEXEXTRACT(Sheet1!B2:C4,"(\d+)m")*60)+IFERROR(REGEXEXTRACT(Sheet1!B2:C4,"(\d+)s")))
Saturday, August 5, 2017
Google Sheet Script to Navigate various HTML Pages
Here is the Google Sheet Script to Navigate various HTML Pages by passing the needed data via URL parameter.
Screencast:
Following is the code for "Code.gs":
function doGet(e) {
var htmlPage,count;
e.parameter.page==null ? htmlPage="index" : htmlPage = e.parameter.page;
e.parameter.count==null ? count=0 : count = e.parameter.count;
var html = HtmlService.createTemplateFromFile(htmlPage);
html.counter = count;
var htmlx = html.evaluate();
return htmlx;
};
function getScriptUrl() {
var url = ScriptApp.getService().getUrl();
return url;
};
Following is the code for "index.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I'm Index!
<br><br>
<a href='<?=url?>?page=apple&count=<?!= ((counter*1)+1) ?>'>
<input name="apple" id="apple" type="button" value="Apple Page"></a>
<br><br>
<a href='<?=url?>?page=google&count=<?!= ((counter*1)+1) ?>'>
<input name="google" id="google" type="button" value="Google Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Following is the code for "apple.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I am Apple!
<br><br>
<a href='<?=url?>?page=index&count=<?!= ((counter*1)+1) ?>'>
<input name="index" id="index" type="button" value="Index Page"></a>
<br><br>
<a href='<?=url?>?page=google&count=<?!= ((counter*1)+1) ?>'>
<input name="google" id="google" type="button" value="Google Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Following is the code for "google.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I am Google!
<br><br>
<a href='<?=url?>?page=apple&count=<?!= ((counter*1)+1) ?>'>
<input name="apple" id="apple" type="button" value="Apple Page"></a>
<br><br>
<a href='<?=url?>?page=index&count=<?!= ((counter*1)+1) ?>'>
<input name="index" id="index" type="button" value="Index Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Screencast:
Following is the code for "Code.gs":
function doGet(e) {
var htmlPage,count;
e.parameter.page==null ? htmlPage="index" : htmlPage = e.parameter.page;
e.parameter.count==null ? count=0 : count = e.parameter.count;
var html = HtmlService.createTemplateFromFile(htmlPage);
html.counter = count;
var htmlx = html.evaluate();
return htmlx;
};
function getScriptUrl() {
var url = ScriptApp.getService().getUrl();
return url;
};
Following is the code for "index.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I'm Index!
<br><br>
<a href='<?=url?>?page=apple&count=<?!= ((counter*1)+1) ?>'>
<input name="apple" id="apple" type="button" value="Apple Page"></a>
<br><br>
<a href='<?=url?>?page=google&count=<?!= ((counter*1)+1) ?>'>
<input name="google" id="google" type="button" value="Google Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Following is the code for "apple.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I am Apple!
<br><br>
<a href='<?=url?>?page=index&count=<?!= ((counter*1)+1) ?>'>
<input name="index" id="index" type="button" value="Index Page"></a>
<br><br>
<a href='<?=url?>?page=google&count=<?!= ((counter*1)+1) ?>'>
<input name="google" id="google" type="button" value="Google Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Following is the code for "google.html":
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var url = getScriptUrl();?>
Hello I am Google!
<br><br>
<a href='<?=url?>?page=apple&count=<?!= ((counter*1)+1) ?>'>
<input name="apple" id="apple" type="button" value="Apple Page"></a>
<br><br>
<a href='<?=url?>?page=index&count=<?!= ((counter*1)+1) ?>'>
<input name="index" id="index" type="button" value="Index Page"></a>
<br><br>
You have clicked
<input type="text" id="label" name="label" value="<?!= (counter*1) ?>" readonly="readonly"
style="text-align:center;width:20px;font-weight:bold;border:none;background:transparent;"/>
times
</body>
</html>
Monday, July 3, 2017
Google Sheet Script for border style
Question:
Solution:
Try the following script code:
////////////////////////////////////////
function fillBorders() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Sheet1");
var r = s.getRange("D69:J79");
var v = r.getValues();
var firstRow = r.getRow();
var lastRow = r.getLastRow();
var lastFilledRow = lastRow;
r.setBorder(false,false,false,false,false,false);
for(var i=v.length-1;i>=0;i--) {
var isRowBlank = true;
for(var j=0;j<v[0].length;j++) {
if(v[i][j]!="") {
isRowBlank = false;
lastFilledRow = firstRow + i;
break;
}
}
if(isRowBlank==false)
break;
}
s.getRange("D"+firstRow+":J"+lastFilledRow).setBorder(true,true,true,true,true,true);
SpreadsheetApp.flush();
};
////////////////////////////////////////
in the above script code, change the sheet name "Sheet1" as per your need.
I have columns and rows: D69:J79 filled with data, data in rows is changing on daily basis, one day it’s D69:J79, another it’s shorter D69:J77 or D69:J75 etc, rows below are blanks accordingly, columns stay the same.
I want script to make regular square line border around this data, but with one rule - bottom line of square should be right below latest row with data. And left and right borders lenght should be fitted to rows with data only as well.
I am total noob in scripts, could somebody help me with proper script for this?
And i hope this script can be set to autorun, so i don’t have to run it each time.
Or maybe there is some other solution more simple :)
Solution:
Try the following script code:
////////////////////////////////////////
function fillBorders() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Sheet1");
var r = s.getRange("D69:J79");
var v = r.getValues();
var firstRow = r.getRow();
var lastRow = r.getLastRow();
var lastFilledRow = lastRow;
r.setBorder(false,false,false,false,false,false);
for(var i=v.length-1;i>=0;i--) {
var isRowBlank = true;
for(var j=0;j<v[0].length;j++) {
if(v[i][j]!="") {
isRowBlank = false;
lastFilledRow = firstRow + i;
break;
}
}
if(isRowBlank==false)
break;
}
s.getRange("D"+firstRow+":J"+lastFilledRow).setBorder(true,true,true,true,true,true);
SpreadsheetApp.flush();
};
////////////////////////////////////////
in the above script code, change the sheet name "Sheet1" as per your need.
Saturday, July 1, 2017
Google Sheet Script to extract URL from a Cell containing function HYPERLINK
In Google Sheet, if you have a cell or a range containing functions HYPERLINK and if you want to extract URL(s) from it then you can do it with the help of following script:
/////////////////////////////////////////////////
function extractURL() {
var activeRange = SpreadsheetApp.getActiveRange();
var activeSheet = activeRange.getSheet();
var formula = activeRange.getFormula();
if(formula=="") return "";
var rangeA1Notation = formula.match(/\((.*)\)/).pop();
var range = activeSheet.getRange(rangeA1Notation);
var f = range.getFormulas();
var v = range.getValues();
for(var i=0;i<f.length;i++) {
for(var j=0;j<f[0].length;j++) {
if(f[i][j]=="") v[i][j]="";
var matchURL = f[i][j].match(/\"(.*?)\"/);
if(matchURL==null) v[i][j]="";
else v[i][j]=matchURL.pop();
}
}
return v;
};
/////////////////////////////////////////////////
copy the above script code in the script editor of your spreadsheet and then use custom function "=extractURL(A2:A10)" to extract the URLs from the range "A2:A10"
Screenshot:
/////////////////////////////////////////////////
function extractURL() {
var activeRange = SpreadsheetApp.getActiveRange();
var activeSheet = activeRange.getSheet();
var formula = activeRange.getFormula();
if(formula=="") return "";
var rangeA1Notation = formula.match(/\((.*)\)/).pop();
var range = activeSheet.getRange(rangeA1Notation);
var f = range.getFormulas();
var v = range.getValues();
for(var i=0;i<f.length;i++) {
for(var j=0;j<f[0].length;j++) {
if(f[i][j]=="") v[i][j]="";
var matchURL = f[i][j].match(/\"(.*?)\"/);
if(matchURL==null) v[i][j]="";
else v[i][j]=matchURL.pop();
}
}
return v;
};
Screenshot:
Monday, February 20, 2017
Google Script to auto delete old files from a Google Drive Folder
If you are creating auto backup of any file in Google Drive using script ( either daily or on any edits ), so the number of back up file keeps on increasing. Now, if you want to delete the excessive files, for example if you want to delete all the files except the last 100 back up files, then you can achieve it by using the following script code:
//////////////////////////////////////////////////
function deleteOldSheets() {
var df = DriveApp.getFolderById("xxx_GOOGLE_DRIVE_FOLDER_ID_xxx");
var arr = new Array();
var files = df.getFiles();
while( files.hasNext() ) {
var f = files.next();
arr.push( [ [ f.getId() ] , [ f.getLastUpdated() ] ] );
}
arr.sort( sortFunction );
for( var i=100 ; i<arr.length ; i++ )
DriveApp.getFileById( arr[i][0] ).setTrashed( true );
};
function sortFunction( a , b ) {
var aDate = new Date(a[1]);
var bDate = new Date(b[1]);
if ( aDate === bDate ) return 0;
else if ( aDate < bDate ) return 1;
else return -1;
};
//////////////////////////////////////////////////
The above script code will help you to delete the back up files ( from a Google Drive folder ) which are excessive and not required anymore, the script will move these files to "Trash".
And if you want to automatically run the above script daily, then in the script editor you can set the trigger for it.
NOTE: In the above script you'll need to replace the Google Drive folder Id.
//////////////////////////////////////////////////
function deleteOldSheets() {
var df = DriveApp.getFolderById("xxx_GOOGLE_DRIVE_FOLDER_ID_xxx");
var arr = new Array();
var files = df.getFiles();
while( files.hasNext() ) {
var f = files.next();
arr.push( [ [ f.getId() ] , [ f.getLastUpdated() ] ] );
}
arr.sort( sortFunction );
for( var i=100 ; i<arr.length ; i++ )
DriveApp.getFileById( arr[i][0] ).setTrashed( true );
};
function sortFunction( a , b ) {
var aDate = new Date(a[1]);
var bDate = new Date(b[1]);
if ( aDate === bDate ) return 0;
else if ( aDate < bDate ) return 1;
else return -1;
};
And if you want to automatically run the above script daily, then in the script editor you can set the trigger for it.
NOTE: In the above script you'll need to replace the Google Drive folder Id.
Subscribe to:
Posts (Atom)