如何在 Google Apps 脚本中定义全局变量

问题描述 投票:0回答:9

我看到 Google 的大多数示例都是它们仅使用单个巨型脚本中的函数。

例如https://developers.google.com/apps-script/quickstart/macros

但在我们的风格中,我们通常将所有函数编写在单个命名空间下,例如

MyCompany = (MyCompany || {});
MyCompany.init = function () {
    Logger.log('init');  
};

function onOpen() {
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var menus = [{
        name: "Init",
        functionName: MyCompany.init
    }];
    spreadsheet.addMenu("Test", menus);
};

但是,当我运行上面的代码时,它返回

"MyCompany is not defined."

如何解决?

google-apps-script google-sheets global-variables google-docs
9个回答
138
投票

您可能最好使用属性服务,因为您可以将它们用作一种持久性全局变量。

点击‘文件 > 项目属性 > 项目属性’设置键值,也可以使用

PropertiesService.getScriptProperties().setProperty('mykey', 'myvalue');

数据可以通过

检索
var myvalue = PropertiesService.getScriptProperties().getProperty('mykey');

13
投票

GAS 中的全局变量与其他语言中的不同。它们不是所有例程中都可用的常量或变量。

我认为我可以使用全局变量来保持函数之间的一致性和效率。但正如 SO 的一些人指出的那样,我错了。

全局变量将在每次执行脚本时进行评估,因此不仅仅是每次运行应用程序时评估一次。
全局变量可以在脚本中更改(因此它们不是不能意外更改的常量),但在调用另一个脚本时将重新初始化。
使用全局变量也会带来速度损失。如果在一个函数中使用同一个全局变量两次或多次,则分配一个局部变量并使用它会更快。

如果您想在应用程序中的所有函数之间保留变量,那么使用缓存服务可能是最好的。 我发现循环遍历驱动器上的所有文件和文件夹需要花费很多时间。但您可以在缓存(甚至属性)中存储有关文件和文件夹的信息,并加快至少 100 倍的速度。

我现在使用全局变量的唯一方法是一些前缀和命名小部件。


11
投票

我正在使用一种解决方法,返回一个带有全局变量对象的函数:

function globalVariables(){
  var variables = {
    sheetName: 'Sheet1',
    variable1: 1,
    variable2: 2
  };
  return variables;
}

function functionThatUsesVariable (){
  var sheet =   SpreadsheetApp.getActiveSpreadsheet().getSheetByName(globalVariables().sheetName);
}

4
投票

GAS 中确实存在全局变量,但是你必须了解环境的客户端/服务器关系才能正确使用它们 - 请看这个问题: Google 脚本中的全局变量(电子表格)

但这不是你的代码的问题;文档表明菜单要执行的函数必须作为字符串提供给方法,现在您正在提供函数的输出: https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#addMenu%28String,Object%29

function MainMenu_Init() {
    Logger.log('init');  
};

function onOpen() {
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    var menus = [{
        name: "Init",
        functionName: "MainMenu_Init"
    }];
    spreadsheet.addMenu("Test", menus);
};

3
投票

我需要类似问题的东西,您可以从缓存中存储和获取https://developers.google.com/apps-script/reference/cache/cache

示例:

// call cache service
 var cache = CacheService.getScriptCache();
// get an item from the cache
  var cached = cache.get("somekey");
// if exists in the cache use it
  if (cached != null) {
   // use it whatever you like. 
  }else{
   // calculate/assign your data to cache
   cache.put("somekey","somevalueorobject");

  // you can even put cache data on TTL (time to live)  in seconds.
   cache.put("somekey","somevalueorobject",60);

2
投票

我用这个:如果你声明 var x = 0;在函数声明之前,该变量适用于所有代码文件,但每次编辑电子表格中的单元格时都会声明该变量


1
投票

对于常量,我使用函数箭头表达式。 足迹类似于变量声明。只需在声明时添加

() =>
,在调用(函数)变量时添加
()

var currentSheet = () => SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var maxAttempts = () => 10;

function myFunction(){
    var sheetName = currentSheet().getName();
    for (var i=0; i< maxAttempts(); i++){
        trySomething(i);
    }
}



0
投票

我有一个工作项目,配置如下。

var MyCompany = {};

检查以下链接上的文件

链接工作示例


-1
投票
    var userProperties = PropertiesService.getUserProperties();


function globalSetting(){
  //creating an array
  userProperties.setProperty('gemployeeName',"Rajendra Barge");
  userProperties.setProperty('gemployeeMobile',"9822082320");
  userProperties.setProperty('gemployeeEmail'," [email protected]");
  userProperties.setProperty('gemployeeLastlogin',"03/10/2020");
  
  
  
}


var userProperties = PropertiesService.getUserProperties();
function showUserForm(){

  var templete = HtmlService.createTemplateFromFile("userForm");
  
  var html = templete.evaluate();
  html.setTitle("Customer Data");
  SpreadsheetApp.getUi().showSidebar(html);


}

function appendData(data){
 globalSetting();
 
  var ws = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
  ws.appendRow([data.date,
                data.name,
                data.Kindlyattention,
                data.senderName,
                data.customereMail,
                userProperties.getProperty('gemployeeName'),
                ,
                ,
                data.paymentTerms,
                ,
                userProperties.getProperty('gemployeeMobile'),
                userProperties.getProperty('gemployeeEmail'),
                Utilities.formatDate(new Date(), "GMT+05:30", "dd-MM-yyyy HH:mm:ss")
                
                
  ]);
  
}

function errorMessage(){

Browser.msgBox("! All fields are mandetory");

}
© www.soinside.com 2019 - 2024. All rights reserved.