I am attempting to make many buttons on a Google Sheets spreadsheet that will record my cryptocurrency trades in a format that is specific to my trade strategy. The details of that strategy are not important for this issue. I only want to run a relative script whenever the (Trade!) button is clicked. I want to copy a lot of them, so it wouldn't make sense to make an individual macro for each buy/sell range. Two possible directions for a solution are clear to me, but I can't find information on either.
Possible solution 1: Assign a macro to a cell when it is selected and put the button inside the cell. I can do this with VBA, but cannot find instructions on how to do this for Google Sheets Script.
Possible solution 2: Have the function select the relative cell beneath the button that was clicked. Targeting cells relative to other cells is easy enough, but I can't seem to find a command for targeting a cell relative to an image. Again, this is doable in Excel with VBA, but I can't find the same function for Google Sheets Script.
Any help is appreciated.
You can use checkboxes and this onEdit() code to call whatever function you wish.
function onEdit(e) {
//e.source.toast('Entry');
//Logger.log(JSON.stringify(e));
var sh=e.range.getSheet();
if(sh.getName()=='Trades' && e.range.columnStart==7 && e.range.rowStart>2 && e.value=="TRUE") {
e.range.setValue('FALSE');
e.source.toast('You clicked cell ' + e.range.getA1Notation());
//call whatever function you wish to call
}
}
Animation:
Related
I have created a sheet in Google Sheets that is basically a form users fill out. They fill in the blanks, then press a button to run a script based on the data. However, no matter how I warn them, they don't exit the last field before clicking the button, and the script perceives that the last field is empty. I have tried letting the script activate another field on the screen, but it doesn't seal in the value before doing that. Is there another command that can force the value to be written to the field?
As an additional option to what Troy123 mentioned you can try the following script to detect blank values and display an alert if there is one before running the code you are using to submit the form.
Script:
function alertMessage() {
let ss = SpreadsheetApp.getActive().getSheetByName("Sheet2");
let lR = ss.getLastRow();
let lRValues = ss.getRange(lR, 1, 1, 3).getValues();
let x = false;
for(let i=0; i<3; i++) // Used 3 because I am just saving 3 values from code line 4
{
console.log(lRValues[0][i]);
if (lRValues[0][i]=="")
{
x = true;
}
}
if(x == true)
{
SpreadsheetApp.getUi().alert("Make sure there are no blank fields");
}
else
{
/*
Insert the form submission function or script here
*/
}
}
Example:
References:
alert(prompt)
Use a checkbox at the end of your form and have them click it. This checkbox does nothing, but it changes focus from the last field to the checkbox.
As suggested in a previous answer by Troy123, use a checkbox. IMHO this is the simplest option and by adding a very simple statement you could make your script to "reset" the checkbox, so it could "emulate" the button states, checked means pressed, unchecked means unpressed.
If order to make this able to work with scripts that requires more than 30 seconds to run, use an on edit installable trigger to call the a function responsible to responde to check/uncheck events.
function respondToCheckUncheck(e){
// Assing to a1Notation the reference of the cell containing the checkbox
const a1Notation = 'H10';
if(e.range.getA1Notation() === a1Notation && e.range.isChecked()){
// call here your function
myFunction();
// once the funcion finish, uncheck the checkbox
e.range.uncheck();
} else {
// do nothing
}
}
If you would like to take your script to a more sophisticated solution, your script could protect the cell having the checkbox and use the Lock Service to prevent other risks.
Using drawings to trigger Google Apps Script functions have several caveats like the one that was mentioned in this question
having a data entered in a cell and clicking the drawing when the cell is still in edit mode, will make that the value read from the cell doesn't match the value wrote.
While the workaround to check that the cell is not empty (see a previously posted answer by Fernando Lara) might help this still could lead to errors, i.e., if the user entered a value, pressed enter, but before clicking the button, edits the cell...
Considering the above, I suggest using other kind of element of the Google Sheets user interface, i.e. the Recorded Macros menu, a custom menu, a checkbox or cell with other data validation using a drowdown, a sidebar (requires the use of the HtmlService).
Other options to have in mind are to use a dialog for data entering created using the HtmlService, a Google Form or an AppSheet app.
Is there some way to force the selection of another cell (e.g. A1) after someone has selected a different cell (e.g. B2)? If i use a simple ...getRange(1,1).activate() code, it works when I hit "Run" in the script editor, but not when a selection is made in the real spreadsheet. Please help?
I've basically written a long "onSelection" code that allows someone to mark their answers to a trivia game as "Correct" or "Wrong" by clicking on the corresponding cells. (I do this with onSelection(e) because buttons don't work on mobile.)
However, if they get two answers correct in a row, onSelection(e) doesn't work because they've already selected "Correct" the first time. I want the code to select 'A1' automatically so it's ready for their next Correct/Wrong input.
A code as simple as the following works when I select any cell in Google Sheets and then hit "Run" in the script editor, but it doesn't not work when I select a cell with my mouse.
function onSelectionChange(e){
var sheet = SpreadsheetApp.getActiveSheet()
sheet.getRange(1,1).activate();
}
I've posted this question 2 days ago but with no answers. Here's a link to a copy of the file I'm working on:
https://docs.google.com/spreadsheets/d/1TCQ0cWulb8Wm63Hs57ruwEXgpP1swKAi/edit?usp=sharing&ouid=110569351169109673921&rtpof=true&sd=true
Basically, what I've done is: the "effettivo" page is a copy of the "pianificazione" page, with all the cells in "effettivo" that copy its value from its relative. The trouble is: for the checkboxes on the right, the formula I've set (=pianificazione!G3, for example) copies the value but it renders the checkbox itself uneditable manually (= I can't click on the checkbox to change the value of that checkbox). I need to find a way to copy all those checkbox values from "pianificazione" to "effettivo" while mantaining the checkboxes themselves editable. Thanks again guys :)
First of all the document you provided is not Google sheet, but Excel sheets. To make checkboxes (or in my example whole data) two-ways editable from both sheets and show the same values in both sheets everytime. I suggest you save this document as Google sheet and use GAS onEdit() function. With this function you also able to mirror other changes in values, not only checkboxes. I built fast example based on your document here
or you can just take over the function to your document
function onEdit(e) {
var sheet = e.range.getSheet();
var value = e.value;
if (sheet.getName() == 'effettivo') {
e.source.getSheetByName('pianificazione').getRange(e.range.rowStart, e.range.columnStart).setValue(value);
}
if (sheet.getName() == 'pianificazione') {
e.source.getSheetByName('effettivo').getRange(e.range.rowStart, e.range.columnStart).setValue(value);
}
}
Important! delete all formulas, that passes values between sheets, since that will be done by function, you don't need them anyway. Or just delete old 'effettivo' sheet and duplicate the 'pianificazione' and rename it to 'effettivo'. Also very important to authorize script first, best way to do it in Script editor trigger onEdit function manually and authorize it.
I'm testing functionality with this spreadsheet:
https://docs.google.com/spreadsheets/d/1vqPDDOXhzBOkTPbJQDgZTgaGevNEkcglVMUjVUn5FKY/edit?usp=sharing
I've created two custom menus:
Custom views
Module navigation
The Custom views menu shows/hides specific columns based on the menu selection, while the Module navigation menu navigates (or sets the active cell) to a specific cell in the sheet (based on a named range). The problem is that I only want these menus to function in a specific sheet (the "Design" sheet) and not others.
I'm a bit of an Apps Script noob, so I probably haven't set things up optimally, but it works except that it works on any sheet instead of only the Design sheet sheet. I've tried getSheetByName() but that keeps throwing up an error.
The Custom Views I definitely only want working on the Design sheet, but the Module Navigation would be great if it could navigate (or set active cell) to the relevant cell on the Design sheet from any other sheet.
I created a function in the script which you can use in your code. This is the function:
function isThisSheetCorrect( nameOfSheet ){
return SpreadsheetApp.getActiveSheet().getSheetName() === nameOfSheet
}
And then in your code, you just run an if statement like this:
if( isThisSheetCorrect("Design") ) {
// run some code
} else {
// do nothing or tell the user that they need to use the "Design" sheet
}
I am writing a Google Sheets Addon, and when I try make changes to my onEdit(e) function, they simply do not reflect. I can make changes to other parts of my addon and it all seems to go through, but right now my onEdit(e) function turns the edited cells red, and nothing - not even deleting the onEdit(e) function - will change that behavior.
I have tried the following:
Changing the code in my script to change the cell to be yellow instead. Then I Test my script as an addon, choose a brand new sheet that I've just created - and yet the onEdit(e) acts as before.
I've tried checking my current project's triggers, but the list is blank, as well as all my simple triggers in general.
I've tried deleting the onEdit(e) method entirely from my project, and deploying that, but it's still there, working on edits.
Not that I think the actual code matters, but my onEdit looks like this:
function onEdit(e) {
const range = e.range;
range.setBackground('#ffe599');
}
Nothing I seem to try will change or remove that behavior from my addon now :/
Please note I am refreshing the page, and even creating entirely new sheets to install the addon from scratch for each attempt to change this thing.
Any help would be awesome as I'm losing my mind a bit! Thanks in advance! :)
I wrote it this way:
function onEdit(e) {
if(e.range.getSheet().getName()=='Sheet1') {
e.range.setBackground('#ffe599');
}
}
And it works for me. It changes the background when the range is edited by a user.
When I delete the function the background doesn't change on edits any longer.
If I rename the function to something other than onEdit is stops working as well.
I made a little change:
function onEdit(e) {
if(e.range.getSheet().getName()=='Sheet1') {
e.range.setBackground('#ffe599');
e.range.offset(0,1).setBackground('#ffff00');
}
}
And the changes the background of the cell edited and the one next to it to the right.