Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a library function from a spreadsheet drop-down menu generated by the same library

I created a library that has a specific function that create new spreadsheet menus (using addMenu). My menus options should call other functions within my library to do stuff.

// Bare Minimum Deployment on a blank spreadsheet with 
// my library registered (called myLibraryName for this example).

function onOpen() {
  myLibraryName.setMenus(); // creating new drop-down menus
}

function onEdit(event) {
  myLibraryName.doEvent(event); // sending the onEdit event to a function in my library.
}

Now the issue is that when I choose a menu option, google app script give me an error message like

Script function myMenuFunction could not be found

So I tried to add a prefix in my menu entry

menuEntries.push({name: "About", functionName: "myLibraryName.myMenuFunction"});

But It's also not working.

So I am asking for suggestions on how to create a library that can create Menus that are linked to functions within the library.

like image 241
VanacK Avatar asked Oct 03 '12 20:10

VanacK


2 Answers

I'm not 100% sure what you're calling, but I think this is a known issue.

Looks like you need to call a function directly from the menu, not call it from the upper level.

There's a good example here.

In looking at your question closer, it seems like you're trying to call the same function across different menus in your spreadsheet. Based on the bug I linked, you probably can't do this since you need to define a local function and use that to interact with the script.

like image 107
OnenOnlyWalter Avatar answered Dec 09 '22 05:12

OnenOnlyWalter


Yep, similar problem.

I have about twenty spreadsheets and it's quite boring to update all its scripts with silly code:

 function doSomething(){ myLib.doSomething();}

every time I add new menu entry in main lib.

So I've found more or less dirty workaround - link menu entries to "proxy" functions in lib and create several similar functions in the client spreadsheets in advance (do it once for all client spreadsheets)

//-----------LIB-----------
function libMenu() {
  var mySheet = SpreadsheetApp.getActiveSpreadsheet();

  var menuEntries = [ {name: "Increment current cell", functionName: "processMenuEntry0"},
                      {name: "Do something with row", functionName: "processMenuEntry1"}
                    ];
  mySheet.addMenu("Library Functions", menuEntries);
 }

 function processMenuEntry0()  { incrementCurrentCell();}
 function processMenuEntry1()  { doSomethingWithRow();  }

 //-----------LIB-----------


 //-----------CLIENT-----------
 function onOpen() {
   Library.libMenu();
 }

 function processMenuEntry0()  {gTracking.processMenuEntry0();}
 function processMenuEntry1()  {gTracking.processMenuEntry1();}
 function processMenuEntry2()  {gTracking.processMenuEntry2();}
 function processMenuEntry3()  {gTracking.processMenuEntry3();}
 // etc.
 // I have reserved twenty menu entries in a such way
 //-----------CLIENT-----------

At the moment I do use a little bit enhansed version that allow me to update menuEntries array only. Here it is:

 //-----------LIB-----------

 var menuEntries = [ {name: "Increment current cell", functionName: "incrementCurrentCell"},
                  {name: "Do something with row", functionName: "doSomethingWithRow"}
                ];

 //returns menu entries with changed 'functionName' parameter (-> "processMenuEntry" + id)
 function convertMenuEntries() {
   var newMenuEnties=[];                  
   for (var i=0; i< menuEntries.length ;i++){
     if (menuEntries[i] == null) {// for line separators
       newMenuEnties.push(null);
       continue;
     }
     newMenuEnties.push({name: menuEntries[i]["name"], functionName: "processMenuEntry" + i});
   }
   return newMenuEnties;
 }


 function libMenu() {
   var mySheet = SpreadsheetApp.getActiveSpreadsheet();  

   mySheet.addMenu("Library Functions", convertMenuEntries());
 }


 // get function name from menuEntries array and call it
 function processMenuEntry(id){
   this[menuEntries[id]["functionName"]]();
 }

 function processMenuEntry0()  {processMenuEntry(0);}
 function processMenuEntry1()  {processMenuEntry(1);}
 // etc.

 //-----------LIB-----------
 //-----------CLIENT-----------
 function onOpen() {
   Library.libMenu();
 }


 function processMenuEntry0()  {gTracking.processMenuEntry0();}
 function processMenuEntry1()  {gTracking.processMenuEntry1();}
 function processMenuEntry2()  {gTracking.processMenuEntry2();}
 function processMenuEntry3()  {gTracking.processMenuEntry3();}
 // etc.
 //-----------CLIENT-----------
like image 34
yso Avatar answered Dec 09 '22 06:12

yso