NB google DOCS not google sheets.
In the following code, I believe I'm doing the following:
- Insert two text elements ('0' and '1') then encapsulate them in two namedRanges tagged respectively with the names '0' and '1'. i.e. two namedRanges each with one text element only.
- Insert a new text element that is not part of any namedRange.
- Retrieve the text of the two named ranges.
The end result in the document is (correctly): 'new 1 0'.
However, when I print out the contents of the debug
array, I get:
As I understand it, I can use namedRanges to encapsulate/protect text elements so that I can retrieve them and manipulate them as I want (use setText() for example, or remove()) without them being affected by or affecting any other elements in the document. That seems to be the purpose of namedRanges.
Instead of getting a namedRange '0' with one text element '0' and a namedRange '1' with one text element '1', I end up with namedRange '0' having three elements (the one I want, the text element from namedRange '1' and the independent text element 'new') and namedRange '1' having two elements (the one I want and the independent text element 'new').
What have I done wrong?
testNamedRanges.gs:
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Test Named Ranges', 'showSidebar')
.addToUi();
}
function onInstall(e) {
onOpen(e);
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('sidebar')
.setTitle('Test namedRange');
DocumentApp.getUi().showSidebar(ui);
}
function testNamedRange() {
var i, j, k, element, ranges, rangeNew, rangeElements, rangeBuilder;
var message = false;
var document = DocumentApp.getActiveDocument();
var cursor = document.getCursor();
var debug = [];
// Remove any pre-existing named ranges
ranges = document.getNamedRanges();
for (j = 0; j < ranges.length; j++) {
ranges[j].remove();
}
// Create and insert two new named ranges each with a single text element
for (i = 0; i < 2; i++) {
element = cursor.insertText(i + ' ');
rangeBuilder = document.newRange();
rangeBuilder.addElement(element);
document.addNamedRange(i, rangeBuilder.build());
}
// Insert independent text element
cursor.insertText('new ');
// Get the named ranges and their text elements and place in the debug array
for (i = 0; i < 2; i++) {
ranges = document.getNamedRanges(i);
for (j = 0; j < ranges.length; j++) {
rangeElements = ranges[j].getRange().getRangeElements();
for (k = 0; k < rangeElements.length; k++) {
debug.push(['tag: ' + i, 'element: ' + k, 'text: ' + rangeElements[k].getElement().getText()]);
}
}
}
// return debug array to sidebar
return {
debug: debug
};
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button class="button" id="testNamedRanges" alt="testNamedRanges" title="testNamedRanges">testNamedRanges</button>
<script>
document.getElementById("testNamedRanges").onclick = testNamedRanges;
function testNamedRanges() {
google.script.run
.withSuccessHandler(testNamedRangeResult)
.testNamedRange();
}
function testNamedRangeResult(result) {
for (var i = 0; i < result.debug.length; i++) {
console.table(result.debug[i]);
}
return;
}
</script>
</body>
</html>
Image showing previous attempts to use named ranges are still stored in the document source:
In attempting to get rid of previous named ranges, I inserted this in the script above just before I create the two new named ranges:
ranges = document.getNamedRanges();
for (j = 0; j < ranges.length; j++) {
ranges[j].remove();
}
This appears to have had no effect: the previous named ranges are still in the document's source in a script element and I still get the erroneous debug
array data.