0

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?

craftApprentice
  • 2,697
  • 17
  • 58
  • 86

2 Answers2

1

No theres no such option. You have to use scriptProperties or scriptDb. A global vsriable goes out of scope once your function finishes. Each outside script call starts from zero.

Zig Mandel
  • 19,571
  • 5
  • 26
  • 36
  • So, when I go to a handler function, I goes out of my main function and I can't, after running the handler, goes back and resume to the point I was when I went to the handler function? – craftApprentice Dec 14 '13 at 03:20
  • that handler function is no longer in the main function's scope. you cant do that. by the time your handler is called, main finished long ago and the script gets loaded from zero again. – Zig Mandel Dec 14 '13 at 04:22
  • "by the time your handler is called, main finished long ago and the script gets loaded from zero again." That was my doubt! – craftApprentice Dec 17 '13 at 00:42
0

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.)

Mogsdad
  • 44,709
  • 21
  • 151
  • 275