function parameters in time-driven trigger - google-apps-script

I have a function that should have two different behaviors depending on its parameters:
If no parameter, do A
Otherwise do B
If I just run the function selecting it on the script editor and clicking run it runs as expected. It does what is supposed to do without parameters. If I run it in a time driven trigger then nothing happens. I supposed that running the function in a trigger will set the parameters as undefined too. Am I missing something?
Here is the function code:
function logToday(sede) {
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('workedDays');
var dateElement = new dateElement_();
var hour=dateElement.hour()+":45";
var monthYear=dateElement.month();
var day=dateElement.dayInMonth();
var dayName=dateElement.weekDayName();
Logger.log("Running log Today with: "+sede);
if(! sede)
{
sede="";hour="";
sheet.appendRow([monthYear,dayName,day,sede,hour]);
}
else
{
var LastRow=new LastRow_(sheet);
if(LastRow.getColValue("sede")=="")
{
LastRow.setColValue("sede",sede);
LastRow.setColValue("Entered Hour",hour);
if(dateElement.weekDay()==0 || dateElement.weekDay()==6 )colorWeekend(sheet);
Logger.log(dateElement.weekDay());
}
}
}

when triggered, a function is given some parameters from the trigger. For exemple a time trigger every minute will return something like this:
{minute=58, day-of-week=1, timezone=UTC, week-of-year=7, second=20, day-of-month=10, month=2, year=2014, hour=10, authMode=full}
the function that do this test:
function test(e){
SpreadsheetApp.openById("YOUR_SPREADSHEET_ID").appendRow([e]);
}
What you can do is: In your code instead of parsing a simple string as parameter you could pass to your function an object:
function passSedeArg(){
var obj={"sede":"argument"}; // here "argument" must be changed for the old "sede" you where passing
logToday(obj);
}
function logToday(obj) {
var sheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('workedDays');
var dateElement = new dateElement_();
var hour=dateElement.hour()+":45";
var monthYear=dateElement.month();
var day=dateElement.dayInMonth();
var dayName=dateElement.weekDayName();
Logger.log("Running log Today with: "+sede);
if(typeof obj.sede=="undefined") // no obj.sede argument where given
{
sede="";hour="";
sheet.appendRow([monthYear,dayName,day,sede,hour]);
}
else // you have a obj.sede argument
{
var LastRow=new LastRow_(sheet);
if(LastRow.getColValue("sede")=="")
{
LastRow.setColValue("sede",obj.sede);
LastRow.setColValue("Entered Hour",hour);
if(dateElement.weekDay()==0 || dateElement.weekDay()==6 )colorWeekend(sheet);
Logger.log(dateElement.weekDay());
}
}
}

Related

How can I keep an array filled outside of a function?

This question is part of finding a solution to a larger problem. However, I am wondering if there is a way to use a function to fill an Array. Based on the test code below, it seems arrays automatically empty after the function. I am looking to have a function that fills the array repeatedly, and another one that triggers to paste the resulting array.Note the paintArray=[] defined outside of the functions.
The console logs '1' for fillArray() but when I run logArray() right after it logs [].
const paintArray = []
function logArray(){
console.log(paintArray)
}
function fillArray(){
paintArray.push(1)
console.log(paintArray)
}
You can use Properties Service this way:
var scriptProp = PropertiesService.getScriptProperties();
function logArray(){
Logger.log(scriptProp.getProperty("paintArray"))
}
function fillArray(){
var obj = scriptProp.getProperty("paintArray")
if(obj){ //check if paintArray Object exists
var arr = JSON.parse(obj); //parse the value to array
arr.push(1); //push value 1
scriptProp.setProperty("paintArray", JSON.stringify(arr)) //set new value of arr to properties
}else{
scriptProp.setProperty("paintArray", "[1]"); //set initial value if paintArray object is undefined
}
}
First run:
Second run:
Third run:
Save and Retrieve Array from Properties Service
function saveArray(a) {
PropertiesService.getScriptProperties().setProperty("myarray",JSON.stringify(a));
}
function getArray() {
return JSON.parse(PropertiesService.getScriptProperties().getProperty("myarray"));
}

How to adding item menus with the java script of an loop's sub menus inside like this example ".addItem("Go to This Sheet", "S"+i+"GoToS")"?

Hy, Everyone .. I have a question about creating the menu in GAS (Google Apps Scripts) to implement to a Google Spreadsheet without a three of the scripts which is has been take long long way and take my energy too and many many so many lines of the scripts like this I have created. This is the script. Here's the code :
function Menu1() {
var ui = s.getUi(),
s = SpreadsheetApp,
ss = s.getAcgtiveSpreadsheet(),
sss = ss.getSheets(),
madeMenu = ui.createMenu('Sheet Tools Just For an Example Menus');
for (var i=0; i < sss.length; i++){
madeMenu.addSubMenu(ui.createMenu(sss[i].getName())
.addItem('Go to ...', 'S'+i+'GoToS')
.addItem('Rename ...', 'S'+i+'RenameS')
.addItem('Move ...', 'S'+i+'MoveS'))
madeMenu.addToUi();
}
}
function GoToS(getSheetNumber) {
var sheet = sss[getSheetNumber];
ss.setActiveSheet(sheet);
}
This of the main of my problems cames to !!! Because these structures of the scripts and then so to make me had to create this lines. See at the below :
function S0GoToS() {
GoToS(0)
}
function S1GoToS() {
GoToS(1)
}
function S2GoToS() {
GoToS(2)
}
function S3GoToS() {
GoToS(3)
}
function S4GoToS() {
GoToS(4)
}
function S5GoToS() {
GoToS(5)
}
The question is How to create them without the third-sub of the scripts ??? I thought and I hope there is the another way to create these for sure yes I believe there is but that just the because I don't know how about that way. Please someone chould be can help me to solve this case. Any achieves will be appreciated. Thanks in advance has taken in your time and I appologies for my poor english.
You can, in fact, generate those functions dynamically. The idea is to keep a for-loop outside of any of your functions, in the "global" scope, which will generate all these functions. Afterwards, they can be called by a menu action. Your could would look like the following:
// function "constructors"
function createGoToFunction(sheetIndex) {
return function() {
var sheet = SpreadsheetApp.getActive().getSheets()[sheetIndex];
sheet.activate();
}
}
function createRenameFunction(sheetIndex) {
return function() {
// Your rename logic
}
}
function createMoveFunction(sheetIndex) {
return function() {
// Your move logic
}
}
// functions definition
this['ALL_SHEETS'] = SpreadsheetApp.getActive().getSheets();
for (i=0; i<this['ALL_SHEETS'].length; i++) {
this['S'+i+'GoToS'] = createGoToFunction(i);
this['S'+i+'RenameS'] = createRenameFunction(i);
this['S'+i+'MoveS'] = createMoveFunction(i);
}
delete this['ALL_SHEETS'];
delete this['i'];
function Menu1() {
var ui = SpreadsheetApp.getUi();
var sheets = SpreadsheetApp.getActive().getSheets();
var madeMenu = ui.createMenu('Sheet Tools Just For an Example Menus');
for (var i=0; i < sheets.length; i++){
var subMenu = ui.createMenu(sheets[i].getName())
.addItem('Go to ...', 'S'+i+'GoToS')
.addItem('Rename ...', 'S'+i+'RenameS')
.addItem('Move ...', 'S'+i+'MoveS');
madeMenu.addSubMenu(subMenu);
}
madeMenu.addToUi();
}
function onOpen() {
Menu1();
}
In order to implement your own functionality for the functions, you just have to change the body of them defined on top (see createGoToFunction as an example).

Call a random function from an array

I have three functions that I have listed in an array. Now I need a random function of the three to be called when pressing a button. However, when I press the button it calls all three functions and I'm not quite sure where I've gone wrong. It looks like this right now:
function Arm1function1(){
this.parent.parent.parent.Armfront1.visible = true;
this.parent.parent.parent.Armback1.visible = false;
}
function Arm1function2(){
this.parent.parent.parent.Armfront1.visible = false;
this.parent.parent.parent.Armback1.visible = true;
}
function Arm1function3(){
this.parent.parent.parent.Armfront1.visible = false;
this.parent.parent.parent.Armback1.visible = false;
}
function getRandomElementOf(Armbuttonarray1:Array):Object {
var Armbuttonarray1:Array = [Arm1function1(), Arm1function2(), Arm1function3()];
var idx:int=Math.floor(Math.random() * Armbuttonarray1.length);
return Armbuttonarray1[idx];
}
Randombutton1part1.addEventListener(MouseEvent.CLICK, Randombutton1part1Click);
function Randombutton1part1Click(e:MouseEvent):void
{
getRandomElementOf(null);
}
Any clue of where I've gone wrong?
Your issue is this line:
var Armbuttonarray1:Array = [Arm1function1(), Arm1function2(), Arm1function3()];
When populating that array, you are actually populating it with the results of the functions.
Should be:
var Armbuttonarray1:Array = [Arm1function1, Arm1function2, Arm1function3];
Notice the lack of parenthesis ().
You want to actually execute the function on the click handler, so you'll need to tweak that a bit too:
getRandomElementOf(null)();
or
getRandomElementOf(null).call();
As an aside, your getRandomElementOf function should probably look more like this:
function getRandomElementOf(array:Array):Object {
return array[Math.floor(Math.random() * array.length)];
}
Then do:
getRandomElementOf([Arm1function1, Arm1function2, Arm1function3])();

Passing state/data to Google Apps Script ServerHandler

I am trying to work out how I can pass some arbitrary state to a ServerHandler in Google Apps Script. The following code illustrates the question - can anybody help?
Thanks.
function myFunc(e) {
// want to get my data object back out here..?
}
function setUp()
{
var data = getMyDataArray();
// ... set up UI...
var h = app.createServerHandler('myFunc');
// How do I passs my data object to the myFunc handler?
flow.add(app.createButton().setText("OK").addClickHandler(h));
app.add(flow);
s.show(app);
}
You can use Hidden elements to store arbitrary data and send it along with a server handler invocation. The issue is that the the element can only store a string. But you can solve this using JSON.
function myFunc(e) {
var yourObj = Utilities.jsonParse(e.parameter.yourObject);
//do what you need
}
function setUp()
{
var data = getMyDataArray();
// ... set up UI...
var hidden = app.createHidden("yourObject", Utilities.jsonStringify(data));
var h = app.createServerHandler('myFunc').addCallbackElement(hidden);
flow.add(app.createButton().setText("OK").addClickHandler(h));
app.add(flow);
s.show(app);
}

How to Getting the Variable from Function in as3 without using get ,set method?

Hai am Getting trouble to retrive the values from function(addText).i Called from another function onFullScreen().I dont know how Can i do this,Kindly Help me?Here i attach my Code
private function addText()
{
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, ncOnStatus);
function ncOnStatus(infoObject:NetStatusEvent)
{
trace("nc: "+infoObject.info.code+" ("+infoObject.info.description+")");
if (infoObject.info.code == "NetConnection.Connect.Success")
{
initSharedObject(chatSharedObjectName);
}
}
function formatMessage(chatData:Object)
{
trace("room"+chatData.message);
number = chatData.txtalign;//i want to retrive the value of number
number.toString();
return number;
}
function syncEventHandler(ev:SyncEvent)
{
var infoObj:Object = ev.changeList;
// if first time only show last 4 messages in the list
if (lastChatId == 0)
{
lastChatId = Number(textchat_so.data["lastChatId"]) - 1;
if (lastChatId < 0)
lastChatId = 0;
}
}
function connectSharedObject(soName:String)
{
textchat_so = SharedObject.getRemote(soName, nc.uri)
// add new message to the chat box as they come in
textchat_so.addEventListener(SyncEvent.SYNC, syncEventHandler)
textchat_so.connect(nc)
}
function connectSharedObjectRes(soName:String)
{
connectSharedObject(soName)
trace(soName)
}
function initSharedObject(soName:String)
{
// initialize the shared object server side
nc.call("initSharedObject", new Responder(connectSharedObjectRes), soName)
}
}
i using the variable in another function ,but I cannot retrive the Value.
private function onFullScreen(event:FullScreenEvent):void
{
mediaContainer.addMediaElement(alert);
alert.alert("Error",number);// if i cannot retrive the value hnumber here
}
The addText() method is asynchronous, meaning that you can't simply call it , you need to wait for the event listener to return a value.
I'm not sure why you would feel the need to enclose all these functions, it's not very legible and I doubt it's necessary. You're also missing quite a few semi colons...
In any case , I couldn't see where the formatMessage() method was called, it seems that's the only place where the "number" variable gets defined.
You could create a variable outside the scope of the functions.
private var num:int;
Then in your addText function, assign a value to the variable:
num = infoObject.info.code;
Then in your onFullScreen function, access the num variable:
alert.alert("Error", num);