How to make each function run on specific page? - google-apps-script

I have two fuctions with same name "myFunction" I run it using google trigers on edit, and I have two sheet how to specify each one for each sheet I use this but it doesn't work
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Copy of Timesheet & Feedback");
//and on the other function
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Visits");

Problem:
getSheetByName() will return the sheet you're looking for, but has nothing to do with the sheet that is being edited to trigger your function.
Solution:
Instead you can use event objects for this purpose. Wrap your whole script inside an if statement checking the name of the sheet. The new function should look something like this:
function myFunction(event) {
var ss = event.range.getSheet();
if (ss.getName() === "Copy of Timesheet & Feedback") {
//your code here
}
}
This way the code will not continue if it doesn't find the sheet it's expecting (the sheet name inside the if statement).
Notes:
Notice the name of the function myFunction(event), "(event)" is important so that we can access the event object to grab the spreadsheet that is being edited.
You won't be able to run the script manually, set up a trigger for "on Edit" and it'll just run automatically.
References:
Event Objects

Related

How to make a trigger that run when there is changes on specific column of different Spreadsheet

I want to ask about how to make a trigger that run when there are changes on different spreadsheet (Source spreadsheet) and on specific column.
I have 2 different spreadsheet (Source Spreadsheet and Target spreadsheet) and the trigger will working on target spreadsheet when there are changes that happened in the specific column of the source spreadsheet. I've just made the code, but it's not working. This code was made on the target spreadsheet. I've already use the onEdit() and onChange() trigger, but nothing happen or run this script.
This code still show some error like:
TypeError: e.source.openById is not a function
Here is the code that I've been made on the target spreadsheet:
function inChange(e) {
var source_spreadsheet_sheetName = e.source.openById('').getName(); //ID of source spreadsheet
var Row = e.source.getActiveCell().getRow();
var Column = e.source.getActiveCell().getColumn();
if (source_spreadsheet_sheetName == '' && Row >= 2 && Column == 2) { //the name of sheet from source spreadsheet and the specific column that has changes on it.
myFunction(); //It will run the process of this myFunction script that I've been made on target spreadsheet
}
}
Your trigger runs. But it fails on first line of code because you're calling a method that you cannot.
Several problems.
Problem #1
var source_spreadsheet_sheetName = e.source.openById('').getName();
the openById probably does not work because source is already of type Spreadsheet so you can directly call getName on it.
It should be
var source_spreadsheet_sheetName = e.source.getName();
Problem #2
There is no getActiveCell on a Spreadsheet, only on a Sheet.
// if you know the sheet name in advance
let sheet = e.source.getSheetByName(YOUR_SHEET_NAME)
// or if you don't, get the active sheet (and don't use the line before)
let sheet = e.source.getActiveSheet()
let row = sheet.getActiveCell().getRow();
let column = sheet.getActiveCell().getColumn();
Problem #3
if (source_spreadsheet_sheetName == ''
A sheet name cannot be empty so this will never be true
source_spreadsheet == '' cannot be true because it's the name of a spreadsheet

Google Script Move selection to specific cell

I'm trying to move the cursor (select cell) when the user clicks on the Sheet.
I've tried so many options and none of them work. The cursor just stays where I click, instead of moving to the specified cell.
Note: I change the background color of the clicked cell just to make sure the selection trigger is working.
function onSelectionChange(e) {
var range = e.range;
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
range.setBackground("blue");
sheet.setCurrentCell("a1").activate();
}
Any help greatly appreciated.
The setCurrentCell method is never executed because you are using the wrong parameter for it.
According to the documentation here, setCurrentCell expects an object of type 'Range`, however, you are passing a string to it.
In order to fix this, you should update your function to this:
function onSelectionChange(e) {
var range = e.range;
var sheet = range.getSheet();
range.setBackground("blue");
var cell = sheet.getRange("A1");
sheet.setCurrentCell(cell);
}
Also, since you are using the onSelectionChange trigger, for best practices, it is recommended you make use of the e event object, hence the modifications above.
Reference
Apps Script Spreadsheet Class - setCurrentCell(cell);
Apps Script Event Objects.

Google Sheets new sheet templating

I'd like every new added sheet (when user presses "+" in lower left corner) to contain some templated information (headers for table). I'm not talking about whole document template, I'd like to make it only for one document. Now for that purpose I use special sheet with template and just duplicate it.
Answer:
While you can't create 'template' sheets to copy from, you can use the onChange() trigger to insert the template to the new sheet as soon as it has been added.
More Information:
As per the documentation on Event Objects, there exists a changeType value in the event object that is generated when the structure of a Spreadsheet is changed:
changeType The type of change (EDIT, INSERT_ROW, INSERT_COLUMN, REMOVE_ROW, REMOVE_COLUMN, INSERT_GRID, REMOVE_GRID, FORMAT, or OTHER).
The INSERT_GRID value can be used to execute some code when a new sheet is added.
Code Example:
For this example, I will assume that you have a template sheet from which you can copy the templated information from, and for this example I will assume it is called Template.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const templateSheet = ss.getSheetByName("Template");
var sheets = ss.getSheets();
function saveSheetNames() {
var names = sheets.map(x => x.getName());
PropertiesService.getScriptProperties().setProperty("sheets", names.toString())
}
function onChange(e) {
if (e.changeType == "INSERT_GRID") {
var rangeToCopy = templateSheet.getDataRange();
var oldSheets = PropertiesService.getScriptProperties().getProperty("sheets").split(",");
var names = sheets.map(x => x.getName());
names.forEach(function(name) {
if (oldSheets.indexOf(name) == -1) {
rangeToCopy.copyTo(ss.getSheetByName(name).getRange(1, 1, rangeToCopy.getNumRows(), rangeToCopy.getNumColumns()));
PropertiesService.getScriptProperties().setProperty("sheets", names.toString());
}
});
}
}
Set up:
The first thing you need to do, after inserting this script into your script editor, is run the function saveSheetNames(). This stores the current sheet names to the script's properties so that when you add a new sheet later, the new sheet can be determined.
Next, you will need to set up an onChange installable trigger.
Follow the Edit > Current project's triggers menu item, and you will have a new page open in the G Suite Developer Hub. Click the + Add Trigger button in the bottom right and set up the trigger settings as follows:
Choose which function to run: onChange
Choose which deployment should run: Head
Select event source: From spreadsheet
Select event type: On change
And press save.
Now, when you add a new sheet with the default + button in the UI, the onChange() function will run, and copy the template sheet to the new sheet. It might take a couple of seconds, but it will be done automatically.
References:
Event Objects | Apps Script | Google Developers

Trouble triggering a macro when a specific cell has a specific value

I'm trying to trigger a google sheet macro / apps script to reformat a sheet when a specific value is entered into a specific cell. I have been working on it to get it to work but without success.
Here is my code;
function onEdit(e) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getRange('C2');
var cellContent = cell.getValue();
if(cellContent === 'Past campaigns - actual cashflows to date only') {
spreadsheet.getRange('7:12').activate();
spreadsheet.getActiveSheet().hideRows(spreadsheet.getActiveRange().getRow(), spreadsheet.getActiveRange().getNumRows());
spreadsheet.getRange('13:13').activate();
}
};
I'm new to macros and apps scripts. I have tried to implement all the suggestions from the following links without success;
How can I get a macro to automatically trigger when a cell reaches a certain value in a Google Sheet?
https://developers.google.com/apps-script/guides/triggers
https://developers.google.com/apps-script/guides/sheets
As #Cooper has said you cannot make a trigger based on a cell value. Only on user changes.
You could try to make the onEdit trigger to execute only inside an if statement. But that's already what you have done.
Try this:
function onEdit(e) {
e.source.toast('Entry');
const sh=e.range.getSheet();
if(sh.getName()!='Sheet Name')return;//you need to change this sheetname
const X=sh.getRange('C2').getValue();
if(X=='Past campaigns - actual cashflows to date only') {
e.source.toast('flag1');
sh.hideRows(e.range.rowStart,e.range.rowEnd-e.range.rowStart+1);
}
}
It's not necessary to use activate in most scripts and certainly in this one since it has to finish in 30 seconds. They use activate in macros because they are following you actions as you move around the screen. But in a script, generally to don't want to interact with the screen very much because it slows down the script and it doesn't really accomplish anything.
I'm currently using in a script that run when a Spreadsheet opens up because it has a lot rows in it and I want it to go down to the last row. So activate is useful because I don't have to scroll down to the last row every time I open the spreadsheet.
try it this way:
function onEdit(e) {
//e.source.toast('Entry');
var sh=e.range.getSheet();
if(sh.getName()!='Sheet Name')return;//you need to change this sheetnamee
var X=sh.getRange('C2').getValue();
if(X=='Past campaigns - actual cashflows to date only') {
//e.source.toast('flag1');
sh.hideRows(e.range.rowStart,e.range.rowEnd-e.range.rowStart+1);
}
}
I hope you're not trying to run this from the script editor because that's not going to work.

Writing into another Spreadsheet with SetValue fails without errors/exceptions

I'm trying to update a spreadsheet from a script running on another spreadsheet.
Nothing seems to have any effect on the table (SetValue(), SetBackgroundRGB(), etc.).
I've checked the scope, it includes "https://www.googleapis.com/auth/spreadsheets" permission; besides, this same script has no problem writing to another spreadsheet that it creates in runtime.
function updateAnotheSpreadsheet() {
var targetSpreadsheet = SpreadsheetApp.openById('<target spreadsheet id>');
var sheet = targetSpreadsheet.getSheetByName('<sheet name>');
Browser.msgBox(sheet.getRange("A1").getValue()); // Here I see that my getSheetByName worked
sheet.getRange("A1").setValue('Test value'); // But this does nothing
}
There are no errors but also no effect: nothing changes in the target spreadsheet.
Hi I was testing and was able to do what you are trying to do. You can try to declare a variable for the message, here is what I was able to do, I hope this resolves your inquiry.
function updateAnotherSpreadsheet() {
//Opening the second Spreadsheet by ID
var targetSpreadSheet = SpreadsheetApp.openById("<SpreadSheetId>");
var sheet = targetSpreadSheet.getSheetByName("<SheetName>");
//Getting the range to show on msgBox.
var msg = sheet.getRange("A1:A1").getValue();
//Displaying old data on A1:A1 from the secondary Spreadsheet.
Browser.msgBox("Old data on secondary spreadsheet: " + msg);
//Getting the range and setting new values
sheet.getRange("A1:A1").setValue('Test value').setBackground("teal").setFontColor("white");
}
I would suggest to check for more information here https://developers.google.com/apps-script/guides/sheets.
I hope this helps, greetings.
I found the problem.
A function called from OnEdit() can't ask for permissions. I needed to first update that other spreadsheet from any function called by something "active", like a button; then, after the script asks for permission once, it can do its thing from OnEdit() the next time it runs.