2013-06-14 2 views
3

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); 
     } 
    } 
    } 
} 

답변

4

Serge, 나는 아주 똑같은 문제를 해결하기 위해 노력해 왔습니다! 공유 할 수있는 부분적인 해결 방법과이를 더 활용할 수있는 아이디어가 있습니다.

Gill이 (은)는 old forum에 능통 한 것처럼 숨겨진 텍스트를 Google 문서 도구에 포함 할 수 없습니다. 있다면, 귀하의 우편물 사소한 것입니다!

태그 또는 "쿠키"(거의) 보이지 않게 만드는 방법은 어떻습니까? 아래는 문서에 "클로킹 (cloaking)"기능을 추가하는 스크립트입니다. 그것은 엑스트라도 가지고있다. 사용자에게 은폐 할 텍스트를 쿼리 한 다음 해당 텍스트의 모든 인스턴스를 검색하여 숨 깁니다. 내가 정한 아이디어는 텍스트를 가능한 작게 (글꼴 크기 0) 만들고 전경색을 배경색과 일치시키는 것이 었습니다.

// in menu:  .addItem('Text Cloaking', 'cloakOn') 

/** 
* Find all matches of target text in current document, and cloak them. 
* At this time, that consists of making the text tiny, but still visible. 
* This is an experiment - my hope was to find a way to implement something 
* like document variables, placeholders that would not be forgotten, so 
* that values could be changed, or even dynamic. 
* 
* @param {String} target  (Optional) The text or regex to search for. 
*       See Body.findText() for details. 
* @param {String} background (Optional) The desired highlight color. 
*       A default orange is provided. 
*/ 
function cloakOn(target) { 
    // If no search parameter was provided, ask for one 
    if (arguments.length == 0) { 
    var ui = DocumentApp.getUi(); 
    var result = ui.prompt('Text Cloaking', 
     'Enter text to cloak:', ui.ButtonSet.OK_CANCEL); 
    // Exit if user hit Cancel. 
    if (result.getSelectedButton() !== ui.Button.OK) return; 
    // else 
    target = result.getResponseText(); 
    } 
    var doc = DocumentApp.getActiveDocument(); 
    var bodyElement = doc.getBody(); 
    var searchResult = bodyElement.findText(target); 

    while (searchResult !== null) { 
    var thisElement = searchResult.getElement(); 
    var thisElementText = thisElement.asText(); 

    //Logger.log(url); 
    thisElementText.setFontSize(searchResult.getStartOffset(), searchResult.getEndOffsetInclusive(),0); 
    var background = thisElementText.getBackgroundColor(searchResult.getStartOffset()) || "#ffffff"; 
    thisElementText.setForegroundColor(searchResult.getStartOffset(), searchResult.getEndOffsetInclusive(), 
             background); 

    // search for next match 
    searchResult = bodyElement.findText(target, searchResult); 
    } 
} 

대체 텍스트 작업에서 이것을 사용하려면 대체 텍스트에 외설적 인 태그가 표시됩니다 (수행중인 것처럼). 최종 문서에서 차지하는 공백이 매우 작아 지도록 가능한 한 짧은 태그를 만들고 싶습니다. 일련의 유니 코드 문자를 숫자로 사용하여 다양한 범위의 2를 제공하고있었습니다. 다른 모든 문맥에서는 나타나지 않을 것입니다.

+1

멋진 아이디어 :-) 나는이 방법으로 필드를 숨길 생각을하지 못했다. 나는 그것을 즉각적으로 구현할 것이다. –