应用脚本如何检测 onOpen 方法是否与文档、工作表或其他类型的文档一起调用



在onOpen方法中,如何确定文档类型?

在快速入门:Google 文档插件中,建议使用以下代码:

function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi(); 
}

但是,当打开Google表格时,脚本会引发异常:

Exception: Cannot call DocumentApp.getUi() from this context. at onOpen(Code:9:15)

应该有一个测试,首先,检测正在打开的文档类型上下文,允许脚本选择是否以及如何添加菜单项。 怎么做? onOpen 的引用表明 e.source 将是一种不同的类型,但type of e.source只是object

欲望是这样的:

function onOpen(e) {
if (/* answer to this question: test if onOpen called for Doc only */) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi(); 
}
}
  • 您想在打开 Google Docs 时检测 Google Docs 的 mimeType。然后,您要检索文档的对象。
  • 您希望使用Google Apps Script实现此目的。

如果我的理解是正确的,那么这个答案呢?请把这看作是几个答案之一。

溶液:

在此示例脚本中,它会在打开 Google 文档时检索容器绑定脚本的活动文档。作为示例情况,当此脚本用于电子表格的容器绑定脚本时,DocumentApp.getActiveDocument()SlidesApp.getActivePresentation()FormApp.getActiveForm()返回null。只有SpreadsheetApp.getActiveSpreadsheet()返回对象。此方法使用此情况。

示例脚本:

示例脚本如下所示。

function onOpen() {
var docObject = DocumentApp.getActiveDocument() ? DocumentApp :
SpreadsheetApp.getActiveSpreadsheet() ? SpreadsheetApp :
SlidesApp.getActivePresentation() ? SlidesApp :
FormApp.getActiveForm() ? FormApp : null;
// When this is used for your script, it becomes as follows.
docObject.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
  • 例如,当上面的脚本被放入谷歌文档时,docObject成为DocumentApp的对象。docObject.getUi().createAddonMenu().addItem('Start', 'showSidebar').addToUi()适用于谷歌文档。

注意:

  • 在此脚本中,使用以下 4 个作用域。
    • https://www.googleapis.com/auth/documents
    • https://www.googleapis.com/auth/forms
    • https://www.googleapis.com/auth/presentations
    • https://www.googleapis.com/auth/spreadsheets
  • 例如,如果您不需要检查 Google 表单,请删除FormApp.getActiveForm() ? FormApp :
  • 上面的脚本通过简单的触发器工作。但是,如果添加其他方法,则可能需要使用可安装触发器。请小心这一点。

引用:

  • 类文档应用
  • 班级电子表格应用程序
  • 课堂幻灯片应用程序
  • 类表单应用程序

如果我误解了你的问题,这不是你想要的方向,我很抱歉。

编辑:

起初,我很抱歉我误解了你的目标。从你更新的问题中,我可以理解如下。

  • 您希望在容器绑定脚本的父级仅为 Google 文档时运行该脚本。

如果我的理解是正确的,那么当我的回答方法被使用时,下面修改一下呢?

从:

if (/* answer to this question: test if onOpen called for Doc only */) {

自:

if (DocumentApp.getActiveDocument()) {
  • 在这种情况下,当这用于除谷歌文档之外的谷歌文档时,DocumentApp.getActiveDocument()返回null。这样,if语句中的脚本不会为Google Docs运行,但Google文档除外。

内置全局变量的.toString()方法通常给出类名。您可以使用它来确定文档类型。

function onOpen(e){
const app = this[ e.source + "App" ];//automatically becomes SpreadsheetApp or DocumentApp or any other editor App
app.getUi()/*Do whatever you want with the Ui object*/;
}

这是我为此编写的函数。诀窍是你不能调用任何访问文档范围的方法,否则你的代码将停止执行。因此,您需要访问不会触发任何 AuthMode.LIMITED 或 FULL 执行范围的函数。

type Host = 'docs' | 'slides';
function getHost(): Host {
let appType;
try {
var activeDocument = DocumentApp.getUi();
if (activeDocument) {
return 'docs';
}
} catch (e) {
console.log(e)
// DocumentApp is not available.
console.info('DocumentApp is not available.')
}
try {
var activePresentation = SlidesApp.getUi();
if (activePresentation) {
return 'slides';
}
} catch (e) {
console.log(e)
// SlidesApp is not available.
console.info('SlidesApp is not available.')
}
return appType;
}

它对我有用的唯一方法是使用 try catch 操作。

function getHost() {
let docUI;
try {
docUI = DocumentApp.getUi();
if (docUI) {
return {type:"doc", doc:DocumentApp, docUI};
}
} catch (e) {
Logger.log("DocumentApp is not available.");
}
try {
docUI = SpreadsheetApp.getUi();
if (docUI) {
return {type:"sheet", doc:SpreadsheetApp, docUI};
}
} catch (e) {
Logger.log("SpreadsheetApp is not available.");
}
return null;
}


function onOpen(e) {
const host = getHost();
if(!host) 
return;
Logger.log("onOpen - host " + host.type);
}

最新更新