gpt4 book ai didi

google-apps-script - 替换文档中的字符串并撤消

转载 作者:行者123 更新时间:2023-12-05 01:08:32 25 4
gpt4 key购买 nike

在我正在处理的 mailMerge 脚本中,我使用 .replaceText()用数据库中的相应值替换字段。

该界面允许在文档中进行测试以查看结果是否符合预期,并且我需要有一个“撤消”功能来将我的字段置于其原始位置,以便我可以将其与其他值一起使用。(此脚本是有界的到侧栏中的文档,请参阅 this post for illustration )

下面的脚本通过在内存中保留字段名称及其替换值来很好地做到这一点。
唯一困扰我的细节是我必须为当前测试数据中没有值的字段定义一个特殊的“空”标签,以防止在文档中丢失它们的踪迹。
(我使用了一个编号的标识符,如°vide12°)。

这工作完美,但并不理想,因为测试模式下的文档并不完全代表最终文档,因为我使用了这些°videXX°...

问题是:当没有数据时,有没有人有更好的主意或另一种方法来“本地化”替换数据? (我知道这听起来很奇怪……这就是我解释整个情况的原因:-)

考虑到 Google Docs 的构建方式,我认为我可以获得完整的元素结构并根据该信息重建文档,但恐怕这是不可能的,因为最小的元素是一个段落,而字段主要只是单个单词。 ..

这是我使用的代码的相关部分,我添加了一些注释以使其(希望)清楚。

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

最佳答案

Serge,我一直在解决同样的问题!我有一个部分的解决方法要分享,还有一些想法可以更进一步。

正如 Gill 在 old forum 上 Eloquent 地指出的那样,无法在 Google 文档中嵌入隐藏文本。 .如果有,您的邮件合并将是微不足道的!

但是,如何使您的标签或“cookies”(几乎)不可见?下面是一个向文档添加“隐藏”功能的脚本。它也有额外的功能;它向用户查询要隐藏的文本,然后搜索该文本的所有实例并隐藏它们。我决定的想法是使文本尽可能小(字体大小为 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);
}
}

为了在文本替换操作中使用它,替换文本将带有一个隐形标签(正如您所做的那样)。我认为您希望标签尽可能短,以便它们在最终文档中占据的空白非常小 - 我正在使用一系列 unicode 字符作为数字,以提供大范围的 2 -digit 'numbers' 不太可能出现在任何其他上下文中。

关于google-apps-script - 替换文档中的字符串并撤消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17114037/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com