在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);
}