Microsoft KB Archive/284883

= RTD Server does not send update notifications to multiple Excel instances =

Article ID: 284883

Article Last Modified on 5/14/2007

-

APPLIES TO


 * Microsoft Office Excel 2007
 * Microsoft Office Excel 2003
 * Microsoft Excel 2002 Standard Edition
 * Microsoft Visual Basic 6.0 Professional Edition

-



This article was previously published under Q284883



SYMPTOMS
When you use multiple instances of Microsoft Office Excel together 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?

Therefore, 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, Excel calls the RTD Server ServerStart method and then passes it a reference to the CallBack object for that instance of Excel. Therefore, if two instances of Excel try to share the same RTD server, the second instance replaces the CallBack object for the first instance. This behavior invalidates 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 DLL for your RTD server instead of 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.



Steps to reproduce the problem
 In Visual Basic, create a new ActiveX EXE project. On the Project menu, click References. Select Microsoft Excel 2002 Object Library, and then click OK. On the Project menu, click Project1 Properties. Change the Project Name to &quot;RTDExe&quot;, and then click OK. Change the Name property of the Class1 class module to &quot;Example&quot;.</li>  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 </li> On the Project menu, select Add Module.</li>  Add the following code to the new module. Public Declare Function SetTimer Lib &quot;user32&quot; (ByVal hWnd As Long, ByVal nIDEvent As Long, _  ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long Public Declare Function KillTimer Lib &quot;user32&quot; (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 </li> On the File menu, click Make RTDExe.exe to build the component.</li> In Excel, create a new workbook.</li> In cell A1, type the following formula:

=RTD(&quot;RTDExe.Example&quot;,,&quot;X&quot;)

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

=RTD(&quot;RTDExe.Example&quot;,,&quot;X&quot;)

The function returns 0.</li> 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.</li></ol>

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.

<div class="references_section">