Search code examples
google-apps-scriptgoogle-sheetsspreadsheetmenuitemsubmenu

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.


Solution

  • 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).