リッチテキストコンテンツコントロールのリストと単一の文字列を引数とし、一致するすべてのコンテンツコントロールの内容をこの文字列に置き換える関数を作成しようとしています。どのようにword-jsを介して膨大な数のコンテンツコントロールのテキストを置き換えますか?
これは少量のコンテンツコントロールでは機能しますが、膨大な量のドキュメントでは失敗します。私は700タイトル以上のコンテンツコントロールを持つドキュメントを個別のタイトルで扱わなければなりません。この場合、コードは最初の66X CCを置き換え、GeneralExceptionで中止します。私は、これが膨大な量のコンテンツコントロールのせいだと仮定しています。私はこれらすべてのCC(GeneralException)のバインディングを登録しようとすると、同様の問題が発生しています。しかしこれは別の話題です。
私はこの問題を回避するために、.sync()ごとの変更量を制限し、CCをループして、必要な数のループを実行しました。しかし、office-jsの非同期性のために、これは簡単ではありません。私はこれまでjavascript-async-promise-programmingについてよく知らない。しかし、これは私が思いついたものです:
function replaceCCtextWithSingleString (CCtitleList, string) {
var maxPerBatch = 100;
/*
* A first .then() block is executed to get proxy objects for all selected CCs
*
* Then we would replace all the text-contents in one single .then() block. BUT:
* Word throws a GeneralException if you try to replace the text in more then 6XX CCs in one .then() block.
* In consequence we only process maxPerBatch CCs per .then() block
*/
Word.run(function (context) {
var CCcList = [];
// load CCs
for(var i = 0; i < 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 i = 0; i < CCcList.length; i++) {
if(CCcList[i].items.length == 0) {
throw 'Could not find CC with title "'+CCtitleList[j]+'"';
}
else {
CClist = CClist.concat(CCcList[i].items);
}
}
$('#status').html('Found '+CClist.length+' CCs matching the criteria. Started replacing...');
console.log('Found '+CClist.length+' CCs matching the criteria. Started replacing...');
// start replacing
return context.sync().then((function loop (replaceCounter, CClist) {
// asynchronous recoursive loop
for(var i = 0; replaceCounter < CClist.length && i < maxPerBatch; i++) { // loop in loop (i does only appear in condition)
// do this maxPerBatch times and then .sync() as long as there are still unreplaced CCs
CClist[replaceCounter].insertText(string, 'Replace');
replaceCounter++;
}
if(replaceCounter < CClist.length) return context.sync() // continue loop
.then(function() {
$('#status').html('...replaced the content of '+replaceCounter+' CCs...');
return loop(replaceCounter, numCCs);
});
else return context.sync() // end loop
.then(function() {
$('#status').html('Replaced the content of all 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;
});
}
しかし...それは動作していません。これは最初の100CCを置き換えて停止します。例外なく、何もせずに、失敗することなく。 return loop(replaceCounter, CClist);
は実行されておらず、理由はわかりません。デバッガでこの行に入ると、私はoffice-jsコードのどこかで私を投げます。
提案がありますか?
編集:
私はフアンBalmoriの提案に基づいて、私のコードを更新し、それが魅力のように動作します。
function replaceCCtextWithSingleString_v1_1 (CCtitleList, string) {
Word.run(function (context) {
var time1 = Date.now();
// load the title of all content controls
var CCc = context.document.contentControls.load('title');
return context.sync().then(function() { // synchronous
// extract CC titles
var documentCCtitleList = [];
for(var i = 0; i < CCc.items.length; i++) { documentCCtitleList.push(CCc.items[i].title); }
// check for missing titles and replace
for(var i = 0; i < CCtitleList.length; i++) {
var index = documentCCtitleList.indexOf(CCtitleList[i]);
if(index == -1) { // title is missing
throw 'Could not find CC with 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 all 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));
}
});
}
それはまだ完了して13995ミリ秒かかりますが、少なくともそれが動作:-)
どのようなアイデアが、GeneralExceptionを引き起こしていましたか?
私はスピードの問題に関する新しい質問を投稿:What is the fastest way of replacing the text of many content controls via office-js?
次のステップでは、タイトルに基づいて、これらのすべてのための個々のコンテンツを提供するために、する必要がありますので、私は、タイトルによって個々のコンテンツコントロールにアクセスする必要があります。私はあなたの提案に基づいて私の機能を再現しようとすると、変更時間を計算し、私のポストを更新します。 –