mailmerge 스크립트에서 .replaceText()
을 사용하여 데이터베이스의 해당 값으로 필드를 바꿉니다.문서에서 문자열 바꾸기 및 실행 취소
인터페이스를 사용하여 문서에서 테스트 결과가 예상대로 표시되는지 확인하고 다른 값과 함께 사용할 수 있도록 원래 위치에서 내 필드를 가져 오는 '실행 취소'기능이 있어야합니다. 이 스크립트는 옆 막대에있는 문서에 묶여 있습니다.
아래 스크립트는 필드 이름의 대체 값을 메모리에 유지함으로써 그 작업을 수행합니다. 내게 방해가되는 유일한 세부 사항은 문서에서 트랙이 손실되는 것을 방지하기 위해 현재 테스트 데이터에 값이없는 필드에 대해 특수 "빈"레이블을 정의해야한다는 것입니다. (예 : ° vide12 °와 같은 번호가 지정된 식별자 사용) 사람이 있는가 : 있습니다 ...
질문을
이
은 완벽하게 작동되지만 테스트 모드에서 문서 때문에 videXX ° 이들의 최종 문서의 표현은 정확하지 않다 내가 사용하는 것이 ° 이후로는 적합하지입니다 덜 눈에 띄는 방식으로 데이터가 없을 때 대체 데이터를 "지역화"하는 더 나은 아이디어 또는 다른 접근법? (나는이 이상한 소리를 안다. 그래서 나는 전체 상황을 설명한다 :-)Google 문서 도구가 구축되는 방식을 고려할 때 나는 완전한 요소 구조를 얻을 수 있었고 그 정보에서 문서를 재구성 할 수 있다고 생각했지만, 가장 작은 요소가 단락이고 필드가 주로 단 하나의 단어이기 때문에 두려워하지 않습니다.
다음은 내가 사용하는 코드의 관련 부분입니다.) 명확.
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 번을 반복하기 때문에
그것은 시간 낭비를 나타날 수 있습니다 (I뿐만 아니라 위의 코드를 업데이트) 메뉴에서 AND 교체를 처리하는 두 가지 다른 기능에서이 함수를 호출하지만, 결과는 즉각적입니다 ... 그래서 왜 귀찮게합니까? 여기에 코드는 누군가에게 아이디어를 제공합니다.
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);
}
}
}
}
멋진 아이디어 :-) 나는이 방법으로 필드를 숨길 생각을하지 못했다. 나는 그것을 즉각적으로 구현할 것이다. –