You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google Workspace插件中重新赋值Google App Script全局变量?

问题描述

在Google Apps Script中尝试重新赋值全局变量myname,点击「Set Name」按钮后,handleSetName函数里已将myname设为"Testing Name",控制台能看到赋值成功,但调用handleGetName函数获取时却显示undefined。

代码示例

var myname = "";

function loadMTS(event) {
    const button1 = CardService.newTextButton().setText("Set Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction().setFunctionName("handleSetName"));

    const button2 = CardService.newTextButton().setText("Get Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction().setFunctionName("handleGetName"));

    return card.addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build();
}

function handleSetName(e) {
    myname = "Testing Name";
    console.log("Name after change in handleSetName Fucntion :", myname);
}

function handleGetName(e) {
    console.log("Name : ", myname);
}

控制台输出截图

控制台输出截图


问题原因与解决办法

核心原因

Google Apps Script的每个函数调用都是独立的运行实例,全局变量的作用域只限于当前函数执行的会话。点击「Set Name」触发handleSetName时,变量myname在这个会话里被修改,但会话结束后值就会被销毁;再点击「Get Name」触发handleGetName时,会开启全新会话,此时全局变量myname会被重新初始化为空字符串,所以输出undefined。

解决办法

要在不同函数调用间共享数据,需要使用Google Apps Script提供的持久化存储或会话状态传递方案:

方案1:使用PropertiesService持久化存储

这是最常用的跨会话数据共享方式,根据数据的访问范围选择不同的属性存储:

function loadMTS(event) {
    const button1 = CardService.newTextButton().setText("Set Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction().setFunctionName("handleSetName"));

    const button2 = CardService.newTextButton().setText("Get Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction().setFunctionName("handleGetName"));

    return CardService.newCardBuilder().addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build();
}

function handleSetName(e) {
    // 用用户属性存储,仅当前用户可见
    PropertiesService.getUserProperties().setProperty("myname", "Testing Name");
    console.log("Name after change in handleSetName Fucntion :", PropertiesService.getUserProperties().getProperty("myname"));
}

function handleGetName(e) {
    const myname = PropertiesService.getUserProperties().getProperty("myname");
    console.log("Name : ", myname);
}
  • getUserProperties():数据仅当前用户可见,适合私有数据
  • getDocumentProperties():数据对所有有权限访问文档/脚本的用户可见
  • getScriptProperties():数据对脚本所有用户可见,适合全局配置

方案2:使用卡片状态传递数据(仅会话内有效)

如果只需要在当前卡片交互过程中共享数据,可以通过ActionResponse更新卡片状态:

function loadMTS(event) {
    // 从事件参数获取已存储的名称,初始为空
    const currentName = event.parameters?.myname || "";
    
    const button1 = CardService.newTextButton().setText("Set Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction()
            .setFunctionName("handleSetName")
            .setParameters({myname: "Testing Name"}));

    const button2 = CardService.newTextButton().setText("Get Name")
        .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
        .setOnClickAction(CardService.newAction()
            .setFunctionName("handleGetName")
            .setParameters({myname: currentName}));

    return CardService.newCardBuilder().addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build();
}

function handleSetName(e) {
    const updatedName = e.parameters.myname;
    console.log("Name after change in handleSetName Fucntion :", updatedName);
    // 返回更新后的卡片,携带状态参数
    return CardService.newActionResponseBuilder()
        .setNavigation(CardService.newNavigation().updateCard(loadMTS(e)))
        .build();
}

function handleGetName(e) {
    const myname = e.parameters.myname;
    console.log("Name : ", myname);
}

内容的提问来源于stack exchange,提问作者Shiv Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:33:33