Read values from now without excel

josh1

Well-Known Member
#11
Create rtd Client ...........
Code:
    'Option Explicit Off  
    Option Strict Off  
    Imports System.Reflection  
    Imports System.Threading  
    Class Test  
        Private Const RTDProgID As String = "MyRTD.RTD"  
        Private Const RTDUpdateEventProgID As String = "MyRTD.UpdateEvent"  
        Private Const RTDEXEProgID As String = "MyRTDEXE.RTD"  
        Private Const RTDEXEUpdateEventProgID As String = "MyRTDEXE.UpdateEvent"  
        Private Const topicID As Integer = 12345  
        Private Const topic As String = "topic"  
        Sub Main()  
            Dim test As New Test()  
            Console.WriteLine("Test in-process (DLL) RTD server. (.Net style)")  
            test.RtdDotNetStyle(RTDProgID, RTDUpdateEventProgID)  
            Console.WriteLine("Test out-of-process (EXE) RTD server.  (.Net style)")  
            test.RtdDotNetStyle(RTDEXEProgID, RTDEXEUpdateEventProgID)  
            Console.WriteLine("Test in-process (DLL) RTD server. (Visual Basic style)")  
            test.RtdDotNetStyle(RTDProgID, RTDUpdateEventProgID)  
            Console.WriteLine("Test out-of-process (EXE) RTD server.  (Visual Basic style)")  
            test.RtdDotNetStyle(RTDEXEProgID, RTDEXEUpdateEventProgID)  
            Console.WriteLine("Press enter to exit ...")  
            Console.ReadLine()  
        End Sub
 

josh1

Well-Known Member
#12
Code:
       Sub RtdDotNetStyle(ByVal rtdProgId As String, ByVal rtdEventProgId As String)  
            'try  
            '{  
            Try  
                '       // Create the RTD server.  
                '       Type rtd;  
                '       Object rtdServer = null;  
                '       rtd = Type.GetTypeFromProgID(rtdID);  
                '       rtdServer = Activator.CreateInstance(rtd);  
                '       Console.WriteLine("rtdServer = {0}", rtdServer.ToString());  
                Dim rtd As Type = Type.GetTypeFromProgID(rtdProgId)  
                Dim rtdServer As Object = Activator.CreateInstance(rtd)  
                Console.WriteLine("rtdServer = {0}", rtdServer.ToString())  
                '       // Create a callback event.  
                '       Type update;  
                '       Object updateEvent = null;  
                '       update = Type.GetTypeFromProgID(eventID);  
                '       updateEvent = Activator.CreateInstance(update);  
                '       Console.WriteLine("updateEvent = {0}", updateEvent.ToString());  
                Dim update As Type = Type.GetTypeFromProgID(rtdEventProgId)  
                Dim updateEvent As Object = Activator.CreateInstance(update)  
                Console.WriteLine("updateEvent = {0}", updateEvent.ToString())  
                '       // Start the RTD server passing in the callback  
                '       // object.  
                '       Object[] param = new Object[1];  
                '       param[0] = updateEvent;  
                '       MethodInfo method = rtd.GetMethod("ServerStart");  
                '       Object ret; // Return value.  
                '       ret = method.Invoke(rtdServer, param);  
                '       Console.WriteLine("ret for 'ServerStart()' = {0}", ret.ToString());  
                Dim param() As Object  
                param = New Object() {updateEvent}  
                Dim ret As Object = rtd.InvokeMember("ServerStart", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, param)  
                Console.WriteLine("ret for 'ServerStart()' = {0}", ret.ToString())  
                '       // Request data from the RTD server.  
                '       Object[] topics = new Object[1];  
                '       topics[0] = topic;  
                '       Boolean newData = true; // Request new data, not cached data.  
                '       param = new Object[3];  
                '       param[0] = topicID;  
                '       param[1] = topics;  
                '       param[2] = newData;  
                '       method = rtd.GetMethod("ConnectData");  
                '       ret = method.Invoke(rtdServer, param);  
                '       Console.WriteLine("ret for 'ConnectData()' = {0}", ret.ToString());  
                Dim newData As Boolean = True  
                Dim topics(0) As Object  
                topics(0) = topic  
                param = New Object() {topicID, topics, newData}  
                ret = rtd.InvokeMember("ConnectData", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, param)  
                Console.WriteLine("ret for 'ConnectData()' = {0}", ret.ToString())  
                '       // Loop and wait for RTD to notify (via callback) that  
                '       // data is available.  
                '       int count = 0;  
                Dim count As Integer  
                'Do  
                '       {  
                Do  
                    '           count++;  
                    count += 1  
                    '           // Check that the RTD server is still alive.  
                    '           Object status;  
                    '           param = null;  
                    '           method = rtd.GetMethod("Heartbeat");  
                    '           status = method.Invoke(rtdServer, param);  
                    '           Console.WriteLine("status for 'Heartbeat()' = {0}",  
                    '               status.ToString());  
                    Dim status As Object = rtd.InvokeMember("Heartbeat", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, Nothing)  
                    Console.WriteLine("status for 'Heartbeat()' = {0}", status.ToString())  
                    '           // Get data from the RTD server.  
                    '           int topicCount = 0;  
                    '           param = new Object[1];  
                    '           param[0] = topicCount;  
                    '           method = rtd.GetMethod("RefreshData");  
                    '           Object[,] retval = new Object[2, 1];  
                    '           retval = (Object[,])method.Invoke(rtdServer, param);  
                    '           Console.WriteLine("retval for 'RefreshData()' = {0}",  
                    '               retval[1,0].ToString());  
                    Dim topicCount As Integer = 0  
                    param = New Object() {topicCount}  
                    Dim retVal(1, 0) As Object  
                    retVal = CType(rtd.InvokeMember("RefreshData", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, param), Object(,))  
                    Console.WriteLine("retval for 'RefreshData()' = {0}", retVal(1, 0).ToString())  
                    '           // Wait for 2 seconds before getting  
                    '           // more data from the RTD server. This  
                    '           // it the default update period for Excel.  
                    '           // This client can requested data at a  
                    '           // much higher frequency if wanted.  
                    '           Thread.Sleep(2000);  
                    Thread.Sleep(2000)  
                    '       } while (count < 5); // Loop 5 times for test.  
                Loop While count < 5  
                '       // Disconnect from data topic.  
                '       param = new Object[1];  
                '       param[0] = topicID;  
                '       method = rtd.GetMethod("DisconnectData");  
                '       method.Invoke(rtdServer, param);  
                param = New Object() {topicID}  
                rtd.InvokeMember("DisconnectData", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, param)  
                '       // Shutdown the RTD server.  
                '       param = null;  
                '       method = rtd.GetMethod("ServerTerminate");  
                '       method.Invoke(rtdServer, param);  
                rtd.InvokeMember("ServerTerminate", BindingFlags.InvokeMethod, Type.DefaultBinder, rtdServer, Nothing)  
                '   }  
                '   catch (Exception e)  
                '   {  
            Catch ex As Exception  
                '       Console.WriteLine("Error: {0} ", e.Message);  
                Console.WriteLine("Error: {0} ", e.Message)  
                '   }  
            End Try  
        End Sub
 

josh1

Well-Known Member
#13
Code:
        Sub RtdVisualBasicStyle(ByVal rtdProgId As String, ByVal rtdEventProgId As String)  
            'try{  
            Try  
                '       // Create the RTD server.  
                '       Type rtd;  
                '       Object rtdServer = null;  
                '       rtd = Type.GetTypeFromProgID(rtdID);  
                '       rtdServer = Activator.CreateInstance(rtd);  
                '       Console.WriteLine("rtdServer = {0}", rtdServer.ToString());  
                Dim rtdServer As Object = CreateObject(rtdProgId)  
                Console.WriteLine("rtdServer = {0}", rtdServer.ToString())  
                '       // Create a callback event.  
                '       Type update;  
                '       Object updateEvent = null;  
                '       update = Type.GetTypeFromProgID(eventID);  
                '       updateEvent = Activator.CreateInstance(update);  
                '       Console.WriteLine("updateEvent = {0}", updateEvent.ToString());  
                Dim updateEvent As Object = CreateObject(rtdEventProgId)  
                Console.WriteLine("updateEvent = {0}", updateEvent.ToString())  
                '       // Start the RTD server passing in the callback  
                '       // object.  
                '       Object[] param = new Object[1];  
                '       param[0] = updateEvent;  
                '       MethodInfo method = rtd.GetMethod("ServerStart");  
                '       Object ret; // Return value.  
                '       ret = method.Invoke(rtdServer, param);  
                '       Console.WriteLine("ret for 'ServerStart()' = {0}", ret.ToString());  
                Dim ret As Object = rtdServer.ServerStart(updateEvent)  
                Console.WriteLine("ret for 'ServerStart()' = {0}", ret.ToString())  
                '       // Request data from the RTD server.  
                '       Object[] topics = new Object[1];  
                '       topics[0] = topic;  
                '       Boolean newData = true; // Request new data, not cached data.  
                '       param = new Object[3];  
                '       param[0] = topicID;  
                '       param[1] = topics;  
                '       param[2] = newData;  
                '       method = rtd.GetMethod("ConnectData");  
                '       ret = method.Invoke(rtdServer, param);  
                '       Console.WriteLine("ret for 'ConnectData()' = {0}", ret.ToString());  
                Dim topics() As Object = New Object() {topic}  
                Dim newData As Boolean = True  
                ret = rtdServer.ConnectData(topicID, topics, newData)  
                Console.WriteLine("ret for 'ConnectData()' = {0}", ret.ToString())  
                '       // Loop and wait for RTD to notify (via callback) that  
                '       // data is available.  
                '       int count = 0;  
                Dim count As Integer = 0  
                'Do  
                '       {  
                Do  
                    '           count++;  
                    count += 1  
                    '           // Check that the RTD server is still alive.  
                    '           Object status;  
                    '           param = null;  
                    '           method = rtd.GetMethod("Heartbeat");  
                    '           status = method.Invoke(rtdServer, param);  
                    '           Console.WriteLine("status for 'Heartbeat()' = {0}",  
                    '               status.ToString());  
                    Dim status As Object = rtdServer.Heartbeat()  
                    Console.WriteLine("status for 'Heartbeat()' = {0}", status.ToString())  
                    '           // Get data from the RTD server.  
                    '           int topicCount = 0;  
                    '           param = new Object[1];  
                    '           param[0] = topicCount;  
                    '           method = rtd.GetMethod("RefreshData");  
                    '           Object[,] retval = new Object[2, 1];  
                    '           retval = (Object[,])method.Invoke(rtdServer, param);  
                    '           Console.WriteLine("retval for 'RefreshData()' = {0}",  
                    '               retval[1,0].ToString());  
                    Dim topicCount As Integer = 0  
                    Dim retVal(,) As Object  
                    retVal = CType(rtdServer.RefreshData(topicCount), Object(,))  
                    Console.WriteLine("retval for 'RefreshData()' = {0}", retVal(1, 0).ToString())  
                    '           // Wait for 2 seconds before getting  
                    '           // more data from the RTD server. This  
                    '           // it the default update period for Excel.  
                    '           // This client can requested data at a  
                    '           // much higher frequency if wanted.  
                    '           Thread.Sleep(2000);  
                    Thread.Sleep(2000)  
                Loop While count < 5  
                '       } while (count < 5); // Loop 5 times for test.  
                '       // Disconnect from data topic.  
                '       param = new Object[1];  
                '       param[0] = topicID;  
                '       method = rtd.GetMethod("DisconnectData");  
                '       method.Invoke(rtdServer, param);  
                rtdServer.DisconnectData(topicID)  
                '       // Shutdown the RTD server.  
                '       param = null;  
                '       method = rtd.GetMethod("ServerTerminate");  
                '       method.Invoke(rtdServer, param);  
                rtdServer.ServerTerminate()  
                '   }  
                '   catch (Exception e)  
                '   {  
            Catch ex As Exception  
                '       Console.WriteLine("Error: {0} ", e.Message);  
                Console.WriteLine("Error: {0} ", ex.Message)  
                '   }  
            End Try  
        End Sub  
    End Class
 

josh1

Well-Known Member
#14
1.RTD Work Sheet Function

Let have a look at the syntax for the Excel RTD worksheet function first:

=RTD(ProgID, Server, String1, String2, … String28)
The ProgID parameter is a required String value representing the programmatic ID (ProgID) of t
3.Create An RTD Server

RTD Sever is a component object model automation server implement the interface Excel.IRtdServer.

3.1 Introduction to IRtdServer

IRtdServer has six interface methods as followings:

1.)ConnectData(TopicID, Strings, GetNewValues)

This method is called whenever Excel requests new topics from the RTD server. The TopicID parameter is a required Long value that represents a unique, arbitrary value automatically assigned by Excel (for example, "34") that identifies the topic.

The Strings parameter is a required array of one or more Variant values that the user enters into the RTD function to uniquely identify the topic. This Variant array should always be an array of String values.

The GetNewValues parameter is a required Boolean value; True if new values are to be retrieved. Leave the GetNewValues parameter alone if you want Excel to use the previous value that it had saved with the Excel spreadsheet.

2.)DisconnectData(TopicID)
This method is called whenever Excel no longer requires a specific topic.

The TopicID parameter is a required Long value that represents the arbitrary, unique value automatically assigned by Excel in the ConnectData method that identifies the topic.

3.)Heartbeat
If the RTD server is no longer able to process RefreshData method calls, the Heartbeat method enables Excel to pop up a dialog box that says "The real-time data server ‘XYZ’ is not responding. Would you like Microsoft Excel to attempt to restart the server?"

This method returns a Long value; a value of 1 indicates that the real-time data server connection still exists, and a value of zero (0) or a negative value indicates that the real-time data server connection no longer exists.

4.)RefreshData(TopicCount)
After a call from the IRTDUpdateEvent callback object’s UpdateNotify method, this method is called by Excel to pull new values from the real-time data server (also known as a topic refresh).

This method returns a two-dimensional array of Variant values. The first dimension represents a list of topic IDs; these topic IDs map to the TopicID parameter in the ConnectData method above. This is how Excel associates topics with data.

The second dimension represents the values associated with the topic IDs.

The TopicCount parameter is a required Long value that the RTD server provides; it represents the number of elements returned in the array of Variant values.

5.)ServerStart(CallbackObject)
This method is called when Excel requests the first topic from the real-time data server.

This method returns a Long value; a value of 1 indicates a successful request, and a value of zero (0) or a negative value indicates a failed request.

This method call is immediately followed by a call to the ConnectData method.

The CallbackObject parameter is a required IRTDUpdateEvent callback object that the RTD server uses to notify Excel when it should gather updates from the RTD server through the IRTDUpdateEvent callback object’s UpdateNotify method.

6.)ServerTerminate
This method is called when Excel no longer requires topics from the RTD server (for example, the user quits Excel).

Create an RTD server to deliver the real-time data to the RTD function. The real-time data server contains the topics that the RTD function relies upon. See the resources section for more information.

3.2 Introduction to IRTDUpdateEvent

As you see at 5.) of 2.1, RTD Server use the IRTDUpdateEvent callback objects to interactive with Excel.The members of the IRTDUpdateEvent callback object are described as followings.

1.)HeartbeatInterval property
This property returns or sets the time interval between RTD server updates.

This property returns a Long value that represents the number of milliseconds between RTD server updates; this property cannot be set below the default of 15,000 milliseconds, because of the standard 15-second RTD server timeout.

2.)Disconnect method
This method tells Excel that the real-time data source will be disconnecting from the RTD server. Excel can use this method to take some type of action before it loses its RTD connection.

3.)UpdateNotify method
This method is called by the RTD server when it has a new value for one or more topics.

3.3 Create An Component

The Component can be written in VB , C++, C# language , it’s up to you. you can query the data source check out the changes topics and then get the changed data only , alternative , you can get data periodically with the help of a timer , or a query loop.

Normally , Excel RTD function have only a return value , which mean you can not update a range at once , another problem is RTD Sever is in-process of excel , so its speed is crucial. There are two structure to speed up.

1.) RTD Return values for a range ,convert them into cells with VBA code.

Structure_VBA

2.) RTD Server cache values for topics.

structure_cache



Further more , you can get much more speed enforcement with multiple thread and asynchronous method , welcome to visit Multiple-Thread In COM.
 

josh1

Well-Known Member
#15
This is how Excel works. You will have to suitably modify for your own client.

How Do I construct the Return Array For the RefreshData Method?

The return array for the RefreshData method must be a two-dimensional Variant array where the first dimension goes from zero (the TopicID parameter) to one, and the second dimension goes from zero to TopicCount minus one. Here is an example:

Dim ra()

TopicCount = UpdatedTopics.Count
ReDim ra(0 To 1, 0 To TopicCount - 1)
i = 0
For Each Item in UpdatedTopics
ra(0, i) = Item.TopicID
ra(1, i) = Item.Value
i = i + 1
Next Item

How Do You Manage a Group of Topics From the RTD Server?

Sometimes topics need to be treated as a group. For example, the Last Price, Size of Last Sale, and Time of Last Sale for a stock should all correspond to one another. You don't want Last Price and Size of Last Sale to be from different trades.

Here are three key things to ensure that a group of topics stays in sync:

Always set the GetNewValues parameter to True in the ConnectData method. Otherwise, saved values may get mixed with new values.
Only return a value from the ConnectData method if the value corresponds to the values that have already been returned for the topics in that group.
In the RefreshData method, all topics in the group should be updated at once. Unless a value hasn't changed, each topic in the group should be included in the RefreshData method's return array.
 
#16
Josh,
it is the client and getting errors on highlighted line. this is where we have to pass our parameters and get values


Code:
 IDispatch dispatch = new IDispatchImpl(CLSID.createFromProgID("NOW.ScripRTD"),
                            ClsCtx.LOCAL_SERVER);

                    IPersistImpl p = new IPersistImpl(dispatch);
                    CLSID clsid = new CLSID();
                    p.getClassID(clsid);
                    System.out.println("ClassID = " + clsid);

                    Variant result = new Variant();
                    Automation automation = new Automation(dispatch);
[COLOR="Red"]result = automation.invoke(GET_PROG_ID_METHOD_NAME);[/COLOR]
                    System.out.println("PROG_ID = " + result.getValue())
 

josh1

Well-Known Member
#17
Josh,
it is the client and getting errors on highlighted line. this is where we have to pass our parameters and get values


Code:
 IDispatch dispatch = new IDispatchImpl(CLSID.createFromProgID("NOW.ScripRTD"),
                            ClsCtx.LOCAL_SERVER);

                    IPersistImpl p = new IPersistImpl(dispatch);
                    CLSID clsid = new CLSID();
                    p.getClassID(clsid);
                    System.out.println("ClassID = " + clsid);

                    Variant result = new Variant();
                    Automation automation = new Automation(dispatch);
[COLOR="Red"]result = automation.invoke(GET_PROG_ID_METHOD_NAME);[/COLOR]
                    System.out.println("PROG_ID = " + result.getValue())
I think you do not need this - CLSID.createFromProgID("NOW.ScripRTD"),
I have already given you the Server Name which is CLSID.
I have also given the six methods/interfaces of the server.

Anyway this should have given you the CLSID - System.out.println("ClassID = " + clsid);

I think it is to be used along with braces. Just Create Instance of the server, 'ServerStart(CallbackObject)' andfollow up with 'ConnectData' method. Return value of ConnectData will be two dimentional array.
Say - ConnectData(TopicID, Strings, GetNewValues)
e.g. - ConnectData(1, nse_fo|NIFTY14JAN6200CE, True)
e.g. - ConnectData(2, nse_fo|NIFTY14JAN6100CE, True)
and see what you get.
 

KelvinHand

Well-Known Member
#18
Hi Josh,

Since you had good knowledge on COM Interface.
As you know to interface amibroker to external WScript, VB and Java
related are easily by CreateObject().

But in C#, seen like no easy CreateObject() link

How can/to let C# interface to amibroker ?
 

josh1

Well-Known Member
#19

Similar threads