Google Sheets using JavaScript functions and check box - javascript

I want to use the "check box" operation of google sheets, and when the check box is true, then call to a function.
Someone can help me with that ?

Supposing your checkbox is at A1, you could use this script to test when it's checked or unchecked (modified):
function onEdit(e) {
var range = e.range;
if (range.getA1Notation() == 'A1') {
var value = range.getValue();
range.setNote('Changed on ' + new Date() + ' to ' + range.getValue());
if (typeof value === 'boolean' && value == true) {
// Do something or call a function when the tick box is checked
}
}
}

While I'm unsure of exactly what you want to do in javascript, the Google Script editor may be useful for you.
In a Google Sheet, go to Tools > Script Editor. It should open a new page and create a new project with a blank function. This is where you can make new functions to be run within Google Sheets.
As an example I made a function called getSum:
function getSum(a,b) {
return a+b;
}
If you save this script and go back to Sheets, you can do =getSum(1,2) and it will return 3
If you wanted to integrate this with a Tick Box, you could do =IF(A1,getSum(1,2),getSum(2,2))
In this case, when the tick box is checked, it will run the first statement, and return 3 , when the box is unchecked, it will return 4
I'm not entirely sure on what you are trying to achieve with JavaScript, but this is one way to introduce custom functions (using Google Script).

Related

Auto Log Wordcount from Docs to Sheets

Having a lot of trouble finding this and as a very beginner programmer, I can't quite troubleshoot my way through this.
What I want to do:
Automatically log the word count of a google doc in a google sheets cell.
The code I've been playing with to try and make it happen that is probably super wrong:
function countWords() {
var doc = DocumentApp.openByURL().getBody().getText();
var punctuationless = doc.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()"?“”]/g," ");
var finalString = punctuationless.replace(/\s{2,}/g," ");
var count = finalString.trim().split(/\s+/).length;
return count;
Ideally, what I'd like to do is, in sheets, set it up so there's a column with links to google docs and be able to just put in a function that will return the wordcount from that doc.
Answer:
You can not create a custom function to do this, as reading another document requires authentication. You can however do this with an in-sheet button which runs the script.
More Information:
As per the documentation on custom functions, it is not possible to run methods which require authentication such as DocumentApp:
Unlike most other types of Apps Scripts, custom functions never ask users to authorize access to personal data. Consequently, they can only call services that do not have access to personal data
As a result, you will instead have to manually run the script - but this can be done from a button in the Sheet.
Code:
Assuming that you have the Document links in column A and wish for the word count to be in column B (starting in row 2):
function countWords() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var linkRange = ss.getRange("A2:A");
try {
linkRange.getValues().forEach(function(cell, index) {
if (cell[0] == "") {
throw "Cell A" + (index + 2) + " is empty"
}
let doc = DocumentApp.openByUrl(cell[0]).getBody().getText();
let count = (doc.match(/\b\S+\b/g) || []).length;
ss.getRange(index + 2, 2).setValue(count);
});
}
catch (err) {
console.log(err);
return;
}
}
Rundown of this function:
Open the sheet containing the document links (remember to change the sheet name!)
Get the range of links down column A
Loop through each link and obtain the Document's text
Obtain all instances of word-boundary/non-whitespace/word-boundary in the document, puts them all into an array, and gets the length of the array.
In this step, if the document is empty, then an empty array is given
Sets the cell in column B adjacent to the link to the result of the count.
This is all wrapped inside a try/catch so that the script stops execution when it reaches an empty cell in column A.
Assigning to a Button:
Now, you can create an in-sheet button which will run the script whenever you click it.
Go to the Insert > Drawing menu item and create a shape; any shape will do, this will act as your button.
Press Save and Close to add this to your sheet.
Move the newly-added drawing to where you would like. In the top-right of the drawing, you will see the vertical ellipsis menu (⋮). Click this, and then click Assign script.
In the new window, type countWords and press OK.
Now, each time you click the button, the script will run.
Visual Example:
References:
Custom Functions in Google Sheets | Apps Script | Google Developers

Condition to Run Macro based on Cell Value

I'm trying to come up with an IF statement that will trigger my macro to run based on a specific value in one cell. My Spreadsheet has many tabs. This is for a forecasting template.
Here is what I have come up with but I am running out of ideas..
function Sum_Calcs() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Integrity Check'), true);
spreadsheet.getRange(K20).getValue(getActiveRange(), true);
if(activeRange === "1") {
}
//My Script is then located beneath//
Any help is much appreciated!
You need to
implement an onEdit function to re-evaluate the if statement each time the value in "K20" was changed (please note that it will work automatically only if the value has been changed manually, by a human)
A second function (macro) that will be called within the if statement if your condition is fulfilled
Based on your code snippet above there some things you need to change:
When you use the method getValue() to retrieve the value of a cell - do not specify any parameter within the brackets () of the method. Instead, assign the return value of this method to a variable
If you want to retrieve a cell value (or perform any other operation) in a certain sheet, use getSheetByName() instead of setActiveSheet
To compare within an if statement the actual value against an integer (number) use if(activeRange == 1)
Note that when getting a range in A1 notation you need to use quotes ("")
Sample code based on your situation:
function myForecastMacro(){
// specify here what shall happen if your "if" statement is fulfilled
function onEdit() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName('Integrity Check');
var activeRange=sheet.getRange("K20").getValue();
if(activeRange == 1) {
myForecastMacro();
}
}

how to get the previous value of a cell in a function

I am currently trying to set up a simple calculation in google sheets that will only add when the value is not equal to the previous value. How can I go about this? All I need is to get the previous value in from the input. It has been a while since I have given my hand at JavaScript so I could be forgetting something simple like that.
I have tried looking into the google API and looking to similar solutions for help. I could just be dumb or missing something simple but does anyone have any idea?
///Call onEdit that takes in the value of e
function onEdit(e)
{
//Get the input value and its previous value
var input = e;
var previous = e; //.prev();? .offset??
//Check if cell is updated
if ( input != previous )
{ return true; }
else
{ return false; }
}
That way
function onEdit(e){
Logger.log(e.oldValue);
}
More details on the event object
You function could be summarised as:
function onEdit(e){
return e.oldValue != e.value;
}
However, I believe that if you just put the same value back in the cell, it's not going to be considered an edit, and thus won't trigger the onEdit() function. So this will always return true when it runs, and not run at all in all other cases.

I need to throw a pop up box based on a selection from a dropdown box that meet a range of criteria

I am trying to throw a pop up box when a selection is made on a drop down box, and the selection meets a range of criteria. (The dropdown box is created from a coldfusion output query). I am new to Javascript so I don't know what I am doing wrong. My code is as follows...
function secondoccupantcheck(obj){
qtenantid = new Array(#ValueList(qRecurring.iTenant_ID)#);
qoccupancy = new Array(#ValueList(qRecurring.ioccupancyposition)#);
qdescription = new Array(#ValueList(qRecurring.cdescription)#);
for (i=0;i<=(qRecurring.length-1);i++){
if ((obj.value ==qtenantid[i]) && (qoccupancy[i] == 1) && (qdescription[i].indexOf("Second Resident")>=0))
{
alert('Resident will be second occupant and occupancy will be zero');
break;
}
}
}
If an occupant in an assisted living house (iTenant_id) wants to move to another room and is currently the main tenant in his or room (iOccupancyposition =1). If he or she will be the second tenant in the room he or she wants to move to, I need to throw an alert box with a message. I can't seem to get it to work. Any help will be appreciated.
A few quick things:
I am assuming you have your JS code surrounded by a CFOUTPUT to
get actual values on client side.
Another assumption include number of values will be same in all
three fields viz. iTenant_ID, ioccupancyposition and
cdescription. If this is not the case or there are consecutive blank values then this logic will not work!
For qdescription you need to use quotedValueList() function
instead of valueList() otherwise browser will throw a JS error.
For the for loop the length should come from qtenantid.length
instead of qRecurring.length OR you need to change your code to: for (i=0;i<=(#qRecurring.recordCount#-1);i++){
Your JavaScrip function is using parameter as an obj and use only
one value out of this object. Why you are passing an object? Pass only the selected value and call is something like val and use it in if condition like: if ((val ==qtenantid[i]) && (qoccupancy[i] == 1) && (qdescription[i].indexOf("Second Resident")>=0))
There are more things that you can check for error handling. Hope this helps.

Clear cell value of adjacent cell if value is a date

I've been working on this script in Google Apps Script for a little while now and think I've got it almost figured out. I could really use another pair of eyes though, as it hasn't yet worked to completion.
What I'm trying to do:
I'm working on a sheet dealing with tentative and actual dates. These two dates are in adjacent columns. Once the "actual" date gets filled into its cell, I would like the "tentative" date to be deleted.
Here is my script thus far:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange('F4:F');
var range2 = sheet.getRange('E4:E');
var rule = range.getDataValidation();
if (rule != null) {
var criteria = rule.getCriteriaType();
var args = rule.getCriteriaValues();
var clear = range2.clear({validationsOnly: false});
}
}
What do I need to do to get this script running?
It appears you want to delete the value in column E if column F was filled. If so, I don't see the need for dealing with data validation rules. The following script checks that the edited cell is in column F, row >= 4, and that the new value in the cell is a date. If these conditions hold, it clears the cell to the left (using offset).
function onEdit(e) {
if (e.range.getColumn() == 6 && e.range.getRow() >= 4) {
if (e.range.getValue() instanceof Date) {
e.range.offset(0, -1).clear();
}
}
}
Note: this script uses the event object passed to onEdit function. Interestingly, its "value" property turned out to be not useful here, because it is not a date object even when a user enters a date. This is what I use e.range.getValue() instead.

Categories