无法更新 NamedRange 段落中的文本
Cannot update text in paragraph of NamedRange
我的 google 文档中有一个带有几个选项的单选按钮。当用户 select 选择一个选项时,它会添加一个带有标题和段落的部分。它应该仅在该部分不可用时添加该部分并将 'updated' 文本附加到该段落。
如果该部分已经可用,它应该只在文本末尾附加更新的文本。
问题: 实际上这个行为很奇怪:
- 例如,如果我 select 名为 'Diagnoses' 的部分,它将被正确创建。
诊断
更新文本,新范围?真
- 如果我 select 名为 'Anamnese' 的部分。该部分也将正确创建:
诊断
更新文本,新范围?假
Anamnese
更新文本,新范围?真
- 如果我切换回 'Diagnoses',它看起来像这样:
诊断
更新文本,新范围?真
Anamne 更新文本,新范围?假
更新文本,新范围?真更新文本,新范围?假
function manageSection(selectedSection) {
section = selectedSection;
var range = doc.getNamedRanges().find(r => r.getName() == section);
if (!range) {
Logger.log('No named range. Installing a named range');
setNamedRange(section)
} else {
Logger.log('Named range found.');
getNamedRange(section)
}
}
// No namedRange found - Set new named range with name section.
function setNamedRange(section) {
goToLastLine();
// Append a section header
var s = body.appendParagraph(section);
s.setHeading(DocumentApp.ParagraphHeading.HEADING4);
// Append paragraph to section
var insert = body.appendParagraph('');
var rangeBuilder = doc.newRange();
rangeBuilder.addElement(insert);
var savedInsert = rangeBuilder.build()
var namedRange = doc.addNamedRange(section, savedInsert);
var namedRangeId = namedRange.getId();
// select the namedRange
doc.setSelection(doc.getNamedRangeById(namedRangeId).getRange());
var newRange = true;
changeTextByNamedRange(section, newRange)
}
// Existing namedRange found.
function getNamedRange(section) {
Logger.log('getNamedRange() started')
var newRange = false;
changeTextByNamedRange(section, newRange)
}
// Update named range.
function changeTextByNamedRange(section, newRange) {
docUi.alert('section:' + section);
var range = doc.getNamedRanges().find(r => r.getName() == section);
// test
var updateText = "updated text, new range? " + newRange;
//
range.getRange().getRangeElements().forEach(e => e.getElement().asText().appendText(updateText));
}
function goToLastLine(){
const kids = body.getNumChildren()
const lastKid = body.getChild(kids - 1)
let last = 0
try {
const lastPar = body.getChild(kids - 1).asParagraph()
last = doc.newPosition(lastPar.getChild(0), lastPar.getText().length)
} catch (e) {
last = doc.newPosition(body.getChild(kids - 1), 0)
} finally {
doc.setCursor(last)
}
}
我有一个解决方法,如果它仍然在您的目标范围内,请随时修改。
我修改了 setNamedRange
和 changeTextByNamedRange
函数。以下是他们的修改:
设置命名范围:
function setNamedRange(section) {
// Append a section header
goToLastLine();
var s = body.appendParagraph(section);
s.setHeading(DocumentApp.ParagraphHeading.HEADING4);
// Append paragraph to section
// for some reason, it fails to include the 1st paragraph when it is blank
// you can add a space, or any character just to include the 1st one properly
var insert = body.appendParagraph("\t");
var rangeBuilder = doc.newRange();
rangeBuilder.addElement(insert);
var savedInsert = rangeBuilder.build();
var namedRange = doc.addNamedRange(section, savedInsert);
var namedRangeId = namedRange.getId();
// select the namedRange
doc.setSelection(doc.getNamedRangeById(namedRangeId).getRange());
changeTextByNamedRange(section);
}
changeTextByNamedRange:
function changeTextByNamedRange(section) {
// docUi.alert('section:' + section);
var range = doc.getNamedRanges().find(r => r.getName() == section);
// get list of section names
var sectionNames = doc.getNamedRanges().map(r => r.getName());
var updateText = "Newer Text is appended for this section " + section + ". ";
// this section contains the succeeding sections as well
// so you have to end the loop when you encounter another section
// use some instead of forEach to be able to break the loop.
range.getRange().getRangeElements().some(e => {
var element = e.getElement();
// do anything you want. Note that this will loop to each element of that range.
// if section has multiple elements, it will append to each element.
// since we are only appending text to a single paragraph element, this currently works
element.asText().appendText(updateText)
// end loop when you encounter a text that is one of the section names
return !sectionNames.includes(element.asText())
});
}
输出:
- 在不同部分多次运行后,修改要附加的文本,添加一些手动文本,然后再次 运行
manageSection
。这是结果。
我的 google 文档中有一个带有几个选项的单选按钮。当用户 select 选择一个选项时,它会添加一个带有标题和段落的部分。它应该仅在该部分不可用时添加该部分并将 'updated' 文本附加到该段落。
如果该部分已经可用,它应该只在文本末尾附加更新的文本。
问题: 实际上这个行为很奇怪:
- 例如,如果我 select 名为 'Diagnoses' 的部分,它将被正确创建。
诊断
更新文本,新范围?真
- 如果我 select 名为 'Anamnese' 的部分。该部分也将正确创建:
诊断
更新文本,新范围?假
Anamnese
更新文本,新范围?真
- 如果我切换回 'Diagnoses',它看起来像这样:
诊断
更新文本,新范围?真
Anamne 更新文本,新范围?假
更新文本,新范围?真更新文本,新范围?假
function manageSection(selectedSection) {
section = selectedSection;
var range = doc.getNamedRanges().find(r => r.getName() == section);
if (!range) {
Logger.log('No named range. Installing a named range');
setNamedRange(section)
} else {
Logger.log('Named range found.');
getNamedRange(section)
}
}
// No namedRange found - Set new named range with name section.
function setNamedRange(section) {
goToLastLine();
// Append a section header
var s = body.appendParagraph(section);
s.setHeading(DocumentApp.ParagraphHeading.HEADING4);
// Append paragraph to section
var insert = body.appendParagraph('');
var rangeBuilder = doc.newRange();
rangeBuilder.addElement(insert);
var savedInsert = rangeBuilder.build()
var namedRange = doc.addNamedRange(section, savedInsert);
var namedRangeId = namedRange.getId();
// select the namedRange
doc.setSelection(doc.getNamedRangeById(namedRangeId).getRange());
var newRange = true;
changeTextByNamedRange(section, newRange)
}
// Existing namedRange found.
function getNamedRange(section) {
Logger.log('getNamedRange() started')
var newRange = false;
changeTextByNamedRange(section, newRange)
}
// Update named range.
function changeTextByNamedRange(section, newRange) {
docUi.alert('section:' + section);
var range = doc.getNamedRanges().find(r => r.getName() == section);
// test
var updateText = "updated text, new range? " + newRange;
//
range.getRange().getRangeElements().forEach(e => e.getElement().asText().appendText(updateText));
}
function goToLastLine(){
const kids = body.getNumChildren()
const lastKid = body.getChild(kids - 1)
let last = 0
try {
const lastPar = body.getChild(kids - 1).asParagraph()
last = doc.newPosition(lastPar.getChild(0), lastPar.getText().length)
} catch (e) {
last = doc.newPosition(body.getChild(kids - 1), 0)
} finally {
doc.setCursor(last)
}
}
我有一个解决方法,如果它仍然在您的目标范围内,请随时修改。
我修改了 setNamedRange
和 changeTextByNamedRange
函数。以下是他们的修改:
设置命名范围:
function setNamedRange(section) {
// Append a section header
goToLastLine();
var s = body.appendParagraph(section);
s.setHeading(DocumentApp.ParagraphHeading.HEADING4);
// Append paragraph to section
// for some reason, it fails to include the 1st paragraph when it is blank
// you can add a space, or any character just to include the 1st one properly
var insert = body.appendParagraph("\t");
var rangeBuilder = doc.newRange();
rangeBuilder.addElement(insert);
var savedInsert = rangeBuilder.build();
var namedRange = doc.addNamedRange(section, savedInsert);
var namedRangeId = namedRange.getId();
// select the namedRange
doc.setSelection(doc.getNamedRangeById(namedRangeId).getRange());
changeTextByNamedRange(section);
}
changeTextByNamedRange:
function changeTextByNamedRange(section) {
// docUi.alert('section:' + section);
var range = doc.getNamedRanges().find(r => r.getName() == section);
// get list of section names
var sectionNames = doc.getNamedRanges().map(r => r.getName());
var updateText = "Newer Text is appended for this section " + section + ". ";
// this section contains the succeeding sections as well
// so you have to end the loop when you encounter another section
// use some instead of forEach to be able to break the loop.
range.getRange().getRangeElements().some(e => {
var element = e.getElement();
// do anything you want. Note that this will loop to each element of that range.
// if section has multiple elements, it will append to each element.
// since we are only appending text to a single paragraph element, this currently works
element.asText().appendText(updateText)
// end loop when you encounter a text that is one of the section names
return !sectionNames.includes(element.asText())
});
}
输出:
- 在不同部分多次运行后,修改要附加的文本,添加一些手动文本,然后再次 运行
manageSection
。这是结果。