Word JS API:扩展Range

问题描述 投票:0回答:1

在回答this question的过程中,我真的希望能够通过特定数量的字符扩展Range。在COM API中,我会使用Range.MoveEnd()。有没有我在JS API中找不到的等价物?

背景:引用的问题是查找超过255个字符的搜索词 - 这是Word中桌面的限制。搜索失败。

解决这个问题的简单方法是搜索前254个字符,然后用剩余的字符数扩展找到的Range,并将Range.Text与完整的搜索词进行比较。

没有找到以这种方式扩展Range的任何等价物,我不得不诉诸:

  • 将搜索词分解为<255个字符
  • 逐个搜索每一件
  • 确定每个搜索到的片段是否与前一个片段相邻
  • 然后展开一个范围以包括相邻的部分
  • 并重复,直到找到所有碎片

因此,我的问题......

async function basicSearch() {
    await Word.run(async (context) => {
        let maxNrChars = 254;
        let searchterm = "";
        let shortSearch = true; //search string < 255 chars
        let fullSearchterm = "Video provides a powerful way to help you prove your point. When you click Online Video, you can paste in the embed code for the video you want to add. You can also type a keyword to search online for the video that best fits your document. Aösdlkvaösd faoweifu aösdlkcj aösdofi "
        let searchTermNrChars = fullSearchterm.length;
        let nrSearchCycles = Number((searchTermNrChars / maxNrChars).toFixed(0));
        let nrRemainingChars = searchTermNrChars - (nrSearchCycles * maxNrChars);
        //console.log("Number of characters in search term: " + searchTermNrChars
        //    + "\nnumber of search cycles required: " + nrSearchCycles
        //    + "\nremaining number of characters: " + nrRemainingChars);

//numerous ranges are required to extend original found range
        let bodyRange = context.document.body.getRange();
        bodyRange.load('End');
        let completeRange = null;
        let resultRange = null;
        let extendedRange = null;
        let followupRange = null;

        let cycleCounter = 0;
        let resultText = "";
        if (searchTermNrChars > maxNrChars) {
            searchterm = fullSearchterm.substring(0, maxNrChars);
            cycleCounter++;
            shortSearch = false;
        }
        else { searchterm = fullSearchterm; }

        let results = context.document.body.search(searchterm);
        results.load({ select: 'font/highlightColor, text' });

        await context.sync();

        // short search term, highlight...
        if (shortSearch) {
            for (let i = 0; i < results.items.length; i++) {
                results.items[i].font.highlightColor = "yellow";
            }
        }
        else {
            //console.log("Long search");
            for (let i = 0; i < results.items.length; i++) {
                resultRange = results.items[i];
                resultRange.load('End');
                extendedRange = resultRange.getRange('End').expandTo(bodyRange.getRange('End'));

                await context.sync();

                //search for the remainder of the long search term
                for (let cycle = 1; cycle < nrSearchCycles; cycle++) {
                    searchterm = fullSearchterm.substring((cycle * maxNrChars), maxNrChars);
                    //console.log(searchterm + " in cycle " + cycle);
                    let CycleResults = extendedRange.search(searchterm);
                    CycleResults.load({ select: 'text, Start, End' });
                    await context.sync();
                    followupRange = CycleResults.items[0];

                    //directly adjacent?
                    let isAfter = followupRange.compareLocationWith(resultRange);
                    if (isAfter.value == Word.LocationRelation.adjacentAfter) {
                        resultRange.expandTo(followupRange);
                        extendedRange = resultRange.getRange('End').expandTo(bodyRange.getRange('End'));
                    }
                    await context.sync();
                }

                if (nrRemainingChars > 0) {
                    console.log("In remaining chars");
                    searchterm = fullSearchterm.substring(searchTermNrChars - nrRemainingChars);
                    console.log(searchterm);
                    let xresults = extendedRange.search(searchterm);
                    xresults.load('end, text');
                    await context.sync();

                    let xresult = xresults.items[0];

                    let isAfter = xresult.compareLocationWith(resultRange);

                    await context.sync();
                    console.log(isAfter.value);
                    if (isAfter.value == Word.LocationRelation.adjacentAfter) {
                        completeRange = resultRange.expandTo(xresult);
                        completeRange.load('text');
                        //completeRange.select();
                        await context.sync();
                        resultText = completeRange.text.substring(0, fullSearchterm.length);
                        console.log("Result" + cycleCounter + ": " + resultText);
                    }  
                }
                else {
                    //No remeaining chars
                    resultRange.load('text');
                    //resultRange.select();
                    await context.sync();
                    resultText = resultRange.text.substring(0, fullSearchterm.length);
                    completeRange = resultRange; 
                }

                //long search successful?
                if (resultText == fullSearchterm) {
                    completeRange.font.highlightColor = "yellow";
                }
                else {
                    console.log("Else! " + resultText + "  /  " + fullSearchterm);
                }
                completeRange = null;
            }
        }  
    });
ms-word office-js
1个回答
1
投票

这是我们在原始设计中所拥有的东西,但它实际上是从API中删除的,因为它很容易导致意外的结果(即隐藏的字符不一致,脚注等),我们无法用手边的资源来覆盖这些情况。我们决定删除它。

据说我认为你可以用Word.js实现类似于range.MoveEnd()的东西,你只需要定义到什么结尾;)。一种方法是使用range.expandTo(endRange)方法。同样,有趣的是如何获取“endRange”,因此以下示例显示了如果“end”表示段落的结尾,可能在您的场景中就足够了。

async function run() {
    await Word.run(async (context) => {
        //assume the range at the end of your 255 characters.
        var startRange = context.document.getSelection().getRange("end"); 
        //This one is the range at the end of the paragraph including the selection.
        var endRange = context.document.getSelection().paragraphs.getLast().getRange("end");

        var deltaRange = startRange.expandTo(endRange);
        context.load(deltaRange);

        await context.sync();
        // this will print the characters after the range all the way to the end of the paragraph.
        console.log(deltaRange.text);
    });
}

希望这有助于或者至少让你朝着正确的方向前进。

© www.soinside.com 2019 - 2024. All rights reserved.