浅谈Excel开发(六) Excel的异步自定义函数

相关文章:

浅谈Excel开发(1) Excel开发概述

浅谈Excel开发(二) Excel 菜单系统

浅谈Excel开发(三) Excel 对象模型

上文介绍了Excel中的自定义函数(UDF ),它极大地扩展了Excel插件的功能,使得我们可以将业务逻 辑以Excel函数的形式表示,并可以根据这些细粒度的自定义函数,构建各种复杂的分析报表。

普通的UDF自定义函数的基本执行逻辑是,Excel接受用户输入的函数表达式,然后通过UDF函数的处理 逻辑进行处理,在处理过程中,Excel 的UI界面会一直等待函数体执行完成之后更新单元格数据。和大多 数同步应用一样,同步的UDF函数会阻塞Excel UI线程,并且不方便动态扩展计算能力,在处理逻辑比较 复杂、进行耗时的计算逻辑的时候,会造成较差的用户体验。所以我们需要开发异步的UDF函数。

一 问题的提出

通常,当用户在Excel中输入自定义函数的时候,我们希望实现以下表现:

开启另外一根线程或者在线程池中处理函数计算逻辑(不同于Excel UI线程)。

同时立即返回“Calculating”,“Fetching”或“Loading”等值提 示用户正在计算。

待计算完成之后,通知Excel重新计算该单元格。

返回真正的计算结果。

以上步骤中,难点在于第三步,一般的函数在第二步返回值之后,整个过程就结束了。由于函数计算 不在Excel主线程中,而刷新Excel单元格重新计算时要在Excel 主线程中进行,并且要刷新哪一个单元格 还需要指明,而且在异常处理上比较麻烦。

在Excel 2010中,提供了直接编写异步UDF的能力,不过只有在使用C/C++开发的XLL Addin中才能使用 ,并且不向下兼容。要编写适用于大多数版本的Excel(03及以上版本)必须使用Excel已经提供的编程机制 。我们可以利用在上文介绍的Excel RTD函数来解决以上问题,Excel RTD机制是Excel 2002就引入的,因 此向上兼容性良好。使用Excel RTD来实现异步UDF函数的基本原理是,当用户在单元格输入函数时:

将函数以RTD函数请求,记录下TopicID,以及请求的表达式及参数,并返回 “Calculating”提示用户正在处理

开辟另外线程处理该TopicID对应的Excel请求,并计算出结果,保存。

调用UpdateNotify方式,请求Excel重新计算单元,在重新计算的单元格中,根据TopicID,以及计算 的结果值,返回给Excel

Excel根据返回的计算结果值,刷新单元格。

根据以上分析,为Excel编写异步UDF函数的可用的解决方案为:

在Excel 2010及以上版本,可以利用C/C++调用Excel API,开发XLL类型插件实现。

在Excel2002 及以上版本,可以利用Excel RTD函数,来实现

通过第三方类库,如Excel-DNA中引入的ReactiveExtension来实现。

考虑到Excel个版本最大限度的兼容性以及本系列文章主要关注.NET 下的Excel插件开发,所以将重点 介绍第2种方法。

二 如何使用RTD实现异步UDF

正如前文所述,RTD函数主要是用来作为实时数据更新来使用的,但是我们可以利用RTD函数的这种特 殊的Push-Pull机制来开发异步的UDF函数。异步UDF函数的主要实现框架如下图:

基于RTD的异步UDF函数的实现大致流程如上:

用户输入UDF函数,在VBA函数层面上,将UDF函数的函数名,及参数作为RTD函数的参数数组,在内部 发起RTD函数调用。

在RTD函数的ConnectData方法中,将该次请求Excel分配的TopicID,以及请求的参数,包括函数名, 参数拼接成Formula的样式,作为Key保存到一个全局的Dictionary中,Value为一个实体类,该实体类记 录了此次的TopicID,以及该Key的请求返回的值Result(Object类型的)以及其他一些字段。

ConnectData返回Loading,或者其他提示符,在单元格中显示,提示正在后台运算。

同时,另开一个线程对全局的请求Dictionary里面的请求进行处理,这个过程涉及到同步的处理,因 为有可能在处理请求的时候,又有新的请求添加进来。

取出key,解析方法名及参数,使用反射或者一些高效率的方法获取该请求对应的值,存储到key对应 的Value的实体的Result字段中。

同时调用RTD的UpdateNotify方法,通知Excel有数据要更新。

Excel调用RTD的RefreshData方法,然后将全局请求的Dictionary中有结果值的数据项及TopicID,放 到二维数组中,并返回。

Excel单元格显示为该请求实际返回的结果值。

时间: 2024-07-30 23:54:03

浅谈Excel开发(六) Excel的异步自定义函数的相关文章

浅谈Android开发中项目的文件结构及规范化部署建议_java

一.几句话 使用Gradle及其推荐的项目框架 把密码等敏感数据放入gradle.properties 不要自己写Http客户端,使用Volley或OkHttp库 使用Jackson库来解析JSON数据 避免Guava并出于Dalvik 65K methods limit不要使用过多的库 使用Fragment来绘制UI界面 Activity主要用来管理Fragment 布局文件XML也是代码,好好组织它们 在布局文件里,使用styles以避免重复的属性 使用多个style文件而不是一个巨大的st

浅谈PHP开发团队的管理之道

说明:本文节选自<浅谈PHP开发团队管理及程序员做人问题>.全文请点击这里访问. 看了标题,也许很多程序员会反感的说:"程序员的做人问题先不用谈,你想出来这个标题,那你做人是不是有问题吧!" 笔者本人并不反驳这样的说法,每个人都有自己的做人原则.法国人的那句俗话说的好:"我不苟同你的思想,但是我绝对捍卫你思想的自由". 是,这是站在个人的立场上可以那么说.但是如果站在一个团队的立场上呢?一切不尽然了! 无论马拉车的原理也好,还是木桶原理也好,西方人整出来

PHP移动互联网开发笔记(4)——自定义函数及数组

一.自定义函数 自定义函数就是我们自己定义的函数,在PHP中自定义函数格式如下: function funname(arg1, arg2, arg3......){ //TODO return values; } <?php function fun($m, $n){ if($m==0 $n==0){ return 0; }else{ $a=$m*$n; return $a; } } $p=2; $h=3; echo $p."*".$h."=".fun($p,

浅谈Excel开发(1) Excel开发概述

做Office相关的开发工作快一年多了,在这一年多里,在插件的开发中遇到了各种各样的问题和困难,还好同事们都很厉害,在和他们的交流讨论中学到了很多的知识.目前Office相关的开发资料是比较少的,最最开始的时候,我看的是一本英文资料,然后再就是MSDN上面去提问了.所以我想写一点东西,让大家也少走一些弯路. 这篇文章就简要介绍一下Office开发的一些相关的知识,使大家对这个有一个大体的了解. 首先来看一看Office 的开发方式. 一 Office开发方式 1 VBA (Visual Basi

浅谈Symphony Spreadsheet在Excel报表测试中的应用

读者通过阅读本文,可以学习到 Symphony Spreadsheet 简单公式的书写,以及一些使用技巧,可以快速的运用到报表测试中,降低测试复杂度,有效提高测试结果准确性. 报表测试中常见数据对比 在 ERP 和 BI 项目测试过程中,对报表数据进行校验是非常有必要的,常见的数据对比场景如下:从系统导出的 http://www.aliyun.com/zixun/aggregation/16544.html">Excel 格式的报表数据,然后再给一份业务数据的源数据,要求校验报表数据是否正

浅谈网站开发的六部曲

中介交易 SEO诊断 淘宝客 云主机 技术大厅 计划阶段也就是是概要设计 在计划的时候,项目经理会制定相应详细的项目开发计划.在这个计划中需要明确几个主要的版本控制控制周期和操作约定.包括以下几点: 创建分支时间 从各个网站的特点可以看出,网站的程序开发和发布是非常频繁的工作.为了更好的提高网站的开发速度,需要进行分布式开发.但在进行分布开发的时候需要的注意的每一个网站的开发目标要明确,在每一段时间可能会产生相应的分支,这里有用到了分支.分支的创建过早可能会与主要的开发流程差别太大,创建过晚可能

浅谈Java开发人员对JCP感觉失望的原因

其中一种感觉就是JCP已经失去了它的吸引力,它不再是被当成针对解决问题的社区,相反,它只是被看成是一些大公司所利用的鉴定规范通过的橡皮图章.这些大公司凭着自身的钱势和力量来指定各种规范从而达到满足自己的利益. "这与有些官僚机构很相似,只不过是JCP在短时间出现这样的发展显得过于迅速." Redwood城市的Infravio公司的CTO,MukundBalasubramanian谈到JCP时,他这样说到,"现在有太多的程序员和公司都卷入JCP,每天都开发很多软件,每天都有大量

浅谈AJAX开发技术_AJAX相关

AJAX(Asynchronous JavaScript and XML,异步JavaScript和XML),AJAX并不是一项新的技术,它产生的主要目的是用于页面的局部刷新,从之前的代码开发来看,读者可以发现,每当用户向服务器端发出请求时,那怕需要的只是简单的更新一点点的局部内容,服务器端都会将一个整体的页面进行刷新,并重新生成代码,这样一来程序的性能肯定会有所降低的,而如果采用了AJAX技术之后,就可以实现局部的内容变更,而不用再进行整体的页面刷新,显然处理的性能要比前者高很多 . 在AJA

HIMI浅谈游戏开发DE自学历程!(仅供参考)

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/game-detail/382.html .                              希望童鞋们不要在此篇博文中发表技术问题,谢谢合作 很多群友进群之后都会问我如何自学:那么今天就专门写篇博文说一下,供各位童鞋交流和学习: 大家先来看一段我每天时间安排的数据: 上班之前: 学习J2me的时候,每天除了饿了去吃饭之外,全部用来