采用Excel RTD(Excel Real-Time Data)技术实时刷新Excel单元格的数据

本文介绍了Excel RTD技术,这是一种用于实时显示和更新Excel中数据的方法。RTD通过'推-拉'方式提高数据更新效率,相比DDE更稳定快速。使用RTD涉及RTD函数、IRTDServer接口及相关的ConnectData、DisconnectData等方法。文章还展示了如何创建RTD Server的简单示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从Excel 2002开始,微软提供了一种叫做Excel RTD(real-time data)的技术,使用该技术可以在Excel中实时查看和更新数据。RTD采用所谓的“推-拉”相结合的技术,使得其在实时获取和更新不断变化的数据(例如股票、汇率、天气)的性能方面,相比较之前的DDE更加稳健和快速。在MSDN的Real-Time Data FAQ上有其性能描述(http://msdn.microsoft.com/en-us/library/aa140060(v=office.10).aspx#odc_xlrtdfaq_whatisrtd),据说在一台配置为 Pentium III 500 MHz 的CPU和 128 MB 内存的电脑上,RTD可以在一秒内对20000个独立的主题(topic)更新三次,对于单独一个主题的更新频率可达1秒200次。

 

在Excel 中使用RTD非常简单,Excel 提供了一个新的工作表函数 RTD,此函数允许通过调用组件对象模型 (COM) 自动化服务器来实现实时数据检索。RTD 工作表函数使用以下语法:

    "=RTD(ProgID, Server, String 1, String 2, ... String n)"

第一个变量 ProgID 表示Real-Time Data 服务器(RTD Server)的编程标识符 (ProgID)。Server 变量指示运行RTD Server的计算机的名称;如果RTD Server在本地运行,则可以将此变量设置为空字符串或将其忽略。其他变量只表示发送到RTD Server的参数;这些参数的每个唯一组合都表示一个“主题”(topic),每个“主题”有一个关联的“主题 ID”(topic id)。这些参数区分大小写。例如,以下内容演示将生成三个不同主题ID的RTD Server调用:

=RTD("ExcelRTD.RTDFunctions",,"AAA", "10")
=RTD("ExcelRTD.RTDFunctions",,"AAA", "5")
=RTD("ExcelRTD.RTDFunctions",,"aaa", "5")

 

要使用 Excel 的 RTD 函数,必须注册一个实现 IRTDServer 接口的COM组件。实现这个接口的COM组件就是所谓的RTD Server。IRTDServer具有以下成员:

ServerStart(CallbackObject)

CallbackObject 是一个IRTDUpdateEvent类型的参数,它有一个UpdateNotify方法,用于通知Excel有更新的数据可用(push)。这样Excel就会通过调用RefreshData方法来刷新所有的主题(pull)。当 Excel 请求RTD Server的第一个 RTD 主题时调用ServerStart方法,该方法会在成功时返回 1,并在失败时返回负值或 0。这个方法在随后应用其他RTD函数时不会再次被调用。

ConnectData(TopicID, Strings, GetNewValues)

其中,TopcID 唯一标识这个函数在Excel中的一个应用,即使复制多份到不同的单元格,对于Excel来讲,也只是对应一个主题。这个 topicID 由Excel返回,我们需要将其记录下来,以便为其提供更新的数据。Strings 是一个System.Array,用于接收RTD函数传入的参数(String 1...String n),这是一个引用类型的参数。GetNewValues 用于确定是否总是获取最新数据,如果这个参数传入true,则每次保存Excel文档以后,再次重新打开时,看到的不一定是上次保存时的数据,而是最新的实时数据,这也是一个引用类型的参数。

每当一个新的主题(Topic)被应用到Excel,ConnectData都会被调用。在这里,需要保存传入的新的TopicID和查询参数以供之后更新数据使用。为此,需要定义好自己的数据结构。

DisconnectData(TopicID)

与ConnectData一样,TopcID 唯一标识这个函数在Excel中的一个应用。当我们从Excel中移除一个主题(删除所有采用相同参数的RTD函数)之后,DisconnectData将被调用,在这里,可以释放对这个主题的监控,并不再为其获取新数据。

Heartbeat

确定RTD Server是不是依然可用,0和负数代表不可用,1代表可用。Excel会调用此方法确定服务是否断连。

RefreshData(TopicCount)

TopicCount表示要更新的主题数量,这是一个引用类型的参数,用于返回给Excel。我们可以定义一个时钟,用于定时向数据源获取数据,这样,在时钟的Elapsed事件中,获取最新数据,并调用xlRTDUpdate成员的UpdateNotify方法以通知Excel,新的数据准备完毕。这样Excel就会调用RefreshData方法,来对工作簿中的数据进行更新。

ServerTerminate

当Excel不再需要从RTD Server获取实时数据时被调用。在这里,可以执行一些清理,例如清除缓存,关闭时钟等等。至此,一个RTD Server的生命周期就结束了。

 

演练

创建一个项目ExcelRTD,添加Microsoft.Office.Interop.Excel引用。创建一个类MarketData.cs,这个类继承IRtdServer接口,以实现一个RTD Server。新建另一个类DataCollector.cs用于从数据源获取数据。DataCollector有一个方法public DataTable GetMarketData(string keyField, object keyValue)将会在MarketData.cs中被使用。为了图简便,我就贴出MarketData.cs的全部代码。

  

ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5
  6using System.Collections;
  7using System.Configuration;
  8using System.Timers;
  9using System.Runtime.InteropServices;
 10using Microsoft.Office.Interop.Excel;
 11
 12namespace ExcelRTD
 13ExpandedBlockStart.gifContractedBlock.gif{
 14    [ComVisible(true),ProgId("ExcelRTD.MarketData")]
 15    public class MarketDataServer : IRtdServer 
 16ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 17        private IRTDUpdateEvent xlRTDUpdate;
 18        private Timer tmrTimer;
 19        private List<MarketData> marketDatas;
 20
 21        //Lets Excel know that our RTD server is still "alive".
 22        public int Heartbeat()
 23ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 24            return 1;
 25        }

 26        
 27        //Initialize RTD server.
 28        public int ServerStart(Microsoft.Office.Interop.Excel.IRTDUpdateEvent CallbackObject)
 29ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 30            //Hold a reference to the callback object.
 31            xlRTDUpdate = CallbackObject;
 32
 33            //2000 millisecond by default.
 34            int intv = 2000;
 35
 36            //'Create the time with a 5000 millisecond interval.
 37            tmrTimer = new Timer(intv);
 38            tmrTimer.AutoReset = true;
 39
 40            tmrTimer.Elapsed += new ElapsedEventHandler(tmrTimer_Elapsed);
 41
 42            return 1;
 43        }

 44
 45        //Terminate RTD server.
 46        public void ServerTerminate()
 47ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 48            //Clear the RTDUpdateEvent reference.
 49            xlRTDUpdate = null;
 50
 51            //Make sure the timer is stopped.
 52            if (tmrTimer.Enabled)
 53ExpandedSubBlockStart.gifContractedSubBlock.gif            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值