Dde is used to achieve dynamic data exchange between processes. It is suitable for the situation where the data exchange frequency between two programs is large, that is, the exchange of real-time data. The ddeml class library has implemented the packaging of dde and is easy to operate. I am using the ddeml library.
My task is to use dde to send real-time data to an excel file. First, create a dde Server (for example, serv1) and register several topics (for example, topic1 ). Open excel, select a cell, and enter = serv1 | topic1! Aaaaa, the dde server will respond, read a timely data according to the topic and item, and return to the current cell. In this way, I can create an excel sheet with the data I want to keep up-to-date.
The steps are as follows:
1. Import all the required ddeml api functions and constants
2. initialize the dde object
3. Register a service and apply for several topics.
4. Compile the message processing program in the callback function
5. Write the value of the corresponding message
To achieve this, several technical problems need to be overcome.
1. How to Use the delegate callback function
2. Format of data uploaded back to excel
3. Message Processing Process
First, let's talk about question 3,
When you enter a formula in excel, ddeserver returns a response, which records the parts of the formula.
Then, find the real-time information and return a value, which is the value to be added to the current cell.
After obtaining the value, call the DdePostAdvise function of ddeml, which will trigger the XTYP_ADVREQ message of the callback function.
Call the DdeCreateDataHandle function in the message to put the new value into the corresponding cell.
Note: The call of DdePostAdvise does not necessarily trigger the XTYP_ADVREQ message immediately. This function uses PostMessage internally,
Instead of sendMessage, the system will collect some XTYP_ADVREQ messages for processing. In this case, you need to differentiate the cell value. It is not difficult to solve this problem. You can solve it yourself.
About question 1,
During dde initialization, you need to call a callback function that accepts the delegate.
Public Declare Function DdeInitialize Lib "user32" Alias "DdeInitializeA" (ByRef pidInst As Integer, ByVal pfnCallback As DDECallBackDelegate, ByVal afCmd As Integer, ByVal ulRes As Integer) As Short
As long as you try it again, you will feel that its call is actually very simple, and there is a lot of information in this regard. The key is that the form of the callback function declaration must be consistent with that of the definition; otherwise, the callback function cannot be called.
Private _ DDECallBack As DDEML. DDECallBackDelegate = Nothing
_ DDECallBack = New DDEML. DDECallBackDelegate (AddressOf DDECallBack)
Dim ddeinst As Integer
Ddeinst = DDEML. DdeInitialize (g_lInstID, _ DDECallBack, DDEML. APPCLASS_STANDARD, 0)
After the dde initialization function is called, the current process will add the dde message to the message loop. If these messages are received, the callback function DDECallBack will be called for processing.
2nd questions
If you want the cell to accept your value, it is unacceptable to pass a string at will. You need to pass it in xltable format. Of course, if you are using the dde client, the format does not matter. (This is what I got through a lot of experiments. If you have a good solution, please share it with me .)
10 00 04 00 01 00 03 00
TdtTable, cb = 4, rows = 1, columns = 3
02 00 10 00
TdtString, cb = 16
04 45 61 73 74
Cch = 4, East (tdtString continued)
04 57 65 73 74
Cch = 4, West (tdtString continued)
05 4e 6f 72 74 68
Cch = 5, North (tdtString continued)
My final problem is that tdtTable cannot fill in multiple cells. The above format is in Microsoft documents. Actually, it doesn't work. I don't know why. Write the data in the first td.