Combining 2 Onedit functions ib 1 script - scripting

I have 2 onEdit scripts as detailed below that conflict. I need to somehow combine the two scrpits in to one. The fist script autosorts when column 9 in Worksheet1 is edited.
Question 1: How to make it run if i need the same function aswell but column 11 in Worksheet2?
The other script inserts a row onEdit, however it does this on all worksheets.
Question 2: How to restrict it to run when a certain cell is adited ie:Q2 on Worksheets 1 & 2?
Question 3: How to combine both scrips into 1 script?
I am a complete novice at script writing so please make you ansers as simple as possible, thanks
Scripts I have that work separately:
Script 1 AutoSort
function onEdit(event) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
if(sheet.getName()=='Worksheet1') {
var editedCell = sheet.getActiveCell();
var columnToSortBy = 9;
var tableRange = "a3:Q999";
if(editedCell.getColumn() == columnToSortBy) {
var range = sheet.getRange(tableRange);
range.sort({column: 9, ascending: false});
Browser.msgBox("sort done");
}
}
}
Script 2 InsertRow
var ss = SpreadsheetApp.getActive();
function onEdit() {
var firstRow = 3;
var sh = ss.getActiveSheet();
var lCol = sh.getLastColumn();
var range = sh.getRange(firstRow, 3, 1, lCol);
var formulas = range.getFormulas();
sh.insertRowsAfter(1, 1);
newRange = sh.getRange(firstRow, 3, 1, lCol);
newRange.setFormulas(formulas);
}

I usually make one onEdit function, which will call some other functions one after another:
function onEdit(event) {
myFunction1(event);
myFunction2();
}
function myFunction1(event) {
// do something
}
function myFunction2() {
// do something else
}

Related

Google script to copy specific cell values

I need a little help with a google spreadsheet script. Currently I'm using a script to copy entire row if contition is met(checkbox TRUE/FALSE). If different condition is met(different checkbox), i need to copy that entire row to "Completed" AND the tricky part for me, I need to ONLY copy cells in A,B,P columns in that specific row to sheet "Flash" to position A,B,C.. Could someone help me? Thanks!
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Orders" && r.getColumn() == 9 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Completed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
} else if(s.getName() == "Orders" && r.getColumn() == 15 && r.getValue() == true) {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Completed");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
var targetSheet = ss.getSheetByName("Flash");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).copyTo(target);
s.deleteRow(row);
}
}

BigQuery Result save as google sheets through api

In Google BigQuery WebUI, it shows query result screen after executing a query, and it shows the button of "Save as Google Sheets". I like this feature but would like to automate this, is there such function through the REST API that I could do?
It doesn’t seem like there is a straightforward way to do this directly with the BigQuery API. There are few workarounds for this though:
You can use the BigQuery API to query your data and then the GoogleSheets API to upload it to Google Sheets.
You can use Google Apps Script. If you go to this link, you click on “New Script”, you can run the code below. You can adapt this to your needs. You can also add a trigger to run the script every hour/minute …
Here the code snippet from this link:
function runQuery() {
// Replace this value with the project ID listed in the Google
// Cloud Platform project.
var projectId = 'XXXXXXXX';
var request = {
query: 'SELECT TOP(word, 300) AS word, COUNT(*) AS word_count ' +
'FROM publicdata:samples.shakespeare WHERE LENGTH(word) > 10;'
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
if (rows) {
var spreadsheet = SpreadsheetApp.create('BiqQuery Results');
var sheet = spreadsheet.getActiveSheet();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log('Results spreadsheet created: %s',
spreadsheet.getUrl());
} else {
Logger.log('No rows returned.');
}
}

Reference entire column, not just one cell Google Sheets

The following will send email notification if F6 is edited on a google sheet. I need help making it send a notification if any cell in column F is edited, not just one cell. I tried ('F6,F7, etc) and I tried F:F, those don't work.
function emailNotification(e) {
var sheet = e.source.getActiveSheet();
if (sheet.getName() !== 'Sheet1' || e.range.getA1Notation() !== ('F6')) return;
return;
var recipient = "mail#google.com";
var subject = 'SUBJECT';
var body = ' BODY OF MAIL ';
MailApp.sendEmail(recipient, subject, body);
};
Please help, I don't know where I'm going wrong. Otherwise the script works like a charm for a single cell. Just not the whole column
This will run code if any cell in column F of Sheet1 is edited.
function onEdit(e)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetName= sheet.getSheetName();
if(sheetName=="Sheet1"){
var editRange = sheet.getActiveRange();
var editRow = editRange.getRow();
var editCol = editRange.getColumn();
var lr = sheet.getLastRow()
var range = sheet.getRange("F1:F"+lr);
var rangeRowStart = range.getRow();
var rangeRowEnd = rangeRowStart + range.getHeight()-1;
var rangeColStart = range.getColumn();
var rangeColEnd = rangeColStart + range.getWidth()-1;
if (editRow >= rangeRowStart && editRow <= rangeRowEnd
&& editCol >= rangeColStart && editCol <= rangeColEnd)
{
Logger.log("Run Code")
//YOUR CODE HERE
}}}

Optimize Google Script for Hiding Columns

These two scripts are incredibly slow. I work with a data set of about 32 columns by 1000 rows ( growing pretty rapidly ).
I've read and even used code for treating data like an array so that you can make only one call to google-services, but I'm not sure how that can help me with this case.
I need to hide certain columns depending on which person is using the google sheet
Here is the actual code:
function HideColumns(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("A1");
sheet.hideColumn(range);
range = sheet.getRange("C1:E1");
sheet.hideColumn(range);
range = sheet.getRange("G1");
sheet.hideColumn(range);
range = sheet.getRange("I1");
sheet.hideColumn(range);
range = sheet.getRange("K1");
sheet.hideColumn(range);
range = sheet.getRange("Q1:Z1");
sheet.hideColumn(range);
range = sheet.getRange("AC1:AG1");
sheet.hideColumn(range);
}
function ShowColumns(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("A1");
sheet.unhideColumn(range);
range = sheet.getRange("C1:E1");
sheet.unhideColumn(range);
range = sheet.getRange("G1");
sheet.unhideColumn(range);
range = sheet.getRange("I1");
sheet.unhideColumn(range);
range = sheet.getRange("K1");
sheet.unhideColumn(range);
range = sheet.getRange("Q1:Z1");
sheet.unhideColumn(range);
range = sheet.getRange("AC1:AG1");
sheet.unhideColumn(range);
}
unfortunately hiding columns is a "spreadsheet only" function, no way to make it faster or in batch...
maybe you could imagine a custom UI (built with UiApp or HTMLService) to show only the user relevant data ? but that might not be possible, depending on how much you need spreadsheet specific features..., not speaking of the work it might represent.
For the ShowColumns() script, are you just needing to unhide all columns in the sheet? If so, you could at least simplify that one a bit:
function ShowColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("1:1");
sheet.unhideColumn(range);
}
You can use batch request to Sheets API (enable advanced service first) to hide/unhide multiple columns in one API call:
function changeHideForColumnsOptimized(ssId, sheetId, columns, hide)
{
let requests = [];
columns.map(col => {
// get column index/indexes
let colArray = col.split(':');
let startIndex = letterToColumn(colArray[0]) - 1;
let endIndex = letterToColumn(colArray[colArray[1] ? 1 : 0]) - 1;
let hiddenByUser = hide ? true: false;
requests.push({
updateDimensionProperties: {
range: {
sheetId: sheetId,
dimension: 'COLUMNS',
startIndex: startIndex, // start index is inclusive
endIndex: endIndex + 1 // end index is exclusive
},
properties: {
hiddenByUser: hiddenByUser
},
fields: 'hiddenByUser'
}
})
});
Sheets.Spreadsheets.batchUpdate({requests: requests}, ssId);
}
// via https://stackoverflow.com/a/21231012/555121
function letterToColumn(letter)
{
var column = 0, length = letter.length;
for (var i = 0; i < length; i++)
{
column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
}
return column;
}
An then use it like this:
function HideColumns(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
let columnsToHide = ['A', 'C:E', 'G', 'I', 'K', 'Q:Z', 'AC:AG'];
changeHideForColumnsOptimized(ss.getId(), sheet.getSheetId(), columnsToHide, true);
}
function ShowColumns(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
let columnsToUnHide = ['A', 'C:E', 'G', 'I', 'K', 'Q:Z', 'AC:AG'];
changeHideForColumnsOptimized(ss.getId(), sheet.getSheetId(), columnsToUnHide, false);
}
This answer is based on these two questions:
Hide column with Sheets API call
Convert column index into corresponding column letter

Dojo Datagrid - Get the row number

I am trying to retrieve the line number in dojo data grid. rowIndex function would not help me much because I need the 'line number' and NOT 'row number' when sorted.
The scenario:
I would like to set the focus on one specific row and this focus should remain even after sorting. But if I use the code below, it does not select the correct row.
For example, the index 1 is on the 5th line after sorting. However, the e.item.id still remains as 1, expected is 5.
calendar.on("itemClick", function (e)
{
MyGrid.doclick({ rowIndex: e.item.id });
MyGrid.scrollToRow(e.item.id);
});
Additionally, I also tried...
calendar.on("itemClick", function (e)
{
var identity = MyGrid._by_idx[e.item.id].idty;
var gridItem = MyGrid.getItem(identity);
var gridItemIndex = MyGrid.getItemIndex(gridItem);
MyGrid.doclick({ rowIndex: gridItemIndex });
MyGrid.scrollToRow(e.item.id);
});
Could you please let me know how to get the correct row after fitering? I thank you for your time.
Wishes,
Santosh
Okay, I figured out the answer.
GetGridItemIndexByGridItem = function (gridItem) {
var indexLength = MyGrid._by_idx.length;
var element = null;
var gridItemIndex = -1;
for (var i = 0; i < indexLength; i++) {
element = MyGrid._by_idx[i];
if (element.item.Guid == gridItem.Guid) {
gridItemIndex = i;
}
}
return gridItemIndex;
}
Best Wishes