在我正在处理的 mailMerge 脚本中,我使用.replaceText()
数据库中的相应值替换字段。
该界面允许在文档中进行测试以查看结果是否符合预期,我需要一个“UNDO”功能来让我的字段处于其原始位置,以便我可以将它与其他值一起使用。(这个脚本是有界的到侧栏中的文档,请参阅此帖子以获取说明)
下面的脚本通过将字段名称及其替换值保存在内存中来很好地做到这一点。唯一困扰我的细节是我必须为当前测试数据中没有值的字段定义一个特殊的“空”标签,以防止在文档中丢失它们的踪迹。(我使用了像°vide12°这样的编号标识符)。
这是完美的工作,但它并不理想,因为测试模式下的文档并不完全代表最终文档,因为我使用了这些°videXX°......
问题是:当没有数据以不太明显的方式出现时,是否有人有更好的想法或其他方法来“本地化”替换数据?(我知道这听起来很奇怪......这就是我解释整个情况的原因:-)
考虑到 Google Docs 的构建方式,我认为我可以获得完整的元素结构并根据该信息重建 doc,但我担心这是不可能的,因为最小的元素是一个段落,而字段主要只是单个单词。 ..
这是我使用的代码的相关部分,我添加了一些注释以使其(希望)清晰。
function valuesInDoc(e){ // this function replaces the fields with database values
var app = UiApp.getActiveApplication();
var listVal = UserProperties.getProperty('listSel').split(',');
var replacements = [];
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var find = body.findText('#ch');
if(find == null){var ui = DocumentApp.getUi() ; ui.alert("Aucun champ (#chX#) trouvé dans le document... Veuillez insérer des identifiants aux endroits souhaités");return app};
var curData = UserProperties.getProperty('selItem').split('|');
var Headers = [];
var OriHeaders = UserProperties.getProperty('Headers').split('|');
for(n=0;n<OriHeaders.length;++n){
Headers.push('#'+OriHeaders[n]+'#');
}
var fctSpe = 0 ;
for(var i in Headers){if(Headers[i].indexOf('SS')>-1){fctSpe = i}}
for(var n=0;n<listVal.length;++n){
var realIdx = Number(listVal[n]);
var newField = ChampSpecial(curData,realIdx,fctSpe);
if(newField!=''){replacements.push(newField+'∏'+'#ch'+(n+1)+'#')};
//Logger.log('value in '+n+'='+realIdx+' >> '+Headers[realIdx]+' = '+ChampSpecial(curData,realIdx,fctSpe))
app.getElementById('textField'+(n+1)).setHTML(ChampSpecial(curData,realIdx,fctSpe));
if(e.parameter.source!='dataSelection'){
body.replaceText('#ch'+(n+1)+'#',newField);
}
}
UserProperties.setProperty('replacements',replacements.join('|'));// memorize the replacement pattern
cloakOn();// hide hidden fields
return app;
}
function fieldsInDoc(e){ // this function does the reverse process and restores the field identifiers
cloakOff();// show hidden fields
var replacements = UserProperties.getProperty('replacements').split('|');
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
for(var n=0;n<replacements.length;++n){
var field = replacements[n].split('∏')[1];
var testVal = replacements[n].split('∏')[0];
body.replaceText(testVal,field);
}
}
function ChampSpecial(curData,idx,ref){ // this function handles a special case for a specific field, the relevant part is right below, see comment
if(idx==-1){return''};
if(curData[idx-1]==''){return'°vide'+idx+'°'};// this is the "empty" identifier
if(idx<ref){return curData[idx]};
if(idx>ref){return curData[idx-1]}
var firstSpace = curData[idx-1].indexOf(' ');
var apos = curData[idx-1].indexOf("'");
//Logger.log('firstSpace='+firstSpace+' apos='+apos)
if(firstSpace<4&&firstSpace>-1){return curData[idx-1].substring(firstSpace+1)};
if(apos<3&&apos>-1){return curData[idx-1].substring(apos+1)};
return curData[idx-1];
}
编辑: 感谢 Mogsdad 的精彩回答,我编写了这两个函数来隐藏/显示未使用的字段。Sinc 在我的例子中,我使用°XX°(XX=2 位数字)来跟踪未使用的字段,我必须修改他的代码来查找这个特定的字符串,并使用 2 个循环来获取所有字段。
我从菜单和其他两个处理替换的函数中调用这些函数(我也更新了上面的代码)
由于我迭代了 100 次以上,但结果是瞬时的……所以为什么要打扰呢?这是代码,以防它给某人一个想法。
function cloakOn() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var found = [];
for(var n=1;n<23;++n){
for(var f=0;f<5;++f){
if(f==0){found[f] = body.findText('°'+Utilities.formatString("%02d",n)+'°')}else{found[f] = body.findText('°'+Utilities.formatString("%02d",n)+'°',found[f-1])}
if(found[f]!=null){
var elemTxt = found[f].getElement().asText();
elemTxt.setFontSize(found[f].getStartOffset(), found[f].getEndOffsetInclusive(),0)
var background = elemTxt.getBackgroundColor(found[f].getStartOffset()) || "#ffffff";
elemTxt.setForegroundColor(found[f].getStartOffset(), found[f].getEndOffsetInclusive(), background);
}
}
}
}
function cloakOff() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var found = [];
for(var n=1;n<23;++n){
for(var f=0;f<5;++f){
if(f==0){found[f] = body.findText('°'+Utilities.formatString("%02d",n)+'°')}else{found[f] = body.findText('°'+Utilities.formatString("%02d",n)+'°',found[f-1])}
if(found[f]!=null){
var elemTxt = found[f].getElement().asText();
var size = elemTxt.getParent().getFontSize();
elemTxt.setFontSize(found[f].getStartOffset(), found[f].getEndOffsetInclusive(),size)
var background = elemTxt.getBackgroundColor(found[f].getStartOffset()) || "#000000";
elemTxt.setForegroundColor(found[f].getStartOffset(), found[f].getEndOffsetInclusive(), background);
}
}
}
}