2016-12-29 26 views
1

なぜこのコードスニペットは、range.values = range.values行のコメントを解除しない限り、値をExcelに書き戻しませんか?なぜこのContext.Syncは機能しないのですか?

$('#run').click(function() { 
    invokeRun() 
     .catch(OfficeHelpers.logError); 
}); 
function invokeRun() { 
    return Excel.run(function(context) { 
     var range = context.workbook.worksheets.getItem("Sheet1").getRange("A1:B3"); 
     range.load('values'); 
     return context.sync() 
      .then(function() { 
       range.values[1][1]=99; 
       console.log(JSON.stringify(range.values)); 
       //range.values=range.values 
       return context.sync(); 
     }); 
    }); 
} 

答えて

1

配列のプロパティは特別です。トピックを説明するために私のウェブサイトにページを追加しました:Reading and writing array properties

ここから要約すると、プロキシオブジェクトモデルの仕組みは、オブジェクトにプロパティを設定するたびに、Office.jsランタイムはsetterとgetterにフックを持ち、呼び出しを傍受して追加しますキューへのコマンド。

はのは、最初の定期的なプロパティの例を見てみましょう。上記のように、range.format.fill.color = "red"のようなものを設定すると、colorプロパティのsetterがリクエストをインターセプトし、キューにコマンドを追加して範囲の塗りつぶしの色を赤に設定します(context.syncでディスパッチ)

オン一方、あなたが持っていたすべては(loadそしてもちろんsync、後)、ゲッターはセッターの代わりに発射するだろう、と色の変数が範囲の現在の塗りつぶしの色になるだろうvar color = range.format.fill.color た場合。

は今、それは通常の性質でした。配列の要素を設定すると、ゲッターとして配列の値に効果的にアクセスします。 range.valuesためのゲッターがそれにアクセスして、完全に無地のJSの配列オブジェクトを返し、その値を設定すると、戻ってそれを伝播する何もしませんので

var array = range.values; 
array[r][c] = '-'; 

:ランタイムの観点から、この行は少し冗長バージョンと違いはありません元のRangeオブジェクトに追加します。

値を反映させたい場合は、同期の直後に配列への参照を取得することをお勧めします(つまり、上記のvar配列= range.values)。必要に応じて配列を作成し、最後にオブジェクトに戻します。range.values = array

それはあなたにも場所に値の配列を変更して、ループ(range.values = range.values)の完了時にバック自体に値プロパティを割り当てることができますを意味します。しかし、実際にはそうではありませんが、これはノーオペレーションであるかのように、不自然に見えます。個人的には、最初は配列を取り出し、それを変数に代入して必要な変更を行い、最後に完全な配列を戻すことを好みます。

上記を明確にするUPDATE:

.valuesにアクセスすることにより、返される配列は非常に明確にし、.formulasなど、純粋なバニラJS配列です。 Office.jsが純粋なオブジェクトを返すためには、純粋なオブジェクトに変更を反映させる機能を「スパイク」させることができないということが実際問題の要点です。

range.set({ 
    values: [[1, 2], [3, 4]], 
    format: { 
     fill: { 
      color: "purple" 
     } 
    } 
} 

これは、それがより行います:それは価値があるものを、私たちは実際に私たちはのように、object.set構文を紹介します1,2ヶ月にロールアウトする必要があり、今後の機能を持っているために

同じオブジェクトに複数のプロパティを設定すると便利ですが、配列のプロパティも扱いやすくなります。

+0

マイケルに感謝します。しかし、私はこれが少し賢い/複雑すぎる/バグであると感じるのを助けることができません。
私は、個人的には、ワークアウトしなくてはならず、さまざまな状況でJSランタイムが何をしようとしているのかを知ることより、取得および設定を制御することを好むでしょう。代わりに、代理人オブジェクトが代入の左側にあるときはいつでも、セッターはキックバックする必要があります(これは巧妙になると予想されます) –

+0

これは珍しいことであり、開発者が必要とすることは残念であるここで特別なコンセプトを思い出してください。残念ながら、ここではできることはあまりありません(幸いなことに、この問題を抱えているアレイだけです)。プロキシオブジェクトモデルは、非同期OMよりもはるかに便利な抽象化ですが、ここではちょっと分解しています(代わりに、独自の「スパイク」バージョンの配列を持つことは、私の意見ではあまり望ましくないでしょう。私たちは今持っているものを持っている)。 –

+0

また、Setコマンド(Loadの反対)を使用すると、返されるものをよりよく制御してExcelに戻すことができます。プロキシオブジェクトが実際にどのように動作するかについて私はまだ頭を悩ましています。私は、バニラ配列ではなく、配列を含むオブジェクトであるということです。また、パフォーマンスPOVからは、潜在的に大容量のデータボリュームの追加コピーを作成するのは魅力的ではありません。 –

関連する問題