Google Apps 脚本 - 工作表 - 菜单触发器不起作用

Posted

技术标签:

【中文标题】Google Apps 脚本 - 工作表 - 菜单触发器不起作用【英文标题】:Google Apps Script - Sheet - Menu Trigger not working 【发布时间】:2021-06-13 18:10:56 【问题描述】:

所以我正在构建一个邮件合并工具,它工作正常。

使用硬编码输入测试触发器可以正常工作:

function test()
  sendEmails("TEST MAILMERGE FROM DRAFT")

如果我提示输入框(显示代码的相关部分),它也可以正常工作。

function sendEmails(subjectLine,sheet=SpreadsheetApp.getActiveSheet()) 
  if (!subjectLine) 
    subjectLine = Browser.inputBox(
      "Mail Merge",
      "Type or copy/paste the subject line of the Gmail " +
        "draft message you would like to use:",
      Browser.Buttons.OK_CANCEL
    );

    if (subjectLine === "cancel" || subjectLine == "") 
      // if no subject line finish up
      return;
    
  

但是,尝试成为聪明的裤子并让菜单动态填充主题行,如下所示:

function onOpen() 
  // get the UI for the Spreadsheet
  const ui = SpreadsheetApp.getUi(); 
  
  // add the menu
  const menu = ui.createMenu("TEST"); 
  
  // get the drafts from Gmail
  let drafts = GmailApp.getDraftMessages(); 
  
  // for each draft, create a new menu item
  drafts.forEach((draft) => 
    // add the drafts to be triggered using the following: addItem(caption: string, functionName: string)
    menu
      .addItem(
        draft.getSubject().toString(),
        'sendEmails("' + draft.getSubject().toString() + '")'
      )
      .addToUi();
  );

但是,这不起作用。它出现以下错误:

找不到错误脚本函数:sendEmails(TEST MAILMERGE FROM DRAFT)

在我看来应该可行。由于上面硬编码的测试触发器有效。 我在这里傻吗?据我所知,这应该有效吗?但事实并非如此。

当/如果我得到它的工作,我会签入以说明没有主题的“垃圾”草稿。不过现在只是想让它实际工作。

【问题讨论】:

【参考方案1】:

Menu.addItem(caption, functionName)

参数:

caption:菜单项的标签,只有第一个单词大写。 functionName:用户选择项目时要调用的函数的名称。您可以使用包含的库中的函数,例如 Library.libFunction1。

Menu.addItem() 需要一个没有参数的函数名。它不允许在函数中传递参数。


解决方法:

根据我的理解,您的目标是有一个不同的菜单项,可以针对您电子邮件帐户中可用的每条草稿消息发送电子邮件。

您可能需要考虑使用Custom dialogs 或Custom sidebars,您可以在其中选择要在调用sendEmails() 函数时作为参数传递的草稿消息主题。您可以参考示例代码。

示例代码:

(代码.gs)

function onOpen() 
  // get the UI for the Spreadsheet
  const ui = SpreadsheetApp.getUi(); 
  
  // add the menu
  const menu = ui.createMenu("TEST")
    .addItem('Send Email', 'selectDraft') 
    .addToUi();



function selectDraft() 

  var html = HtmlService.createHtmlOutputFromFile('draft');
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .showModalDialog(html, 'Select Draft Message');


function getDraftSubject()
    
  // get the drafts from Gmail
  let drafts = GmailApp.getDraftMessages(); 
  var subjects = [];
  // for each draft, create a new menu item
  drafts.forEach((draft) => 
    subjects.push(draft.getSubject().toString());
  );
  Logger.log(subjects);
  return subjects;


function sendEmails(subjectLine,sheet=SpreadsheetApp.getActiveSheet()) 

  Logger.log(subjectLine);

(draft.html)

<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
  <h2>Select Draft Subject</h2>
  <form id="myForm" onsubmit="handleFormSubmit()">
    <div class="form-group">
        <label for="subject">Draft Subject</label>
        <select class="form-control form-control-sm" id="subject" name="subject" required>
          <option value="" selected>Choose...</option>
        </select>
      </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form> 

  
  <script>
  google.script.run.withSuccessHandler(function(subj) 
      let select = document.getElementById("subject");
      subj.forEach(function(e, i) 
        let option = document.createElement("option");
        option.value = e;
        option.text = e;
        select.appendChild(option);
      );
  ).getDraftSubject();

  
  function handleFormSubmit() 
    
    var value = document.getElementById("subject").value;
    google.script.run.sendEmails(value);
    document.getElementById("myForm").reset();
  

</script>
</body>

它有什么作用?

    创建一个自定义菜单,该菜单将根据 draft.html 显示一个对话框

    在draft.html 中,我们使用google.script.run.withSuccessHandler(function) 在我们的服务器端(应用程序脚本)调用getDraftSubject(),它返回了一组草稿消息主题。然后我们更新表单的select 类,并根据获得的每个草稿消息主题添加选项。

    当表单被提交时,它会调用handleFormSubmit(),我们得到选定的草稿消息主题并使用google.script.run.myFunction(...) (any server-side function)传递该值。

    google.script.run.sendEmails(value);


输出:

【讨论】:

以上是关于Google Apps 脚本 - 工作表 - 菜单触发器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

计算工作表中的行数,然后使用 Google Apps 脚本在 Google 电子表格上减去

Google Apps 脚本按钮:我可以分配一个未附加到工作表的“全局”脚本吗?

将工作表复制到另一个电子表格[Google Apps脚本]

Google Apps脚本:动态单元格位置;无权调用setValues

用于将 google drive 中的文件名列表与 google sheet 列中的名称列表进行比较的 Apps 脚本,以将新文件从驱动器添加到工作表

使用 Google Apps 脚本在 Google 表格中创建新表格