为什么此代码段不会将值写回Excel,除非我取消注释range.values = range.values行?
$('#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();
});
});
}
答案 0 :(得分:2)
数组属性很特殊。我在我的网站上添加了一个页面来描述主题: Reading and writing array properties 。
总结一下,代理对象模型的工作方式,无论何时在对象上设置属性,Office.js运行时都有一个挂钩到setter和getter,用于拦截调用并添加命令到队列。
让我们先举一个常规财产的例子。按照上面的说法,无论何时设置range.format.fill.color = "red"
之类的东西,color属性的setter都会拦截请求,并在内部向队列添加一个命令,将范围填充颜色设置为红色(用下一个{{1分派) }})
另一方面,如果你只有context.sync
(当然,在var color = range.format.fill.color
和load
之后),getter将触发而不是setter,颜色变量将获得范围的当前填充颜色。
现在,这是常规属性。无论何时设置数组的元素,都可以有效地将数组值作为getter访问。从运行时的角度来看,这一行与稍微冗长的版本没有区别:
sync
因为var array = range.values;
array[r][c] = '-';
的getter返回一个非常简单的JS数组对象,访问它然后设置它的值不会将它传播回原始的Range对象。
如果希望将值反射回来,最好的方法是在同步后立即获取对数组的引用(即var array = range.values,如上所述),然后在数组上设置值根据需要,然后最终将其设置回对象:range.values
。
这意味着您还可以在适当的位置修改values数组,然后在循环完成时将values属性赋值回自身(range.values = array
)。然而,这看起来很尴尬,好像它是一个无操作,而实际上它不是。所以个人而言,我更喜欢在开始时检索数组并将其分配给自己的变量,然后进行任何必要的修改,最后设置完整的数组。
更新以澄清上述内容:
非常清楚,通过访问range.values = range.values
,.values
等, ARE 纯粹的vanilla JS数组返回了数组。这实际上是问题的症结所在:为了让Office.js返回纯粹的对象,这意味着那些纯粹的对象不能被sp" spiked"能够反映变化。
对于它的价值,我们实际上有一个即将推出的功能,应在一两个月内推出,我们将在其中引入.formulas
语法,如:
object.set
这样可以更方便地在同一个对象上设置多个属性,但它也可以使数组属性更容易处理。