如何为 Excel 创建 RealTimeData 服务器

文章翻译 文章翻译
文章编号: 285339 - 查看本文应用于的产品
展开全部 | 关闭全部

概要

Microsoft Excel 提供了一个新的工作表函数 RTD,此函数允许通过调用组件对象模型 (COM) 自动化服务器来实现实时数据检索。本文介绍如何使用 Visual Basic 创建 RealTimeData 服务器,以使用 Excel 的 RTD 函数。

更多信息

RTD 工作表函数使用以下语法:
=RTD(ProgID,Server,String1,[String2],...)
第一个变量 ProgID 表示 RealTimeData 服务器的编程标识符 (ProgID)。Server 变量指示运行 RealTimeData 服务器的计算机的名称;如果 RealTimeData 服务器在本地运行,则可以将此变量设置为空字符串或将其忽略。其他变量只表示发送到 RealTimeData 服务器的参数;这些参数的每个唯一组合都表示一个“主题”,每个“主题”又有一个关联的“主题 ID”。这些参数区分大小写。例如,以下内容演示将生成三个不同主题 ID 的 RTD 服务器调用:
=RTD("ExcelRTD.RTDFunctions",,"AAA", "10")

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

=RTD("ExcelRTD.RTDFunctions",,"aaa", "5")
要使 COM 自动化服务器成为 RealTimeData 服务器,以使用 Excel 的 RTD 函数,它必须实现 IRTDServer 接口。此外,该服务器还必须实现 IRTDServer 的所有方法:

ServerStart
当 Excel 请求服务器的第一个 RTD 主题时调用。ServerStart 会在成功时返回 1,并在失败时返回负值或 0。ServerStart 方法的第一个参数是一个回调对象,当 Excel 应从 RealTimeData 服务器收集更新时,RealTimeData 服务器将使用此对象通知 Excel。
ServerTerminate
当 Excel 不再需要从 RealTimeData 服务器获取 RTD 主题时调用。
ConnectData
每当 Excel 从 RealTimeData 服务器请求新的 RTD 主题时调用。
DisconnectData
每当 Excel 不再需要某个特定的主题时调用。
HeartBeat
如果自上次通知 Excel 从 RealTimeData 服务器获取更新起已经过给定的间隔,Excel 将调用此方法。
RefreshData
当 Excel 请求刷新主题时调用。RefreshData 在服务器通知 Excel 存在更新后调用,并返回要更新的主题计数以及每个主题的主题 ID 和值。

创建示例 RealTimeData 服务器

下面的示例演示如何在 Microsoft Excel 2002 中创建和使用 RealTimeData 服务器。此服务器只提供一个每隔 10 秒在工作表上更新一次的计数器。该服务器最多可接受两个主题字符串。第一个主题字符串可以是 AAA、BBB 和 CCC;任何其他主题字符串都将被视为无效的主题字符串,此时服务器将对 RTD 函数返回 #VALUE!。第二个字符串是一个数值,它表示返回值应采用的递增方式。如果省略第二个字符串,则默认递增值为 1。如果第二个字符串不是数值,服务器将对 RTD 函数返回 #NUM!。
  1. 在 Visual Basic 中启动一个新的 ActiveX DLL 工程。
  2. 在“工程”菜单上,单击“引用”,选择与您的 Excel 版本相对应的对象库,然后单击“确定”。例如,请选择下列选项之一:
    • 对于 Microsoft Office Excel 2007,请选择“Microsoft Excel 12.0 对象库”。
    • 对于 Microsoft Office Excel 2003,请选择“Microsoft Excel 11.0 对象库”。
    • 对于 Microsoft Excel 2002,请选择“Microsoft Excel 10.0 对象库”。
  3. 在“工程”菜单上,单击“Project1 属性”。将“工程名称”更改为“ExcelRTD”,然后单击“确定”。
  4. 将类模块“Class1”的“Name”属性更改为“RTDFunctions”。向“RTDFunctions”中添加以下代码:
    Option Explicit
    
    Implements IRtdServer  'Interface allows Excel to contact this RealTimeData server
    
    Private m_colTopics As Collection
        
    Private Function IRtdServer_ConnectData(ByVal TopicID As Long, Strings() As Variant, GetNewValues As Boolean) As Variant
        '** ConnectData is called whenever a new RTD topic is requested
        
        'Create a new topic class with the given TopicId and string and add it to the
        'm_colTopics collection
        Dim oTopic As New Topic
        m_colTopics.Add oTopic, CStr(TopicID)
        oTopic.TopicID = TopicID
        oTopic.TopicString = Strings(0)
        If UBound(Strings) >= 1 Then oTopic.SetIncrement Strings(1)
        
        'For this example, the initial value for a new topic is always 0
        IRtdServer_ConnectData = oTopic.TopicValue
        
        Debug.Print "ConnectData", TopicID
    End Function
    
    Private Sub IRtdServer_DisconnectData(ByVal TopicID As Long)
       '** DisconnectData is called whenever a specific topic is not longer needed
       
       'Remove the topic from the collection
       m_colTopics.Remove CStr(TopicID)
       
       Debug.Print "DisconnectData", TopicID
    End Sub
    
    Private Function IRtdServer_Heartbeat() As Long
        '** Called by Excel if the heartbeat interval has elapsed since the last time
        '   Excel was called with UpdateNotify.
        Debug.Print "HeartBeat"
    End Function
    
    Private Function IRtdServer_RefreshData(TopicCount As Long) As Variant()
        '** Called when Excel is requesting a refresh on topics. RefreshData will be called
        '   after an UpdateNotify has been issued by the server. This event should:
        '   - supply a value for TopicCount (number of topics to update)
        '   - return a two dimensional variant array containing the topic ids and the
        '     new values of each.
       
        Dim oTopic As Topic, n As Integer
        ReDim aUpdates(0 To 1, 0 To m_colTopics.Count - 1) As Variant
        For Each oTopic In m_colTopics
            oTopic.Update
            aUpdates(0, n) = oTopic.TopicID
            aUpdates(1, n) = oTopic.TopicValue
            n = n + 1
        Next
        TopicCount = m_colTopics.Count
        IRtdServer_RefreshData = aUpdates
       
       Debug.Print "RefreshData", TopicCount & " topics updated"
    End Function
    
    Private Function IRtdServer_ServerStart(ByVal CallbackObject As Excel.IRTDUpdateEvent) As Long
        '** ServerStart is called when the first RTD topic is requested
        
        Set oCallBack = CallbackObject
        Set m_colTopics = New Collection
        g_TimerID = SetTimer(0, 0, TIMER_INTERVAL, AddressOf TimerCallback)
        If g_TimerID > 0 Then IRtdServer_ServerStart = 1       'Any value <1 indicates failure.
        
        Debug.Print "ServerStart"
    End Function
    
    Private Sub IRtdServer_ServerTerminate()
        '** ServerTerminate is called when no more topics are needed by Excel.
        
        KillTimer 0, g_TimerID
    
        '** Cleanup any remaining topics. This is done here since 
        '   IRtdServer_DisconnectData is only called if a topic is disconnected 
        '   while the book is open. Items left in the collection when we terminate
        '   are those topics left running when the workbook was closed.
    
        Dim oTopic As Topic
        For Each oTopic In m_colTopics
            m_colTopics.Remove CStr(oTopic.TopicID)
            Set oTopic = Nothing
        Next
    
        Debug.Print "ServerTerminate"
      
    End Sub
    
    					
  5. 在“工程”菜单上,单击“添加类模块”。将类模块的“Name”属性更改为“Topic”,并将“Instancing”属性更改为“Private”。向“Topic”类模块中添加以下代码:
    Option Explicit
    
    Private m_TopicID As Long
    Private m_TopicString As String
    Private m_Value As Variant
    Private m_IncrementVal As Long
    
    Private Sub Class_Initialize()
        m_Value = 0
        m_IncrementVal = 1
    End Sub
    
    Friend Property Let TopicID(ID As Long)
        m_TopicID = ID
    End Property
    
    Friend Property Get TopicID() As Long
        TopicID = m_TopicID
    End Property
    
    Friend Property Let TopicString(s As String)
        s = UCase(s)
        If s = "AAA" Or s = "BBB" Or s = "CCC" Then
            m_TopicString = s
        Else
            m_Value = CVErr(xlErrValue) 'Return #VALUE if not one of the listed topics
        End If
    End Property
    
    Friend Sub Update()
        On Error Resume Next 'the next operation will fail if m_Value is an error (like #NUM or #VALUE)
        m_Value = m_Value + m_IncrementVal
    End Sub
    
    Friend Sub SetIncrement(v As Variant)
        On Error Resume Next
        m_IncrementVal = CLng(v)
        If Err <> 0 Then
            m_Value = CVErr(xlErrNum) 'Return #NUM if Increment value is not numeric
        End If
    End Sub
    
    Friend Property Get TopicValue() As Variant
        If Not (IsError(m_Value)) Then
            TopicValue = m_TopicString & ": " & m_Value
        Else
            TopicValue = m_Value
        End If
    End Property
    					
  6. 在“工程”菜单上,选择“添加模块”。向新模块中添加以下代码:
    Public Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, _
    ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    
    Public Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
    
    Public Const TIMER_INTERVAL = 5000
    Public oCallBack As Excel.IRTDUpdateEvent
    Public g_TimerID As Long
    
    Public Sub TimerCallback(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
        oCallBack.UpdateNotify
    End Sub
    					
  7. 在“文件”菜单上,单击“生成 ExcelRTD.dll”以生成组件。

在 Excel 中使用 RTD 服务器

  1. 在 Microsoft Excel 中启动一个新工作簿。
  2. 在单元格 A1 中,请输入以下公式,然后按 Enter 键:
    =RTD("ExcelRTD.RTDFunctions",,"AAA", 5)
    初始返回值为“AAA: 0”。五秒钟后,该值将更新为“AAA:10”,10 秒钟后,该值将更新为“AAA:15”,依此类推。

  3. 在单元格 A2 中,请输入以下公式,然后按 Enter:
    =RTD("ExcelRTD.RTDFunctions",,"BBB", 3)
    初始返回值为“BBB: 0”。该单元格值每隔五秒递增 3。

  4. 在单元格 A3 中,请输入以下公式,然后按 Enter:
    =RTD("ExcelRTD.RTDFunctions",,"AAA", 5)
    此单元格的初始返回值与单元格 A1 的内容匹配,因为它使用的“主题”与 A1 中所用的主题相同。

  5. 在单元格 A4 中,请输入以下公式,然后按 Enter:
    =RTD("ExcelRTD.RTDFunctions",,"AAA", 10)
    初始返回值为“AAA: 0”。与其他单元格相同,该单元格值也是每隔五秒钟递增一次。请注意,它的返回值与单元格 A1 或 A3 的内容并不匹配,因为它们传递给服务器的参数组合是不同的。
在本演示中,RTD 服务器已经过编译,Excel 使用的是该组件的运行时版本。出于调试目的,RTD 服务器可以在 Visual Basic IDE 中运行。

要在调试模式下运行,请按照下列步骤操作:
  1. 退出 Microsoft Excel 并切换到 Visual Basic 中的工程。
  2. 按 F5 启动该组件。如果显示“工程属性”对话框,请单击“确定”选择“等待创建组件”的默认选项。
  3. 确保显示 Visual Basic 中的“即时”窗口。当您在单元格中输入公式以及单元格被更新时,请在 Visual Basic 中检查“即时”窗口的内容,以确定触发各个事件的都是哪些操作。
关于 DisconnectData 事件的说明

虽然 Excel 是 RTD 服务器的订户,但当它不再需要主题时(例如删除或清除单元格中的 RTD 公式时),它将触发“DisconnectData”事件。然而,当您关闭工作簿或退出 Excel 时,Excel 并不对 RTD 服务器的每个主题都调用“DisconnectData”,而是只调用“ServerTerminate”。当您创建 RTD 服务器时,应编写一些代码,以便在激发“ServerTerminate”事件时执行任何必需的清理主题或其他对象的操作。

(c) Microsoft Corporation 2001,保留所有权利。由 Microsoft Corporation 的 Lori B. Turner 供稿。

参考

有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
284883 RTD 服务器不向多个 Excel 实例发送更新通知

属性

文章编号: 285339 - 最后修改: 2008年8月27日 - 修订: 5.0
这篇文章中的信息适用于:
  • Microsoft Office Excel 2007
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 标准版
  • Microsoft Visual Basic 6.0 专业版
关键字:?
kbexpertisebeginner kbautomation kbhowto KB285339
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com