javascript - How replace the text in a huge number of content controls via word-js? -


i trying write function takes list of rich text content controls , single string argument, , replaces content of matching content controls string.

while works smaller amount of content controls, fails documents huge amount of them. have work documents on 700 content controls individual titles. in case, code replaces first 66x ccs , aborts generalexception. assume due huge amount of content controls. having similar problems, when try register bindings these ccs (generalexception). different topic.

i tried work around problem, limiting amounts of changes per .sync() , looping through ccs, performing many loops necessary. however, not easy, due asynchronous nature of office-js. not familiar javascript-async-promise-programming far. have come with:

function replacecctextwithsinglestring (cctitlelist, string) {     var maxperbatch = 100;      /*      * first .then() block executed proxy objects selected ccs      *      * replace text-contents in 1 single .then() block. but:      * word throws generalexception if try replace text in more 6xx ccs in 1 .then() block.      * in consequence process maxperbatch ccs per .then() block      */     word.run(function (context) {         var ccclist = [];          // load ccs         for(var = 0; < cctitlelist.length; i++) {             ccclist.push(context.document.contentcontrols.getbytitle(cctitlelist[i]).load('id'));         }          return context.sync().then(function () { // synchronous             var cclist = [];             // aggregate list of ccs             for(var = 0; < ccclist.length; i++) {                 if(ccclist[i].items.length == 0) {                     throw 'could not find cc title "'+cctitlelist[j]+'"';                 }                 else {                     cclist = cclist.concat(ccclist[i].items);                 }             }             $('#status').html('found '+cclist.length+' ccs matching criteria. started replacing...');             console.log('found '+cclist.length+' ccs matching criteria. started replacing...');              // start replacing             return context.sync().then((function loop (replacecounter, cclist) {                 // asynchronous recoursive loop                 for(var = 0; replacecounter < cclist.length && < maxperbatch; i++) { // loop in loop (i appear in condition)                     // maxperbatch times , .sync() long there still unreplaced ccs                     cclist[replacecounter].inserttext(string, 'replace');                     replacecounter++;                 }                  if(replacecounter < cclist.length) return context.sync()  // continue loop                     .then(function () {                         $('#status').html('...replaced content of '+replacecounter+' ccs...');                         return loop(replacecounter, numccs);                     });                 else  return context.sync() // end loop                     .then(function () {                         $('#status').html('replaced content of ccs');                     });             })(0, cclist));         });     }).catch(function (error) {         $('#status').html('<pre>error: ' + json.stringify(error, null, 4) + '</pre>');         console.log('error: ' + json.stringify(error, null, 4));         if (error instanceof officeextension.error) {             console.log('debug info: ' + json.stringify(error.debuginfo, null, 4));         }         throw error;     }); } 

however... not working. replaces first 100 ccs , stops. without failure, without exception or anything. return loop(replacecounter, cclist); not executed , don't know why. if try step line in debugger throws me somewhere in office-js code.

any suggestions?

edit:

i updated code based on suggestions of juan balmori , works charm:

    function replacecctextwithsinglestring_v1_1 (cctitlelist, string) {     word.run(function (context) {         var time1 = date.now();          // load title of content controls         var ccc = context.document.contentcontrols.load('title');          return context.sync().then(function () { // synchronous             // extract cc titles             var documentcctitlelist = [];             for(var = 0; < ccc.items.length; i++) { documentcctitlelist.push(ccc.items[i].title); }              // check missing titles , replace             for(var = 0; < cctitlelist.length; i++) {                 var index = documentcctitlelist.indexof(cctitlelist[i]);                 if(index == -1) { // title missing                     throw 'could not find cc title "'+cctitlelist[i]+'"';                 }                 else { // replace                     ccc.items[index].inserttext(string, 'replace');                 }             }              $('#status').html('...replacing...');              return context.sync().then(function () {                 var time2 = date.now();                 var tdiff = time2-time1;                 $('#status').html('successfully replaced selected ccs in '+tdiff+' ms');             });         });     }).catch(function (error) {         $('#status').html('<pre>error: ' + json.stringify(error, null, 4) + '</pre>');         console.log('error: ' + json.stringify(error, null, 4));         if (error instanceof officeextension.error) {             console.log('debug info: ' + json.stringify(error.debuginfo, null, 4));         }     }); } 

it still takes 13995 ms complete, @ least works :-)

any ideas, provoking generalexception though?

i posted new question concerning speed issue: what fastest way of replacing text of many content controls via office-js?

good question.. did perf test long time ago , able change more 10k content controls in document. 700 should ok. not sure why pre-filling list, not needed, navigating 2 times collection not perf. can string comparison while traversing collection!

here example, did quick test 700 content control document hypothetical tag of "test".

i able 1. compare text against whatever want compare (its string) 2. change value if condition true.

it took 5134 milliseconds complete operation , here code. think quite acceptable.

hope helps!

 function perfcontentcontrols() {          var time1 = date.now(); // lets see in how time complete operation :)          var ccs =0          word.run(function (context) {              var myccs = context.document.body.contentcontrols.getbytag("test");              context.load(myccs);              return context.sync()              .then(function () {                  ccs  = myccs.items.length                  (var = 0; < ccs; i++) {                      if (myccs.items[i].text == "new text 3") // can check cc content , if needed replace it....                           myccs.items[i].inserttext("new text 4", "replace");                                    }                    return context.sync()                  .then(function () {                      var time2 = date.now();                    var diff = time2 - time1;                    console.log("# of ccs:" + ccs + " time change:" + diff + "ms");                  })              })             .catch(function (er) {                 console.log(er.message);               })            })        }


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -