无法更新 NamedRange 段落中的文本

Cannot update text in paragraph of NamedRange

我的 google 文档中有一个带有几个选项的单选按钮。当用户 select 选择一个选项时,它会添加一个带有标题和段落的部分。它应该仅在该部分不可用时添加该部分并将 'updated' 文本附加到该段落。

如果该部分已经可用,它应该只在文本末尾附加更新的文本。

问题: 实际上这个行为很奇怪:

  1. 例如,如果我 select 名为 'Diagnoses' 的部分,它将被正确创建。

诊断

更新文本,新范围?真

  1. 如果我 select 名为 'Anamnese' 的部分。该部分也将正确创建:

诊断

更新文本,新范围?假

Anamnese

更新文本,新范围?真

  1. 如果我切换回 '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)
  }
}

我有一个解决方法,如果它仍然在您的目标范围内,请随时修改。

我修改了 setNamedRangechangeTextByNamedRange 函数。以下是他们的修改:

设置命名范围:

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。这是结果。