Организация горячего канала Excel – приложение DDE.
В этой главе вкратце описано, как осуществить корректное подключение и отключение от ячеек Excel. Например, необходимо получить доступ к ячейке, расположенной во втором столбце и первой строке на странице с названием «Лист1» рабочей книги «Книга1». Для начала необходимо зарегистрироваться в библиотеке DDEML и получить программный идентификатор idInst:
// Создаем делегат-переходник для функции обратного вызова
_DDECallBack = new DDECallBackDelegate(DDECallBack);
// Регистрация в библиотеке DDEML
DDEML.DdeInitialize(ref idInst, _DDECallBack, 0, 0);
После этого создаем канал связи с нужным разделом. В нашем случае, как было упомянуто выше, название сервиса: «EXCEL», а название раздела «[Книга1.xls]Лист1». Необходимо помнить, что расширение файла необходимо указывать, если эта книга открыта из файла. Если осуществляется подключение к созданной, но еще не сохраненной книге, то расширение не указывается.
// Формируем название раздела
string szTopic = “[Книга1.xls]Лист1”;
// Получение идентификатора сервиса
IntPtr hszService = DDEML.DdeCreateStringHandle(_idInst, "EXCEL", DDEML.CP_WINANSI);
// Получаем идентификатор раздела
IntPtr hszTopic = DDEML.DdeCreateStringHandle(_idInst, szTopic, DDEML.CP_WINANSI);
// Подключаемся к разделу
IntPtr hConv = DDEML.DdeConnect(_idInst, hszService, hszTopic , (IntPtr) null);
// Проверяем результат
if(hConv!=IntPtr.Zero)
{
...
}
// Освобождаем идентификаторы строк
DDEML.DdeFreeStringHandle(_idInst, hszService);
DDEML.DdeFreeStringHandle(_idInst, hszTopic);
После создания канала информируем Excel о том, чтобы приложение получало содержимое нужной ячейки, как только оно изменится («горячий канал»). Для этого посылаем Excel транзакцию XTYP_ADVSTART:
// Формируем название ячейки
string szItem = “R1C2”;
// Создаем идентификатор строки
IntPtr hszItem = DDEML.DdeCreateStringHandle(_idInst, szItem, DDEML.CP_WINANSI);
// Подписываемся на тему
uint pwdResult = 0;
IntPtr hData = DDEML.DdeClientTransaction((IntPtr)null, 0, hConv, hszItem, DDEML.CF_TEXT, DDEML.XTYP_ADVSTART, 1000,ref pwdResult);
if(hData!=IntPtr.Zero)
{
...
}
// Освобождаем идентификатор строки
DDEML.DdeFreeStringHandle(_idInst, hszItem);
Отключение производим в обратном порядке, сначала информируем сервер о том, что данные из ячейки нам больше не нужны, посылая Excel транзакцию XTYP_ADVSTOP:
// Формируем название ячейки
string szItem = “R1C2”;
// Создаем идентификатор строки
IntPtr hszItem = DDEML.DdeCreateStringHandle(_idInst, szItem, DDEML.CP_WINANSI);
// Подписываемся на тему
uint pwdResult = 0;
IntPtr hData = DDEML.DdeClientTransaction((IntPtr)null, 0, hConv, hszItem, DDEML.CF_TEXT, DDEML.XTYP_ADVSTOP, 1000, ref pwdResult);
if(hData!=IntPtr.Zero)
{
...
}
// Освобождаем идентификатор строки
DDEML.DdeFreeStringHandle(_idInst, hszItem);
После завершения транзакции, закрываем канал:
//Закрываем канал
DDEML.DdeDisconnect(hConv);
И завершаем работу с библиотекой DDEML:
// Отключаемся от DDEML
DDEML.DdeUninitialize(idInst);
Необходимо отметить, что для всех трех режимов создается одинаковый канал. При этом для одних ячеек мы можем указывать «горячий» режим, для других – «теплый», а с третьими работать по явному запросу. Для того, чтобы включить «теплый» канал, необходимо отправить Excel транзакцию, код которой состоит из побитной комбинации кода транзакции XTYP_ADVSTART и флага XTYPF_NODATA.