1

I wasn't sure how to name title but here it goes

i need assistance to pass a variable when calling a function inside menu function

function onOpen(){

  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Custom Menu')
    .addSubMenu
    (ui.createMenu('Save')
      .addItem('Save All', 'doSaveAll')
      .addSeparator()
      .addItem('Save Grafics (Trade - Options - BTC - Termo - Future -  Fund)', 'doSaveSheets')
      .addSeparator()
      .addItem('Save Trade',   'doSaveSheet("Trade")')
      .addItem('Save Options', 'doSaveSheet("Opções")')
      .addItem('Save BTC',     'doSaveSheet("BTC")')
      .addItem('Save Termo',   'doSaveSheet("Termo")')
      .addItem('Save Future',  'doSaveSheet("Future")')
      .addItem('Save Fund',    'doSaveSheet("Fund")')
      .addSeparator()
      .addItem('Save Proventos','doSaveProventos')
      .addSeparator()
      .addItem('Save Balanço (BLC - DRE - FLC - DVA)','doSaveDatas')
    //....
    )
    .addToUi();
};

when i try from menu to use Trade, i get error

Função de script não encontrada: doSaveSheet("Trade")

i guess it would be something like

Function script was not found: doSaveSheet("Trade")

is there a way from menu to call that function with that variale or do i need to workaround with something like:

function menuSaveTrade() {
  doSaveSheet('Trade');
}

      .addItem('Save Trade',   'menuSaveTrade()')

that would defeat the purpose of having function structured like this:

function doSaveSheets() 
{
  const sheetNames = ['Trade', 'Opções', 'BTC', 'Termo', 'Future', 'Fund'];
  
  sheetNames.forEach(sheetName => 
  {
    try 
    {
      doSaveSheet(sheetName);
    } 
    catch (error) 
    {
      console.error(`Error saving sheet ${sheetName}:`, error);
    }
  });
}

function doSaveSheet(sheetName) 
{
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ss_t = ss.getSheetByName(sheetName);                                 // ss_s = target spreadsheet
  const ss_c = ss.getSheetByName('Config');                                  // ss_c = config spreadsheet

  Utilities.sleep(2500); // 2,5 secs

  console.log('Save:', sheetName);

  if (sheetName === 'Trade') 
  {
      var C2_ = ss_t.getRange('C2').getValue();  

      var Proventos = ss_c.getRange(ENP).getDisplayValue();        // ENP = Enable Proventos
      var Save = ss_c.getRange(STR).getDisplayValue();             // STR = Save to Trade 

    const ss_p = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Prov');

      var B3_ = ss_p.getRange('B3').getDisplayValue();  

    if( ( B3_ == "Proventos" || Proventos != "TRUE" ) && ( C2_ > 0 ) )  // check if error
    {
      processSaveSheet(ss_t, sheetName, Save) 

      doExportSheet(sheetName)                                     // Special case to export alone
    }

  doCheck(sheetName)
  }
//.......
}

those functions work, that isnt the problem, i need help just with the menu, cos i coulnt find a way to make it work, thanks in advance

  • 1
    You cannot pass parameters to a menu function. – Cooper Jul 21 '23 at 18:25
  • yea after many attempts i feared that, so im going to create a bunch o dummy functions instead to be used on menu, reply as an answer so i can set that – Bruno Carvalho Jul 21 '23 at 18:43
  • Since a person has to click on the menu's how about using a custom dialog that has all of the parameters builtin as select elements. Perhaps that way you can minimise the number of functions. – Cooper Jul 21 '23 at 19:24
  • Here's a simple dialog I did yesterday – Cooper Jul 21 '23 at 19:26
  • did you forget to link? – Bruno Carvalho Jul 21 '23 at 20:04
  • https://stackoverflow.com/a/76731190/7215091 – Cooper Jul 21 '23 at 20:08
  • i will play around with it, cos ive never did it, but in this case i just created a bunch of dummy functions, menu is there just in case, to not open app script, but everything is triggered and automated anyway , actually around 250 Spreadsheets, im updating the template to redo all of them – Bruno Carvalho Jul 21 '23 at 21:06

1 Answers1

1

In your situation, if you want to create the custom menu using doSaveSheet(sheetName) with the arguments of ['Trade', 'Opções', 'BTC', 'Termo', 'Future', 'Fund'], how about the following workaround?

In this workaround, the custom menu is dynamically created. This workaround referred to this answer.

When this is reflected in a sample script, it becomes as follows.

Sample script:

Please copy and paste the following script to the script editor of Google Spreadsheet. And, please reopen Google Spreadsheet. By this, the custom menu is created.

setCustomMenu(); // In this workaround, please don't remove this line.
function onOpen() { } // In this workaround, please don't remove this line.

function setCustomMenu() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('Custom Menu');
  var subMenu = ui.createMenu('Save')
    .addItem('Save All', 'doSaveAll')
    .addSeparator()
    .addItem('Save Grafics (Trade - Options - BTC - Termo - Future -  Fund)', 'doSaveSheets')
    .addSeparator();
  var obj = [ // This is from your showing script.
    { name: 'Save Trade', arg: 'Trade' },
    { name: 'Save Options', arg: 'Opções' },
    { name: 'Save BTC', arg: 'BTC' },
    { name: 'Save Termo', arg: 'Termo' },
    { name: 'Save Future', arg: 'Future' },
    { name: 'Save Fund', arg: 'Fund' },
  ];
  obj.forEach(({ name, arg }, i) => {
    var fn = `func${i}`;
    this[fn] = function (arg) {
      return function () { return doSaveSheet(arg) };
    }(arg);
    subMenu.addItem(name, fn);
  });
  subMenu.addSeparator()
    .addItem('Save Proventos', 'doSaveProventos')
    .addSeparator()
    .addItem('Save Balanço (BLC - DRE - FLC - DVA)', 'doSaveDatas')
  //...
  menu.addSubMenu(subMenu).addToUi();
}

function doSaveSheets() {

  // Please replace this script with your actual script of doSaveSheets().

}

function doSaveSheet(sheetName) {

  Browser.msgBox(sheetName);
  // Please replace this script with your actual script of doSaveSheet(sheetName).

}

Testing:

When the above script is tested, the following result is obtained. In this test, Browser.msgBox(sheetName); is run. You can see that the function doSaveSheet(sheetName) is run with each argument.

enter image description here

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • 1
    works just great, many thanks i couldn't do that, but i can manage to adapt the rest of the code, really appreciate – Bruno Carvalho Jul 22 '23 at 22:07
  • menu works perfectly, but if i try to run any function from within spreadsheet like ```=getSheetID()``` that returns getId(), i get ```Error Exception: Cannot call SpreadsheetApp.getUi() from this context. (line 5). ```Which is ```var ui = SpreadsheetApp.getUi();``` from your exemple – Bruno Carvalho Jul 25 '23 at 19:15
  • 1
    @Bruno Carvalho About your new issue of `menu works perfectly, but if i try to run any function from within spreadsheet like =getSheetID() that returns getId(), i get Error Exception: Cannot call SpreadsheetApp.getUi() from this context. (line 5). Which is var ui = SpreadsheetApp.getUi(); from your exemple`, unfortunately, this script cannot be used with the custom function. I have to deeply apologize for this specification of Google side. – Tanaike Jul 25 '23 at 23:20