简体   繁体   English

GAS:在处理程序函数中使用变量时,如何更改全局变量值并保留其更改后的值?

[英]GAS: How to change a global variable value and preserve its changed value when using the variable in a handler function?

I have this global variable in my script: 我的脚本中有这个全局变量:

var targetDocId = 'No doc ID informed yet';

I'm trying to change the value of this global variable inside my main function: 我试图在我的主要功能内更改此全局变量的值:

function generatePersonDatasheet() {
  var target = createDuplicateDocument(template, docName);
  var link = target.getUrl();
  targetDocId = target.getId(); // <-------- HERE
  if (theses == 1){
    Logger.log("going to showList() ");
    return showList();
  }   
  showURL(docName, link); 
}

After that, I'm trying to acess the changed global variable value in a handler function: 之后,我尝试在处理程序函数中访问已更改的全局变量值:

function submit(e){
  var numberOfItems = Number(e.parameter.checkbox_total);
  var thesesArrays = [];
  for(var i = 0; i < numberOfItems; i++){
    if(e.parameter['checkbox_isChecked_'+i] == 'true'){
      thesesArrays.push(fact_list[i]);
    }
  }
  for (var i = 0; i < thesesArrays.length; i++){
    var thesesId = thesesArrays[i][2];
    var thesesType = thesesArrays[i][1];        
    importTheses(targetDocId, thesesId, thesesType); // <-----HERE
  }
  return UiApp.getActiveApplication().close();
}

function importTheses(targetDocId, thesesId, thesesType) {
  var targetDoc = DocumentApp.openById(targetDocId);
  var targetDocParagraphs = targetDoc.getParagraphs();
  var targetDocElements = targetDocParagraphs.getNumChildren();

  var thesesDoc = DocumentApp.openById(thesesId);
  var thesesParagraphs = thesesDoc.getParagraphs();
  var thesesElements = thesesDoc.getNumChildren();

  var eltargetDoc=[];
  var elTheses=[];

  for( var j = 0; j < targetDocElements; ++j ) {
       var targetDocElement = targetDoc.getChild(j);
        eltargetDoc[j]=targetDocElement.getText();
       if(el[j]== thesesType){
           for( var k = 0; k < thesesParagraphs-1; ++k ) {
               var thesesElement = thesesDoc.getChild(k);
               elTheses[k] = thesesDoc.getText();
               targetDoc.insertParagraph(j, elTheses[k]);
         }
      }
   }
}

But, as long as I tryied to change the targetDocId , when it's use as argument to importTheses(targetDocId, thesesId, thesesType); 但是,只要我尝试更改targetDocId ,当它用作importTheses(targetDocId, thesesId, thesesType);参数时importTheses(targetDocId, thesesId, thesesType); it still has the value 'No doc ID informed yet', even I have changed it, as if the program had been run from the beginning. 它仍然具有“尚未通知任何文档ID”的值,即使我已对其进行了更改,就好像该程序是从头开始运行的一样。 Is an alternative to this "reset to original value" behavior? 是否可以替代此“重置为原始值”行为? Or I have to use scriptDB or ScriptProperties to store the changed value of the global variable? 还是我必须使用scriptDB或ScriptProperties存储全局变量的更改值?

No theres no such option. 没有这样的选择。 You have to use scriptProperties or scriptDb. 您必须使用scriptProperties或scriptDb。 A global vsriable goes out of scope once your function finishes. 函数完成后,全局vsriable将超出范围。 Each outside script call starts from zero. 每个外部脚本调用均从零开始。

Each separate execution of a script is done in a new execution instance. 脚本的每个单独执行都在新的执行实例中完成。 Any variables defined outside of a block of code (aka "global" variables) are therefore unique for that instance. 因此,在代码块之外定义的任何变量(也称为“全局”变量)对于该实例都是唯一的。 When a trigger function is invoked by an event, it runs in its own instance, and any global values it sets are visible only to that instance; 当事件触发一个触发器函数时,它在自己的实例中运行,并且它设置的任何全局值仅对该实例可见。 another function that is invoked by a spreadsheet or document UI, for example, would have its very own version of that non-scoped object (global). 例如,由电子表格或文档UI调用的另一个函数将具有该非范围对象的自己的版本(全局)。

Definition and retrieval of targetDocId would be a good application of the Cache Service . targetDocId定义和检索将是Cache Service的良好应用。 note 注意

function get_targetDocId () {
  var cache = CacheService.getPublicCache();
  var cached = cache.get("targetDocId");
  if (cached != null) {
    return cached;
  }
  var target = createDuplicateDocument(template, docName);  /// Need to add handling for pre-existing document
  var link = target.getUrl();
  var contents = target.getId();
  cache.put("targetDocId", contents, 1500); // cache for 25 minutes
  return contents;
}

Now instead of trying to use a global variable, just call this function: 现在,不要尝试使用全局变量,只需调用以下函数:

...
var targetDoc = DocumentApp.openById(get_targetDocId());
...

note Cache Service is one example of persistent storage available for Google Apps Script. note缓存服务是可用于Google Apps脚本的永久存储的一个示例。 The Properties Service was introduced after this answer was written, and is a much lighter-weight way to persist "global" variables between execution instances. 在编写此答案后引入了属性服务 ,这是一种在执行实例之间持久保存“全局”变量的轻量级方法。


Observation: it appears that you're using a global (static) for tempate and docName , since there are no parameters for generatePersonDatasheet() . 观察:看来,您使用的是全局(静态)为tempatedocName ,因为不存在任何参数generatePersonDatasheet() You could simply generate the targetDocId on the fly. 您可以简单地动态生成targetDocId。

Bug: As it is written, get_targetDocId() will create a new copy of docName every time it needs to refresh the cache (15 mins). 错误:在编写时,每次需要刷新缓存(15分钟)时, get_targetDocId()都会创建一个新的docName副本。 You should add handling for the possibility of a pre-existing file. 您应该添加处理以使文件可能已存在。 (This is true of your existing onOpen() as well.) (这也适用于您现有的onOpen() 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM