2016-05-17 4 views
2

私は、検索を実行し、その結果に関する情報をユーザーにリストとして表示するための単語用のタスクページアドインを作成しました。 ユーザーがリスト内のアイテムをクリックすると、単語の範囲を選択してユーザーにアイテムの場所を表示したいと考えています。 アドインを使用すると、ユーザーはその範囲で追加の作業を実行できます(たとえば、フォントの色を変更するなど)。異なるWord.runコンテキストでどのように範囲を使用できますか?

は、私が検索を実行すると、以下の機能を使用して表示するための範囲を得ることができています:

私は、ユーザーのクリックで範囲を選択する難しさを持っていますが
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; 
    }); 
}; 

。 Iの範囲コンテキストを使用して試みた:

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(); 
    }); 
    }); 
} 

Iがそれぞれのコンテンツコントロールを作成することを含む可能性のある方法を横切ってきました新しいコンテキストでselectRange関数内のすべてのコンテンツコントロールをリロードし、一致するコントロールを見つけることができますが、これは既に範囲がある場合は非常に非効率的です。

異なるWord.runコンテキスト間で範囲を再利用する最も良い方法は何ですか?

答えて

4

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; 

〜マイケル・Zlatkovsky、オフィス拡張のチームの開発者、TrackedObjectsに加えMSFT

+0

私は 'range.context.sync() 'でIは、次のエラーを取得上記呼び出し:' GeneralException:GeneralException {[機能]を:、 __proto__:{}、 コード:「GeneralException 」 DEBUGINFO:{ [機能]、 __proto__:{}、 errorLocation: "Document._GetObjectByReferenceId" }、 メッセージ: "GeneralException"、 名: "OfficeExtension.Error"、 traceMessages:[] } ' –

+0

Se私の2つの上記アップデート –

0

はrunSearch方法ではなく、直接、検索結果を使用するよりも、検索結果の範囲を取得するために更新する必要修正。

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; 
    }); 
}; 
関連する問題