簡體   English   中英

如何在不同的Word.run上下文中使用范圍?

[英]How can a range be used across different Word.run contexts?

我創建了一個用於運行搜索的單詞的taskpane插件,並將結果信息作為列表顯示給用戶。 當用戶點擊列表中的項目時,我想在單詞中選擇范圍以向用戶顯示項目的位置。 然后,插件將允許用戶在該范圍上執行其他任務,例如更改字體顏色。

我可以使用以下函數運行搜索並獲取顯示范圍:

function runSearch(textToFind) {
  var items = [];
  return Word.run(function(context) {
    var options = Word.SearchOptions.newObject(context);
    options.matchWildCards = false;

    var rangesFind = context.document.body.search(textToFind, options);
    context.load(rangesFind, 'text, font, style');
    return context.sync().then(function() {
      for (var i = 0; i < rangesFind.items.length; i++) {
        items.push(rangesFind.items[i]);
        context.trackedObjects.add(rangesFind.items[i]);
      }
      return context.sync();
    });
  })
  .then(function() {
    return items;
  });
}; 

但是我在用戶點擊時選擇范圍有困難。 我嘗試過使用范圍上下文:

function selectRange(range){
  range.select();
  return range.context.sync();
}

或者在新的Word.run上下文中使用范圍:

function selectRange(range){
  return Word.run(function(context) {
    context.load(range);
    return context.sync().then(function(){
      range.select();
      return context.sync();
    });
  });
}

我遇到了一個潛在的方法,涉及為每個搜索結果創建一個內容控件,然后在新上下文中重新加載selectRange函數中的所有內容控件並找到匹配的控件,但是當我已經有了這個范圍時,這似乎效率很低。

在不同的Word.run上下文中重用范圍的最佳方法是什么?

您不能跨Word.run調用使用對象。 Word.run每次調用時Word.run創建一個新的上下文,而原始對象則與其自己的上下文綁定,從而產生不匹配。

話雖這么說,你絕對可以Word.run中添加你想要的對象context.trackedObjects.add(obj) ,即使在Word.run完成執行后它們仍將作為工作對象。 通過“工作對象”,我的意思是他們的路徑不會失效(想想類似於垃圾收集的東西,但對於遠程對象)。

一旦你有了這樣的對象(它看起來像你一樣),你應該能夠打電話

range.select();
range.context.sync().catch(...);

如果它不適合你,你能提供一個你得到的錯誤的例子嗎?

為了完整起見,我應該注意,一旦將對象添加到trackedObjects集合中,您就可以有效地將這些對象的內存管理放在自己手中。 這意味着如果你沒有正確釋放內存,你通過減少其內存/范圍調整鏈來減慢Word的速度。 因此,一旦使用了跟蹤對象,就應該調用obj.context.trackedObjects.remove(obj) ,然后調用obj.context.sync() 不要忘記最后一部分 - 如果您不進行同步,則不會發送刪除被跟蹤對象的請求,並且您將繼續耗盡內存。

=======更新1 =======

湯姆,謝謝你提供錯誤信息。 看起來這可能是API的Word實現中的一個錯誤 - 我會對此進行跟進,如果有更多問題,有人可能會聯系到您。

從概念的角度來看,您絕對是在正確的道路上 - 以下內容適用於Excel,例如:

var range;
Excel.run(function (ctx) {
    var sheet = ctx.workbook.worksheets.getActiveWorksheet();

    range = sheet.getRange("A5");
    range.values = [[5]];
    ctx.trackedObjects.add(range);

    return ctx.sync();
})
.then(function(){
    setTimeout(function() {
        range.select();
        range.context.trackedObjects.remove(range);
        range.context.sync();
    }, 2000);
})
.catch(function (error) {
    showMessage("Error: " + error);        
});

=======更新2 =======

事實證明產品確實存在錯誤。 然而,好消息是,使用僅限JavaScript的修復很容易修復,事實上我們將在接下來的幾周內更新CDN。

使用此修復程序,以下代碼有效:

var paragraph;
Word.run(function (ctx) {
    var p = ctx.document.body.paragraphs.first;
    paragraph = p.next;
    ctx.trackedObjects.add(paragraph);
    return ctx.sync();
})
.then(function(){
    setTimeout(function() {
        paragraph.select();
        paragraph.context.trackedObjects.remove(paragraph);
        paragraph.context.sync()
            .then(function() {
                console.log("Done");
            })
            .catch(handleError);
    }, 2000);
})
.catch(handleError);

function handleError (error) {
    console.log('Error: ' + JSON.stringify(error));
    if (error instanceof OfficeExtension.Error) {
        console.log('Debug info: ' + JSON.stringify(error.debugInfo));
    }
}

想要更好的消息? 在更新CDN之前,您可以使用下面的代碼“修補”JavaScript庫並使代碼在上面運行。 您應該在Office.js已經加載后(即,在Office.initialize函數中)以及在執行Word.run之前運行此代碼。

var TrackedObjects = (function () {
    function TrackedObjects(context) {
        this._autoCleanupList = {};
        this.m_context = context;
    }
    TrackedObjects.prototype.add = function (param) {
        var _this = this;
        if (Array.isArray(param)) {
            param.forEach(function (item) { return _this._addCommon(item, true); });
        }
        else {
            this._addCommon(param, true);
        }
    };
    TrackedObjects.prototype._autoAdd = function (object) {
        this._addCommon(object, false);
        this._autoCleanupList[object._objectPath.objectPathInfo.Id] = object;
    };
    TrackedObjects.prototype._addCommon = function (object, isExplicitlyAdded) {
        if (object[OfficeExtension.Constants.isTracked]) {
            if (isExplicitlyAdded && this.m_context._autoCleanup) {
                delete this._autoCleanupList[object._objectPath.objectPathInfo.Id];
            }
            return;
        }
        var referenceId = object[OfficeExtension.Constants.referenceId];
        if (OfficeExtension.Utility.isNullOrEmptyString(referenceId) && object._KeepReference) {
            object._KeepReference();
            OfficeExtension.ActionFactory.createInstantiateAction(this.m_context, object);
            if (isExplicitlyAdded && this.m_context._autoCleanup) {
                delete this._autoCleanupList[object._objectPath.objectPathInfo.Id];
            }
            object[OfficeExtension.Constants.isTracked] = true;
        }
    };
    TrackedObjects.prototype.remove = function (param) {
        var _this = this;
        if (Array.isArray(param)) {
            param.forEach(function (item) { return _this._removeCommon(item); });
        }
        else {
            this._removeCommon(param);
        }
    };
    TrackedObjects.prototype._removeCommon = function (object) {
        var referenceId = object[OfficeExtension.Constants.referenceId];
        if (!OfficeExtension.Utility.isNullOrEmptyString(referenceId)) {
            var rootObject = this.m_context._rootObject;
            if (rootObject._RemoveReference) {
                rootObject._RemoveReference(referenceId);
            }
            delete object[OfficeExtension.Constants.isTracked];
        }
    };
    TrackedObjects.prototype._retrieveAndClearAutoCleanupList = function () {
        var list = this._autoCleanupList;
        this._autoCleanupList = {};
        return list;
    };
    return TrackedObjects;
}());
OfficeExtension.TrackedObjects = TrackedObjects;

希望這可以幫助!

~Michael Zlatkovsky,Office Extensibility團隊的開發人員,MSFT

除了TrackedObjects修復之外,runSearch方法還需要更新以獲取searchResult的范圍,而不是直接使用searchResult。

function runSearch(textToFind) {
  var items = [];
  return Word.run(function(context) {
    var options = Word.SearchOptions.newObject(context);
    options.matchWildCards = false;

    var rangesFind = context.document.body.search(textToFind, options);
    context.load(rangesFind);
    return context.sync().then(function() {
      for (var i = 0; i < rangesFind.items.length; i++) {
        var range = rangesFind.items[i].getRange();
        context.load(range, 'text');
        items.push(range);
        context.trackedObjects.add(items[items.length-1]);
      }
      return context.sync();
    });
  })
  .then(function() {
    return items;
  });
}; 

2019年仍然是更新2中的代碼片段對我不起作用,具有以下錯誤:

錯誤:{“line”:9700,“column”:28,“sourceURL”:“ https:// localhost:3000 / taskpane.js ”}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM