Google Sheets Script - If or statement. Restrict onEdit to specific sheet - if-statement

Super quick question. I have this function I want to run on entire workbook, except two specific sheets.
This is my code:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
if (sheet.getName() != "Total" || sheet.getName() != "DataRange" ) {
someAction();
}
}
This just does not work, the code runs on all sheets no matter what. This is probably a noob question but.

not an "answer" as you already answered your own question, but an alternative:
I'll prefer to use an indexOf I found that (in this case) clearer thant the switch:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
if (["Total","DataRange"].indexOf(sheet.getName()) == -1 ) {
someAction();
}
}
I just identify in an array all the sheet that I want to avoid and then check that the current sheet is not one of then (return -1)

I solved it by using switch instead
switch (sheet.getName()) {
case "Total":
return;
case "DataRange":
return;
default:
doSomething();
break;
}
Answer by Kenny Bones moved from question to answer space.

Related

Google Sheets Scripts, IF date of a cell

I ve been getting some issues trying to use IF statement using items on the sheets as answers, mostly i been trying either using as firt statement a string directly or using another cell of the sheets with the statement comparing to the one i ve been trying to detect with out any results. Mostly my objective would be to, with a daly trigger, use an IF statement to detect every day if the date of today is the same as a date marked on a cell, my only current solution is and only thing is to make it detect if a cell is empty or not, so i just been using google Formulas that do the detect of the date, and if True make it empty, and if not make something appear
Here are some of the tests I ve been trying
Test 1:
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SheetName");
else if (Sheet.getRange(1, 1).getValue() == "2/2/2020"){}
(cell A1=2/2/2020)
Test 2:
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SheetName");
else if (Sheet.getRange(1, 1).getValue() == Sheet.getRange(1, 2).getValue()){}
(cell A1=2/2/2020)
(cell B1=2/2/2020)
Here are two solutions depending on what you are trying to accomplish.
This first one gets the values, formats them to a date format, and then compares them
function myFunction() {
var tz = Session.getScriptTimeZone();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('SheetName');
var data = sheet.getDataRange().getValues();
var aVal = Utilities.formatDate(data[0][0],tz,'MM/dd/YYYY');
var bVal = Utilities.formatDate(data[0][1],tz,'MM/dd/YYYY');
Logger.log([aVal,bVal])
if(aVal == bVal) {
//do something
}
}
This second section gets the display values and compares them. The first solution compares the date values while this second solution compares the dates as a string. Good luck!
function myFunction1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('SheetName');
var data = sheet.getDataRange().getDisplayValues();
var aVal = data[0][0]
var bVal = data[0][1]
Logger.log([aVal,bVal])
if(aVal == bVal) {
//do something
}
}

How can I get a simple bixby Action to work with refresh?

I have this action it its model file HandlQuestionTimeOut.model.bxb :
action (HandleQuestionTimeOut)
{
type(Calculation)
description (Handles Question Time Out.)
collect
{
input (message)
{
type (core.Text)
min (Required) max (One)
}
}
output (core.Text)
}
This in HandleQuestionTimeOut.js
var console = require("console");
module.exports.function = function handleQuestionTimeOut (message)
{
console.log("handleQuestionTimeOut -> message: " + message);
return message;
}
This in the quiz.endpoints.bxb inside the endpoints bracket:
action-endpoint (HandleQuestionTimeOut)
{
accepted-inputs (message)
local-endpoint (HandleQuestionTimeOut.js)
}
I am trying to call that action with refresh like this:
input-view
{
match: Answer(this)
{
to-input: UpdateQuiz(action)
}
refresh
{
if(true)
{
spec
{
delay-seconds (3)
with-request
{
intent
{
goal {HandleQuestionTimeOut}
value: core.Text(Timeout)
}
}
}
}
}
// code continues...
Can you please tell what am I doing wrong? I don't get that HandleQuestionTimeOut log in the console.
Can you clarify you questions?
Though I noticed something, based on my personal opinion:
1) correct module.exports.function -> module.export.function
2) In the refresh section I think you need to specify condition for 'true' or is it there for debugging purpose?
I've just verified that this issue is fixed in 20B SDK release.
Please refer the release notes for details about other changes.

Google Script .getvalue() Not Working With Cells With a Formula In It

I have this google script for google sheets that moves rows of data from "Sheet1" to "Sheet2" when column 15 says "tracking", and it works perfectly fine when I type in "tracking" but I would like that column to be an IF equation something like IF(G:G="tracking not available at this time","","tracking"). But the code does not seem to recognize the formula change from "" to "tracking". Do I need to change the getvalue()? Or is there a different workaround to this issue? I've used =query(importrange) withing the spreadsheet to copy over data with a trigger word, but I really want this to be more of an archive system and add a row to the bottom of "Sheet2" whenever row15 on "sheet1"Thanks! Here is the code:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 14 && r.getValue() == "tracking") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet2");
if(targetSheet.getLastRow() == targetSheet.getMaxRows()) {
targetSheet.insertRowsAfter(targetSheet.getLastRow(), 20);
}
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I had an issue with this recently
I spent about 3 hours debugging something yesterday and this was the culprit.
try using r.getDisplayValue() instead of r.getValue
I am still new to this myself, and feel free to correct me if I am wrong, because if there is a different reason I would really love to know!!!
It seems that if a value in a cell is not typed in but placed there through a formula such as =query() or a similar method, I don't think it actually sees that there is a value in the cell. (I got null values or the formula itself)
If you use getDisplayValue, it "should" get the value that you actually see in the cell.
The correct way to get formulas, instead of displayed values, is with getFormulas rather than getValues

How can I change one object only when one other object is selected?

I'm browsing MEL and expressions and trying to do something like this: if I select one object I deactivate one property from another. But I'm having problems with the object selection denomination. The following is an example:
If (select pCube1-r on) {
  PCube2.visibility = 0;
}
I have tried with strings too but it didn't work...
global proc myscript() {
string $a[] = ls -sl;
if ($a[0] == "pCube1")
hide = "pCube2";
else;
}
scriptJob -e"SelectionChanged"
"myScript";
Can someone help?
Thank you very much!
To find out if a given object is selected you'll need to loop over the list returned by ls -sl.
string $sel[] = `ls -sl`;
string $item;
for ($item in $sel)
{
if ($item == "your-object-here")
{
doSomething();
}
}
This is safer than using an index in any case because you can't be sure there will be an item 0.

Replicating Google Analytics DateRange picker

I need to replicate the Google Analytics date picker (plus a few new options). Can anyone tell me how to highlight all the cells on a calendar between two dates. My basic JavaScript is OK but I think I'm getting a bit out of my depth.
I'm using JQuery 1.5.1 and JQuery UI 1.8.14.
In needed to replicate Google Analytics date picker as well. I know you were asking just about highlighting cells, but if someone else would prefer complete solution, you can see my answer from another question: jquery google analytics datepicker
Here's a solution using the built-in 'onSelect' event (jsFiddle):
$(document).ready(function() {
'use strict';
var range = {
'start': null,
'stop': null
};
$('#picker').datepicker({
'onSelect': function(dateText, inst) {
var d, ds, i, sel, $this = $(this);
if (range.start === null || range.stop === null) {
if (range.start === null) {
range.start = new Date(dateText);
} else {
range.stop = new Date(dateText);
}
}
if (range.start !== null && range.stop !== null) {
if ($this.find('td').hasClass('selected')) {
//clear selected range
$this.children().removeClass('selected');
range.start = new Date(dateText);
range.stop = null;
//call internal method '_updateDatepicker'.
inst.inline = true;
} else {
//prevent internal method '_updateDatepicker' from being called.
inst.inline = false;
if (range.start > range.stop) {
d = range.stop;
range.stop = range.start;
range.start = d;
}
sel = (range.start.toString() === range.stop.toString()) ? 0 : (new Date(range.stop - range.start)).getDate();
for (i = 0; i <= sel; i += 1) {
ds = (range.start.getMonth() + 1).toString() + '/' + (range.start.getDate() + i).toString() + '/' + (range.start.getFullYear()).toString();
d = new Date(ds);
$this.find('td a').filter(function(index) {
return $(this).text() === d.getDate().toString();
}).parents('td').addClass('selected');
}
}
}
}
});
});
I became desperate and came up with a solution on my own. It wasn't pretty but I'll detail it.
I was able to construct a div that had the text boxes, buttons and the datepicker that looked like the Google Analytics control but I couldn't make the datepicker work properly. Eventually, I came up with the idea of creating a toggle variable that kept track of which date you were selecting (start date or end date). Using that variable in a custom onSelect event handler worked well but I still couldn't figure out how to get the cells between dates to highlight.
It took a while, but I slowly came to the realization that I couldn't do it with the datepicker as it existed out of the box. Once I figured that out, I was able to come up with a solution.
My solution was to add a new event call afterSelect. This is code that would run after all the internal adjustments and formatting were complete. I then wrote a function that, given a cell in the datepicker calendar, would return the date that it represented. I identified the calendar date cells by using jQuery to find all the elements that had the "ui-state-default" class. Once I had the date function and a list of all the calendar cells, I just needed to iterate over all of them and, if the date was in the correct range, add a new class to the parent.
It was extremely tedious but I was able to make it work.