GAS:如何在处理函数中使用变量时更改全局变量值并保留其更改的值? [英] GAS: How to change a global variable value and preserve its changed value when using the variable in a handler function?
问题描述
我的脚本里有这个全局变量:
var targetDocId ='尚未通知文档ID';
我试图在主函数内改变这个全局变量的值:
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);
}
之后,我尝试访问更改后的全局变量值处理函数:
$ p $ 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();
}
函数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 = []; (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]);
}
}
}
}
但,只要我尝试改变 targetDocId
,当它用作 importTheses(targetDocId,thesesId,thesesType)的参数时;
它仍然具有'没有通知文档ID'的值,即使我已经改变了它,就像程序从头开始运行一样。是否可以选择重置为原始值行为?或者我必须使用scriptDB或ScriptProperties来存储全局变量的值?
脚本的每个单独执行是在新的执行实例中完成。因此,在代码块之外定义的任何变量(也称为全局变量)因此对于该实例是唯一的。当事件调用触发器函数时,它会在自己的实例中运行,并且它设置的任何全局值仅对该实例可见;例如,由电子表格或文档UI调用的另一个函数将拥有其自己版本的非范围对象(全局)。
定义和检索 targetDocId
将是缓存服务。 note
function get_targetDocId(){
var cache = CacheService.getPublicCache();
var cached = cache.get(targetDocId);
if(cached!= null){
return cached;
}
var target = createDuplicateDocument(template,docName); ///需要为已存在的文档添加处理
var link = target.getUrl();
var contents = target.getId();
cache.put(targetDocId,contents,1500); //缓存25分钟
返回内容;
$ / code>
现在不用试图使用全局变量,只需调用这个函数: / p>
...
var targetDoc = DocumentApp.openById(get_targetDocId()); b
note 缓存服务是可用于Google Apps脚本的持久性存储的一个示例。在撰写答案之后,引入了属性服务,在执行实例之间持久化全局变量。
观察:看起来您正在使用全局(静态)for tempate
和 docName
,因为 generatePersonDatasheet()
。您可以简单地生成targetDocId。
Bug:在写入时, get_targetDocId()
会创建每次需要刷新缓存时(15分钟),都会有一个新的 docName
副本。您应该添加处理以预先存在的文件的可能性。 (您的现有 onOpen()
也是如此。)
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);
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. 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?
解决方案 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).
Definition and retrieval of targetDocId
would be a good application of the 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. 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()
. You could simply generate the targetDocId on the fly.
Bug: As it is written, get_targetDocId()
will create a new copy of docName
every time it needs to refresh the cache (15 mins). You should add handling for the possibility of a pre-existing file. (This is true of your existing onOpen()
as well.)
这篇关于GAS:如何在处理函数中使用变量时更改全局变量值并保留其更改的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!