RTD Server does not send update notifications to multiple Excel instances (284883)



The information in this article applies to:

  • Microsoft Office Excel 2003
  • Microsoft Excel 2002
  • Microsoft Visual Basic Professional Edition for Windows 6.0

This article was previously published under Q284883

SYMPTOMS

When you use multiple instances of Excel with your RealTimeData (RTD) server, you may receive the following message:
The real-time data server 'servername.classname' is not responding. Would you like Microsoft Excel to attempt to restart the server?
Consequently, your RTD server is unable to send update notifications to multiple instances of Excel.

CAUSE

You may receive this message if your RTD server is an ActiveX EXE that is built for MultiUse instancing, which is a default setting for ActiveX EXE projects in Visual Basic. An ActiveX EXE that is MultiUse can be shared among clients. Separate Excel instances cannot share RTD servers; when Excel starts an RTD Server, it calls the RTD Server's ServerStart method and passes it a reference to the CallBack object for that instance of Excel. Therefore, if two instances of Excel attempt to share the same RTD server, the second instance replaces the CallBack object for the first instance, thereby invalidating the CallBack object for the first instance.

RESOLUTION

Use SingleUse instancing for ActiveX EXE components that will act as RTD servers for Excel. When you build ActiveX EXE components as SingleUse, each instance of Excel has its own instance of the RTD server.

Another solution is to use an ActiveX dynamic-link library (DLL) for your RTD server rather than an ActiveX EXE. ActiveX DLLs load in the same process space as their clients, and each instance of Excel always has its own instance of the RTD server.

MORE INFORMATION

Steps to reproduce the problem

  1. In Visual Basic, create a new ActiveX EXE project.
  2. On the Project menu, click References. Select Microsoft Excel 2002 Object Library and click OK.
  3. On the Project menu, click Project1 Properties. Change the Project Name to "RTDExe" and click OK.
  4. Change the Name property of the Class1 class module to "Example". Add the following code to the class module:
    Option Explicit
    
    Implements IRtdServer  'Interface allows Excel to contact this RealTimeData server.
    
    Dim nCounter As Long
    
    Private Function IRtdServer_ConnectData(ByVal TopicID As Long, Strings() As Variant, _
       GetNewValues As Boolean) As Variant
        IRtdServer_ConnectData = nCounter
    End Function
    
    Private Sub IRtdServer_DisconnectData(ByVal TopicID As Long)
        nCounter = 0
    End Sub
    
    Private Function IRtdServer_Heartbeat() As Long
        'Do nothing.
    End Function
    
    Private Function IRtdServer_RefreshData(TopicCount As Long) As Variant()
        Dim aUpdates(0 To 1, 0 To 0) As Variant
        nCounter = nCounter + 1
        aUpdates(0, 0) = 0   'For this sample, we only refresh topic id = 0
        aUpdates(1, 0) = nCounter
        TopicCount = 1
        IRtdServer_RefreshData = aUpdates
    End Function
    
    Private Function IRtdServer_ServerStart(ByVal CallbackObject As Excel.IRTDUpdateEvent) As Long
        nCounter = 0
        Set oCallBack = CallbackObject
        g_TimerID = SetTimer(0, 0, TIMER_INTERVAL, AddressOf TimerCallback)
        If g_TimerID > 0 Then IRtdServer_ServerStart = 1       'Any value <1 indicates failure.
    End Function
    
    Private Sub IRtdServer_ServerTerminate()
        KillTimer 0, g_TimerID
    End Sub
    					
  5. From the Project menu, select Add Module. Add the following code to the new module:
    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
    					
  6. On the File menu, click Make RTDExe.exe to build the component.
  7. In Excel, create a new workbook.
  8. In cell A1, type the following formula:

    =RTD("RTDExe.Example",,"X")

    The function returns 0.
  9. After five seconds, the value in A1 increments to indicate that the server is notifying Excel of updates.
  10. Start another instance of Excel and add a new workbook.
  11. In cell A1, type the following formula:

    =RTD("RTDExe.Example",,"X")

    The function returns 0.
  12. The value in A1 of the second instance of Excel continues to update, but the value in A1 of the first instance does not. After the heartbeat interval has elapsed (15 seconds is the default), the first instance of Excel displays the following error message:
    The real-time data server 'rtdexe.example' is not responding. Would you like Microsoft Excel to attempt to restart the server?
    If you click Yes, the server restarts and the first instance of Excel receives update notifications from the server. However, after you restart the server, the second instance of Excel then generates the same message after the heartbeat interval has been reached.
To correct the problem so that you do not receive this error, switch to the project in Visual Basic, change the Instancing property of the Example class to SingleUse, and then rebuild the RTD server.

REFERENCES

For more information, click the following article number to view the article in the Microsoft Knowledge Base:

285339 How to create a RealTimeData Server for Excel 2002


Modification Type:MinorLast Reviewed:4/1/2005
Keywords:kberrmsg kbpending kbprb KB284883 kbAudDeveloper