Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google apps script 如何确定是什么导致脚本运行?_Google Apps Script - Fatal编程技术网

Google apps script 如何确定是什么导致脚本运行?

Google apps script 如何确定是什么导致脚本运行?,google-apps-script,Google Apps Script,每当我尝试显示UI对话框(例如或)时,通过菜单项(例如,从Google Sheets)调用时,它工作正常,但如果我尝试从Google Apps脚本编辑器(例如,通过Run>Run函数)调用脚本,它会挂起我的脚本 我猜这是因为谷歌应用程序脚本编辑器无法显示任何用户界面。为了解决这个问题,我想创建一个包装函数来检查脚本是如何运行的,而不是根据源代码显示UI “执行”屏幕具有类型(编辑器、独立、触发器)的概念: 这让我觉得有一种方法可以让这种类型的代码以某种方式出现 函数外观的Psuedo代码:

每当我尝试显示UI对话框(例如或)时,通过菜单项(例如,从Google Sheets)调用时,它工作正常,但如果我尝试从Google Apps脚本编辑器(例如,通过Run>Run函数)调用脚本,它会挂起我的脚本

我猜这是因为谷歌应用程序脚本编辑器无法显示任何用户界面。为了解决这个问题,我想创建一个包装函数来检查脚本是如何运行的,而不是根据源代码显示UI

“执行”屏幕具有类型(编辑器、独立、触发器)的概念:

这让我觉得有一种方法可以让这种类型的代码以某种方式出现

函数外观的Psuedo代码:

function showMessage(message) {
  var scriptSource = ???;
  if (scriptSource === "Standalone") {
    Browser.msgBox(message);
  } else {
    console.log(message);
  }
}
如何获取
脚本源代码

我能找到的最接近的东西是,但它缺少枚举值“Editor”和“Trigger”。此外,它是一个只在网络上可用的属性。我不知道如何访问当前触发器。据我所知,这只能通过(例如,通过
triggerUid
)对充当触发器的函数提供。我在应用程序脚本编辑器中运行的此方法无权访问事件对象。

  • 您想知道当前项目是容器绑定脚本类型还是独立脚本类型
  • 您想使用
    Browser.msgBox()
我可以理解你上面的问题。为了实现它,作为一种解决方法,我建议使用Apps脚本API。示例脚本的流程如下所示。我认为对于你的情况有几个变通办法。所以,请把这看作是其中之一

  • 在应用程序脚本API中使用projects.get方法检索项目的父ID。父ID表示Google文档的文件ID。
    • 返回父ID时,会发现项目是绑定到容器的脚本类型
    • 未返回父ID时,会发现项目是独立脚本类型
  • 当父ID的mimeType为Google Form时,
    Browser.msgBox()
    不能使用。因此,if语句用于此
  • 示例脚本: 这是一个示例脚本。在此示例脚本中,使用当前项目的脚本ID。当然,您也可以手动指定脚本ID

    var id = ScriptApp.getScriptId(); // Retrieve scriptId of current project.
    var url = "https://script.googleapis.com/v1/projects/" + id + "?fields=parentId";
    var res = UrlFetchApp.fetch(url, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
    res = JSON.parse(res.getContentText());
    if ("parentId" in res) {
      Logger.log("Container-bound script type.")
      var mimeType = DriveApp.getFileById(res.parentId).getMimeType();
      if (mimeType === MimeType.GOOGLE_FORMS) {
        Logger.log("Browser.msgBox() cannot be used at Google Form.");
      } else {
        Browser.msgBox("Hello world");
      }
    } else {
      Logger.log("Standalone script type.")
      Logger.log("Hello world");
    }
    
    注:
    • 使用此脚本时,请执行以下流程。
    • 在API控制台启用应用程序脚本API
    • 至少,将以下作用域添加到清单中。
      • https://www.googleapis.com/auth/drive
      • https://www.googleapis.com/auth/script.external_request
      • https://www.googleapis.com/auth/script.projects.readonly
    • 如果在脚本中需要添加其他作用域,请添加它们。如果您想在脚本编辑器中使用scopes的自动安装程序,可以使用一个库来实现。您可以在中查看详细信息
    参考资料:
    如果我误解了你的问题,我很抱歉

    编辑:
    • 您需要确认是从脚本编辑器还是从自定义菜单调用该函数
    如果我的理解是正确的,那么这个示例脚本怎么样?这是一个示例脚本。可以通过提供脚本ID和函数名来检索进程列表。在此示例脚本中,使用Apps脚本API中processs.listScriptProcesses的“ProcessType”,它确认是从脚本编辑器还是从自定义菜单调用该函数

    示例脚本: 这是一个示例脚本。可以通过提供脚本ID和函数名来检索进程列表

    使用此脚本时,请在API控制台启用应用程序脚本API,并添加
    https://www.googleapis.com/auth/script.processes
    添加到清单中

    该脚本的使用方法如下所示

  • 运行
    addCustomMenu()
  • 在自定义菜单上运行
    sampleFunction
    • 这样,日志中将显示来自自定义菜单的调用
  • 在脚本编辑器中运行
    sampleFunction
    • 这样,来自脚本编辑器的调用将显示在日志中
  • 脚本: 参考资料:

      • 不是最好的解决方案,但我目前的解决方法是创建每个函数的3个版本,并将调用方式附加到名称中

        例如,如果有一个“Hello World”函数:

        function onOpen() {
          var menu = [
            {name: 'Hello World', functionName: 'helloWorldViaMenu_'},
          ];
          SpreadsheetApp.getActive().addMenu('Custom', menu);
        }
        
        function helloWorldViaMenu_() {
          helloWorld_(false);
        }
        
        function helloWorldViaEditor() {
          helloWorld_(true);
        }
        
        function helloWorld_(invokedFromEditor) {
          if (invokedFromEditor) {
            Logger.log("Hello world");
          } else {
            Browser.msgBox("Hello world");
          }
        }
        
        helloWorldViaEditor
        是唯一在末尾没有
        \ucode>的编辑器,因此可以通过“选择功能”编辑器UI下拉菜单选择它。

        制作对话框

        您可以从菜单或脚本编辑器运行它们。它们的工作原理相同

        function makeAmenu(){
          SpreadsheetApp.getUi().createMenu('A Menu')
          .addItem('Run my Dialogs', 'showMyDialogs')
          .addToUi();
        }
        
        function showMyDialogs(){
          var ui=SpreadsheetApp.getUi();
          ui.alert('This is an alert');
          ui.prompt('This is a prompt');
          var html=HtmlService.createHtmlOutput('<p>This is a modeless dialog</p><input type="button" value="Close" onClick="google.script.host.close();" />');
          ui.showModelessDialog(html, 'Dialog');
        }
        
        函数makeAmenu(){
        SpreadsheetApp.getUi().createMenu('菜单')
        .addItem('运行我的对话框','显示我的对话框')
        .addToUi();
        }
        函数showMyDialogs(){
        var ui=SpreadsheetApp.getUi();
        ui.alert(“这是一个警报”);
        ui.prompt(“这是一个提示符”);
        var html=HtmlService.createHtmlOutput(“这是一个无模式对话框”

        ”; showModelessDialog(html,“Dialog”); }
        如果从此处运行脚本:

        您必须到这里才能看到它:


        如果我误解了你的情况,我很抱歉。例如,当您想知道UI是否可以用于项目中的函数时,了解项目是容器绑定脚本类型还是独立脚本类型如何?另外,尽管googleform的绑定脚本具有
        getUi()
        的方法,但不能使用
        Browser.msgBox()
        。我认为有几种方法可以确认它们。@Tanaike:如何确定“项目是容器绑定脚本类型还是独立脚本类型”?我想这会解决我的问题。@Tanaike:还有关于“
        getUi()
        Browser.msgBox()function makeAmenu(){
          SpreadsheetApp.getUi().createMenu('A Menu')
          .addItem('Run my Dialogs', 'showMyDialogs')
          .addToUi();
        }
        
        function showMyDialogs(){
          var ui=SpreadsheetApp.getUi();
          ui.alert('This is an alert');
          ui.prompt('This is a prompt');
          var html=HtmlService.createHtmlOutput('<p>This is a modeless dialog</p><input type="button" value="Close" onClick="google.script.host.close();" />');
          ui.showModelessDialog(html, 'Dialog');
        }