google-apps-scriptgoogle-docsnamed-rangestextrange

Best practice for filling a text range in Google Docs App Script


I use a template in google docs for a letter and I want to fill the letter after the (dynamic) header of the letter automatically via App Scripts. Is there any best practice to set the text always to the same position? I've tried to use a placeholder and replace it. But sometimes I need to replace the text more than one time.


Solution

  • In your situation, how about using NamedRange? Ref

    When the NamedRange is used, the script is as follows.

    Sample script:

    // Create custom menu.
    function onOpen() {
      DocumentApp.getUi().createMenu("sample")
        .addItem("1. Install named range", "setNamedRange")
        .addItem("2. Change text by named range", "changeTextByNamedRange")
        .addItem("Delete named range", "deleteNamedRange")
        .addToUi();
    }
    
    const nameOfNamedRange = "sample1"; // Please set the name of your named range.
    
    // Set named range.
    function setNamedRange() {
      const doc = DocumentApp.getActiveDocument();
      const ele = doc.getCursor().getElement();
      const range = doc.newRange().addElement(ele).build();
      doc.addNamedRange(nameOfNamedRange, range);
    }
    
    // Update named range.
    function changeTextByNamedRange() {
      const updateText = "updated sample"; // Please set the updated text you want.
    
      const doc = DocumentApp.getActiveDocument();
      const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
      if (!range) {
        throw new Error("No named range. Please install a named range.");
      }
      range.getRange().getRangeElements().forEach(e => e.getElement().asText().setText(updateText));
    }
    
    // Delete named range.
    function deleteNamedRange() {
      const doc = DocumentApp.getActiveDocument();
      const range = doc.getNamedRanges().find(r => r.getName() == nameOfNamedRange);
      if (!range) return;
      range.remove();
    }
    

    Usage:

    1. Please set the cursor to the document you want to set the named range.
    2. Run setNamedRange. By this, the point of the current cursor is set as the named range.
    3. When you want to change the text of the named range. Please run changeTextByNamedRange. By this, the updated text is put to the named range as the replacement.
      • In this case, even when the paragraph is changed and the texts before and after the named range are changed, the named range can be used.

    When you want to delete the named range, please run deleteNamedRange.

    Testing:

    When the above script is run, the following result is obtained.

    enter image description here

    Reference: