2016-07-12 124 views
0

选择具有公式的单元格后,我们可以在Excel公式栏中选择其公式的一部分并计算它(通过按F9)。我需要通过JavaScript API重新评估子公式。评估公式的子公式

例如,让我们假设细胞A1B1的值,C1分别123和Cell D1包含公式=A1+B1+C1。我希望能够快速评估子公式,如A1+B1,B1+C1,并获得结果35

在VBA中,下manual计算模式,我们可以的D1初始式的子式(例如,=A1+B1)存储在变量中,然后分配到D1得到结果3,然后还原回初始公式到D1好像什么都没有发生;此评估不会提高D1后代的任何其他单元的计算(感谢manual模式)。

但是,使用JavaScript API时,重新计算仅适用于automatic模式。如果我们将一个子公式(例如,=A1+B1)分配给D1D1后代的所有单元格都会被ctx.sync重新计算,这可能很昂贵。

那么有没有一种方法或解决方法来优化?

一种可能的解决方法是在工作簿中找到没有单元依赖的单元格(例如工作表的usedRange之外的单元格,但我们仍然需要确保没有单元格依赖于该单元格,原因是usedRange ...),然后为该单元格分配一个子公式并获取该值。这种方法的缺点是

1)它仍然是一个黑客,并修改工作表的区域。

2)用户定义的函数(如果编程不好)可能依赖于工作表的尺寸或单元的位置。在这种情况下,评估孤立单元中的用户定义函数可能会导致原始单元中的评估产生不同的结果(或副作用)。

任何人都可以帮忙吗?

+0

我很想了解更多关于您正在使用如此多的功能和API功能的这个加载项。如果您想演示或分享您的想法,请通过[email protected]与我联系,并提供我的工作电子邮件地址。谢谢! –

+0

感谢您的关注和感谢@MichaelZlatkovsky不断回答我的问题。我认为这是一个特权,可以直接与微软团队联系,并且非常感谢。实际上,我之前已经在OCaml中开发了一个“引擎”,并且一个月后我一直在开发Excel JavaScript加载项作为“接口”。我已经提交了2个,并且正在开发第三个(所以不是所有的功能都集成在一个插件中)。当我认为我的加载项是可表达的,我很乐意继续与你们密切合作(并远程)... – SoftTimur

回答

0

我认为你列出的第一种方法可能是最简单的。也就是说,重写单元格的公式并将其保存为一个JavaScript变量(字符串)。接下来修改公式,对该值发出一个负载,然后将公式恢复为保存字符串。这种方法唯一的缺点就是你搞乱了某人的公式,这意味着如果在步骤1和步骤2之间出现问题,你就会使文档处于肮脏的状态。而且,正如你所说的那样,它可能会对计算产生下游影响(表现方式)。

另外,如果你真的知道有什么公式,你可以使用“工作表函数”功能。例如,在此计算20 +两个工作表范围总和的总和。

Excel.run(function (ctx) { 
    var result = ctx.workbook.functions.sum(
     20, 
     ctx.workbook.worksheets.getItem("Sheet1").getRange("F3:F5"), 
     ctx.workbook.worksheets.getItem("Sheet1").getRange("H3:H5") 
    ).load(); 

    return ctx.sync(); 
}).catch(function(e) { 
    console.log(e); 
}); 

这是“最干净”的方式来计算的,因为它不影响工作状态,甚至可以连锁计算:

Excel.run(function (ctx) { 
    var range = ctx.workbook.worksheets.getItem("Sheet1").getRange("E2:H5"); 

    var sumOfTwoLookups = ctx.workbook.functions.sum(
     ctx.workbook.functions.vlookup("Wrench", range, 2, false), 
     ctx.workbook.functions.vlookup("Wrench", range, 3, false) 
     ); 
    sumOfTwoLookups.load(); 

    return ctx.sync(); 
}).catch(function(e) { 
    console.log(e); 
}); 

的缺点是,这将不与UDF一起工作(以及与数组公式有关的事情),以及您需要先验地知道细胞组成的公式。但是如果你在谈论计算公式的子公式,我假设你已经有了关于公式的一些信息,所以后者可能不成问题。

+0

好的,这很有趣,我不知道“工作表函数”。 ..有一点是我没有找到'-','/'和'+','*'的函数(而不是使用诸如SUM,PRODUCT之类的解决方法)。如果它们不存在,似乎我们必须执行两次'ctx.sync'才能实现SUM(1,SUM(3,4)-2)',因为我们不能直接写'var result = ctx。 workbook.functions.sum(1,ctx.workbook.functions.sum(3,4)-2)'... – SoftTimur

+0

我问[另一个问题](http://stackoverflow.com/questions/38337870/worksheet-function对于这个...... – SoftTimur

+0

对于这个和许多其他场景,真正需要的是相当于VBA Application.Evaluate和Worksheet.Evaluate(最好是少了一些比VBA评估) –