Не удалось установить dde соединение с сервером excel либо не запущен

Обновлено: 05.07.2024

В данной статье я хочу поделиться решением, которое наверняка будет многим полезно. Началось с того, что передо мной была поставлена задача организовать чтение данных из книги MS Excel, причем данные из ячеек нужно было считывать только в том случае, если они изменились. При этом были выдвинуты жесткие требования к скорости и оперативности обработки информации в изменившихся ячейках.

2. Описание протокола DDE.

Начнем с кратного описания протокола DDE. Материал статьи охватывает только ту часть API протокола, которая необходима для организации "горячего" канала DDE.

По протоколу DDE, сервер в первую очередь должен зарегистрировать себя в библиотеке DDEML. После этого он регистрирует предоставляемые сервисы.

Клиентское приложение также сначала регистрирует себя в библиотеке DDEML. После этого клиентское приложение создает канал связи с сервером.

Протокол DDE поддерживает три вида обмена данными между клиентом и сервером:

  • По явному запросу
  • "Теплый канал"
  • "Горячий канал"

В первом случае клиент явным образом посылает серверу запрос, указывая нужный элемент данных. Сервер, получив подобный запрос, предоставляет клиенту эти данные.

В случае организации "теплого канала" сервер, при изменении данных, отправляет клиенту извещение. Клиент, получив это извещение, может послать запрос серверу на получение этих данных, после чего сервер предоставляет данные клиенту.

В случае "горячего канала" сервер будет отправлять клиенту данные, не ожидая явного запроса при их изменении.

На практике, как правило, используется либо передача данных по явному запросу, либо "горячий канал", причем второй очень удобен при организации быстрого обмена данными между приложениями в режиме реального времени. Именно "горячий" канал и будет рассматриваться в этой статье.

В библиотеке DDEML данные адресуются трехступенчатой схемой: сервис (service), раздел (topiс) и элемент данных (data item). Для сервера DDE приложения MS Excel, эта схема выглядит следующим образом:

Для установления связи, приложение должно сначала зарегистрировать себя в библиотеке DDEML и получить свой программный идентификатор. Этот идентификатор необходимо хранить в течение всей работы, так как для каждого приложения, которое регистрируется в библиотеке DDEML, создается своя копия необходимых структур данных.

Параметры, которые передаются функции при вызове:

  • pidInst - ссылка на переменную типа <двойное слово>, в которую функция запишет программный идентификатор, присваиваемый приложения библиотекой DDEML. Перед вызовом функции программа должна обнулить значение этой переменной.
  • pfnCallback - указатель на функцию обратного вызова.
  • afCmd - набор битовых флагов инициализации, а также устанавливающий некоторые специфические условия работы с библиотекой.
  • ulRes - зарезервировано и должно быть равно нулю.

В случае успешной регистрации, функция DdeInitialize возвращает нулевое значение. Если при инициализации произошла ошибка, то функция вернет код ошибки.

Если приложение больше не собирается работать с библиотекой DDEML, то оно должно вызвать функцию DdeUninitialize, передав ей в качестве параметра программный идентификатор, полученный при регистрации:

После успешной инициализации, клиентское приложения должно создать канал связи с сервером. Для каждого сервиса и раздела создается свой канал связи. После успешного создания канала, ему присваивается идентификатор, который указывается в дальнейших транзакциях, как клиентом, так и сервером.

Адресация происходит посредством строк, однако в транзакциях используются их идентификаторы. Эти идентификаторы присваиваются каждой строке библиотекой DDEML и хранятся в специальной системной таблице идентификации строк. Для создания идентификатора строки, необходимо воспользоваться функцией DdeCreateStringHandle:

Функция получает следующие параметры:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • psz - адрес текстовой строки, завершенной двоичным нулем. Длина строки не должна превышать 255 байт.
  • iCodePage - кодовая страница, определяющая тип строки, получаемой на вход. При указании константы CP_WINANSI данная строка рассматривается как строка ANSI. Если указать константу CP_WINUNICODE, то строка рассматривается как состоящая из символов Unicode.

Функция возвращает идентификатор, который библиотека DDEML присвоила данной строке.

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки.

Функция возвращает значение true, если операция прошла успешно, и false - если при выполнении функции произошли ошибки.

Для того, чтобы получить строку по ее идентификатору, необходимо воспользоваться функцией DdeQueryString:

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки, которую нужно получить.
  • psz - указательна буфер, в который будет записана строка
  • cchMax - максимальная длина строки в символах. Вид символа определяется следующим по порядку параметром и может быть ANSI (1 байт) или Unicode (2 байта)
  • iCodePage - определяет тип символов строки. Возможные значения CP_WINANSI - для символов стандарта ANSI (1 байт) и CP_WINUNICODE - для символов стандарта Unicode (2 байта).

Функция возвращает количество скопированных символов. При этом если фактическая длина строки (в символах) меньше указанной в параметре cchMax, то функция скопирует cchMax символов и вернет это значение. Если cchMax больше фактической длины строки, то функция скопирует всю строку и вернет количество скопированных символов. Если передать через параметр psz нулевое значение, то функция проигнорирует значение параметра cchMax и вернет фактическую длину строки в символах. Размер буфера в байтах для строки зависит от размера символа и определяется параметром iCodePage.

Для получения данных из глобальной области памяти по их идентификатору нужно воспользоваться функцией DdeGetData:

Функция должна получить на вход следующие параметры:

  • hData - идентификатор порции данных в глобальной области памяти;
  • pDst - указатель на буфер, куда будут скопированы данные из глобальной области.
  • cbMax - размер буфера в байтах. Если фактический размер данных больше размера области в буфере, которая выделяется под эти данные(см. ниже параметр cbOff), то будут скопированы только первые (cbMax - cbOff) байт. Иначе функция скопирует все данные в буфер.
  • cbOff - смещение в буфере относительно начала, с которого функция поместит в буфер данные из глобальной области.

Функция возвратит количество фактически скопированных байт данных. Если вместо ссылки на буфер через параметр pDst передать нулевое значение, то функция вернет фактический размер порции данных в глобальной области памяти, при этом значение параметров cbMax и cbOff будут проигнорированы.

Канал связи DDE создается с помощью функции DdeConnect:

В качестве параметров функция должна получить следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hszService - идентификатор строки названия сервиса, который необходимо предварительно получить вызовом функции DdeCreateStringHandle
  • hszTopic - идентификатор строки названия раздела, который также заранее запрашивается у библиотеки DDEML вызовом функции DdeCreateStringHandle;
  • pCC - указатель на специальную структуру типа CONVCONTEXT, в которой указывается информация о национальном языке и кодовой странице. В большинстве случаев (в нашем тоже) достаточно указать нулевое значение, что означает использование кодовой страницы ANSI.

Функция возвращает идентификатор созданного канала связи. В случае ошибки функция вернет нулевое значение. Полученный идентификатор канала необходимо хранить в течение всего сеанса связи.

Когда приложение завершает работу с каналом, оно должно закрыть его, вызвав функцию

DdeDisconnect:

В качестве параметра функция получает идентификатор канала, который нужно закрыть. Функция возвращает true, если канал успешно закрыт и false в случая возникновения ошибок при закрытии канала.

Функция обратного вызова имеет следующий заголовок:

  • wType - Код транзакции. Коды транзакций предопределены протоколом DDE. Значения и названия соответствующих им констант можно посмотреть в технической документации. Забегая вперед, отмечу, что в нашем примере будут использоваться транзакции XTYP_ADVSTART для запуска потока данных по каналу, XTYP_ADVSTOP - для остановки потока данных, XTYP_ADVDATA - транзакция с уведомлением наличии данных от сервера.
  • wFmt - формат данных (в нашем случае данные представляют собой текстовую строку, поэтому этому параметру при вызове будет присвоено значение CF_TEXT, равное единице).
  • hConv - идентификатор канала. Этот идентификатор получен при создании канала.
  • hsz1 - идентификатор строки названия раздела.
  • hsz2 - идентификатор строки названия элемента данных.
  • hData - идентификатор глобальной области в памяти, где находятся данные от сервера. Данные необходимо получить с помощью функции DdeGetData.

В свою очередь функция запуска транзакции DdeClientTransaction имеет следующий заголовок:

  • pData - ссылка на данные, передаваемые транзакцией.
  • cbData - размер передаваемых данных
  • hConv - идентификатор канала связи, полученный заранее функцией DdeConnect
  • hszItem - идентификатор элемента данных, в нашем случае - ячейки. Идентификатор должен быть получен заранее, с помощью функции DdeCreateStringHandle.
  • uFmt - формат данных. Для случая с Excel указывается константа CF_TEXT(1)
  • uType - код транзакции. Определяется комбинацией битовых флагов. В случае организации горячего канала выполняется транзакция XTYP_ADVSTART - для начала цикла получения данных из ячейки (подписки на ячейку) и XTYP_ADVSTOP - для прекращения цикла получения данных из ячейки (отписки от ячейки).
  • dwTimeout - тайм-аут для синхронных транзакций - максимальное время выполнения синхронной транзакции. Если в качестве параметра передать 0, то будет запущена асинхронная транзакция. При запуске синхронной транзакции, приложение ждет ее завершения. При этом максимальное время выполнения транзакции определяется значением параметра. При запуске асинхронной транзакции приложение не ждет завершения транзакции и продолжает свою работу. По завершению транзакции клиент получит транзакцию XTYP_XACT_COMPLETE.
  • pdwResult - ссылка на двойное слово, в которое будет записан код завершения транзакции. Изначально эта переменная должна быть приравнена к нулю. (По рекомендации Microsoft, не рекомендуется использовать этот параметр, так как, возможно, в дальнейшем он поддерживаться не будет).

Возвращает нулевое значение, если транзакция была выполнена с ошибкой, или ненулевую величину, смысл которой зависит от транзакции, (В нашем случае будет возвращена единица) при нормальном выполнении.

Для функции обратного вызова необходимо создать делегат, который имеет соответствующую сигнатуру, и указать его в качестве параметра в функции DdeInitialize:

Забегая вперед, отмечу, что для отображения необходимых функций и констант библиотеки DDEML в компоненте ExcelDDEHotConnection служит класс DDEML.

Ниже приведен список остальных функций для работы с DDE:

Делегат функции обратного вызова:

Отображение функции DdeInitialize:

Отображение функции DdeUninitialize:

Отображение функции DdeCreateStringHandle:

Отображение функции DdeFreeStringHandle:

Отображение функции DdeConnect:

Отображение функции DdeDisconnect:

Отображение функции DdeClientTransaction:

Отображение функции DdeGetData:

Отображение функции DdeQueryString:

4. Организация горячего канала Excel - приложение DDE.

В этой главе вкратце описано, как осуществить корректное подключение и отключение от ячеек Excel. Например, необходимо получить доступ к ячейке, расположенной во втором столбце и первой строке на странице с названием <Лист1> рабочей книги <Книга1>. Для начала необходимо зарегистрироваться в библиотеке DDEML и получить программный идентификатор idInst:

После этого создаем канал связи с нужным разделом. В нашем случае, как было упомянуто выше, название сервиса: <EXCEL>, а название раздела <[Книга1.xls]Лист1>. Необходимо помнить, что расширение файла необходимо указывать, если эта книга открыта из файла. Если осуществляется подключение к созданной, но еще не сохраненной книге, то расширение не указывается.

После создания канала информируем Excel о том, чтобы приложение получало содержимое нужной ячейки, как только оно изменится (<горячий канал>). Для этого посылаем Excel транзакцию XTYP_ADVSTART:

Отключение производим в обратном порядке, сначала информируем сервер о том, что данные из ячейки нам больше не нужны, посылая Excel транзакцию XTYP_ADVSTOP:

После завершения транзакции, закрываем канал:

И завершаем работу с библиотекой DDEML:

5. Компонент ExcelDDEConnection.

Ниже приведены основные методы и свойства класса ExcelDDEHotConnection:

НазваниеОписание
ExcelDDEHotConnection()Конструктор. Осуществляет регистрацию в библиотеке DDEML
TopicDescriptorCollection TopicsСвойство. Ссылка на коллекцию разделов. Раздел адресуется названием книги и названием страницы
void Dispose()Завершить работу объекта. Закрывает все каналы и производит отключение от библиотеки DDEML
event AdviseDelegate DataСобытие. Происходит при изменении содержимого любой из подписанных ячеек. Событие вызывается для каждой изменившейся ячейки.

Коллекция разделов TopicDescriptorCollection.

Коллекция разделов представляет собой набор объектов, описывающий разделы. При добавлении раздела в коллекцию, происходит автоматическое создание канала, а при удалении - закрытие канала. Коллекция не допускает дублирование одинаковых разделов. Раздел добавляется в коллекцию только в том случае, если удалось создать канал для этого раздела.

Дескриптор раздела TopicDescriptor.

Экземпляр класса описывает раздел данных. Каждый раздел содержит в себе коллекцию элементов данных типа ItemDescriptor, описывающих ячейки. При добавлении ячейки происходит отправка Excel транзакции на подписку на эту ячейку, при удалении - транзакция на завершение работы с ячейкой.

В данной статье я хочу поделиться решением, которое наверняка будет многим полезно. Началось с того, что передо мной была поставлена задача организовать чтение данных из книги MS Excel, причем данные из ячеек нужно было считывать только в том случае, если они изменились. При этом были выдвинуты жесткие требования к скорости и оперативности обработки информации в изменившихся ячейках.

2. Описание протокола DDE.

Начнем с кратного описания протокола DDE. Материал статьи охватывает только ту часть API протокола, которая необходима для организации "горячего" канала DDE.

По протоколу DDE, сервер в первую очередь должен зарегистрировать себя в библиотеке DDEML. После этого он регистрирует предоставляемые сервисы.

Клиентское приложение также сначала регистрирует себя в библиотеке DDEML. После этого клиентское приложение создает канал связи с сервером.

Протокол DDE поддерживает три вида обмена данными между клиентом и сервером:

  • По явному запросу
  • "Теплый канал"
  • "Горячий канал"

В первом случае клиент явным образом посылает серверу запрос, указывая нужный элемент данных. Сервер, получив подобный запрос, предоставляет клиенту эти данные.

В случае организации "теплого канала" сервер, при изменении данных, отправляет клиенту извещение. Клиент, получив это извещение, может послать запрос серверу на получение этих данных, после чего сервер предоставляет данные клиенту.

В случае "горячего канала" сервер будет отправлять клиенту данные, не ожидая явного запроса при их изменении.

На практике, как правило, используется либо передача данных по явному запросу, либо "горячий канал", причем второй очень удобен при организации быстрого обмена данными между приложениями в режиме реального времени. Именно "горячий" канал и будет рассматриваться в этой статье.

В библиотеке DDEML данные адресуются трехступенчатой схемой: сервис (service), раздел (topiс) и элемент данных (data item). Для сервера DDE приложения MS Excel, эта схема выглядит следующим образом:

Для установления связи, приложение должно сначала зарегистрировать себя в библиотеке DDEML и получить свой программный идентификатор. Этот идентификатор необходимо хранить в течение всей работы, так как для каждого приложения, которое регистрируется в библиотеке DDEML, создается своя копия необходимых структур данных.

Параметры, которые передаются функции при вызове:

  • pidInst - ссылка на переменную типа <двойное слово>, в которую функция запишет программный идентификатор, присваиваемый приложения библиотекой DDEML. Перед вызовом функции программа должна обнулить значение этой переменной.
  • pfnCallback - указатель на функцию обратного вызова.
  • afCmd - набор битовых флагов инициализации, а также устанавливающий некоторые специфические условия работы с библиотекой.
  • ulRes - зарезервировано и должно быть равно нулю.

В случае успешной регистрации, функция DdeInitialize возвращает нулевое значение. Если при инициализации произошла ошибка, то функция вернет код ошибки.

Если приложение больше не собирается работать с библиотекой DDEML, то оно должно вызвать функцию DdeUninitialize, передав ей в качестве параметра программный идентификатор, полученный при регистрации:

После успешной инициализации, клиентское приложения должно создать канал связи с сервером. Для каждого сервиса и раздела создается свой канал связи. После успешного создания канала, ему присваивается идентификатор, который указывается в дальнейших транзакциях, как клиентом, так и сервером.

Адресация происходит посредством строк, однако в транзакциях используются их идентификаторы. Эти идентификаторы присваиваются каждой строке библиотекой DDEML и хранятся в специальной системной таблице идентификации строк. Для создания идентификатора строки, необходимо воспользоваться функцией DdeCreateStringHandle:

Функция получает следующие параметры:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • psz - адрес текстовой строки, завершенной двоичным нулем. Длина строки не должна превышать 255 байт.
  • iCodePage - кодовая страница, определяющая тип строки, получаемой на вход. При указании константы CP_WINANSI данная строка рассматривается как строка ANSI. Если указать константу CP_WINUNICODE, то строка рассматривается как состоящая из символов Unicode.

Функция возвращает идентификатор, который библиотека DDEML присвоила данной строке.

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки.

Функция возвращает значение true, если операция прошла успешно, и false - если при выполнении функции произошли ошибки.

Для того, чтобы получить строку по ее идентификатору, необходимо воспользоваться функцией DdeQueryString:

В качестве параметров функция получает следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hsz - идентификатор строки, которую нужно получить.
  • psz - указательна буфер, в который будет записана строка
  • cchMax - максимальная длина строки в символах. Вид символа определяется следующим по порядку параметром и может быть ANSI (1 байт) или Unicode (2 байта)
  • iCodePage - определяет тип символов строки. Возможные значения CP_WINANSI - для символов стандарта ANSI (1 байт) и CP_WINUNICODE - для символов стандарта Unicode (2 байта).

Функция возвращает количество скопированных символов. При этом если фактическая длина строки (в символах) меньше указанной в параметре cchMax, то функция скопирует cchMax символов и вернет это значение. Если cchMax больше фактической длины строки, то функция скопирует всю строку и вернет количество скопированных символов. Если передать через параметр psz нулевое значение, то функция проигнорирует значение параметра cchMax и вернет фактическую длину строки в символах. Размер буфера в байтах для строки зависит от размера символа и определяется параметром iCodePage.

Для получения данных из глобальной области памяти по их идентификатору нужно воспользоваться функцией DdeGetData:

Функция должна получить на вход следующие параметры:

  • hData - идентификатор порции данных в глобальной области памяти;
  • pDst - указатель на буфер, куда будут скопированы данные из глобальной области.
  • cbMax - размер буфера в байтах. Если фактический размер данных больше размера области в буфере, которая выделяется под эти данные(см. ниже параметр cbOff), то будут скопированы только первые (cbMax - cbOff) байт. Иначе функция скопирует все данные в буфер.
  • cbOff - смещение в буфере относительно начала, с которого функция поместит в буфер данные из глобальной области.

Функция возвратит количество фактически скопированных байт данных. Если вместо ссылки на буфер через параметр pDst передать нулевое значение, то функция вернет фактический размер порции данных в глобальной области памяти, при этом значение параметров cbMax и cbOff будут проигнорированы.

Канал связи DDE создается с помощью функции DdeConnect:

В качестве параметров функция должна получить следующее:

  • idInst - программный идентификатор приложения, полученный при регистрации в библиотеке DDEML;
  • hszService - идентификатор строки названия сервиса, который необходимо предварительно получить вызовом функции DdeCreateStringHandle
  • hszTopic - идентификатор строки названия раздела, который также заранее запрашивается у библиотеки DDEML вызовом функции DdeCreateStringHandle;
  • pCC - указатель на специальную структуру типа CONVCONTEXT, в которой указывается информация о национальном языке и кодовой странице. В большинстве случаев (в нашем тоже) достаточно указать нулевое значение, что означает использование кодовой страницы ANSI.

Функция возвращает идентификатор созданного канала связи. В случае ошибки функция вернет нулевое значение. Полученный идентификатор канала необходимо хранить в течение всего сеанса связи.

Когда приложение завершает работу с каналом, оно должно закрыть его, вызвав функцию

DdeDisconnect:

В качестве параметра функция получает идентификатор канала, который нужно закрыть. Функция возвращает true, если канал успешно закрыт и false в случая возникновения ошибок при закрытии канала.

Функция обратного вызова имеет следующий заголовок:

  • wType - Код транзакции. Коды транзакций предопределены протоколом DDE. Значения и названия соответствующих им констант можно посмотреть в технической документации. Забегая вперед, отмечу, что в нашем примере будут использоваться транзакции XTYP_ADVSTART для запуска потока данных по каналу, XTYP_ADVSTOP - для остановки потока данных, XTYP_ADVDATA - транзакция с уведомлением наличии данных от сервера.
  • wFmt - формат данных (в нашем случае данные представляют собой текстовую строку, поэтому этому параметру при вызове будет присвоено значение CF_TEXT, равное единице).
  • hConv - идентификатор канала. Этот идентификатор получен при создании канала.
  • hsz1 - идентификатор строки названия раздела.
  • hsz2 - идентификатор строки названия элемента данных.
  • hData - идентификатор глобальной области в памяти, где находятся данные от сервера. Данные необходимо получить с помощью функции DdeGetData.

В свою очередь функция запуска транзакции DdeClientTransaction имеет следующий заголовок:

  • pData - ссылка на данные, передаваемые транзакцией.
  • cbData - размер передаваемых данных
  • hConv - идентификатор канала связи, полученный заранее функцией DdeConnect
  • hszItem - идентификатор элемента данных, в нашем случае - ячейки. Идентификатор должен быть получен заранее, с помощью функции DdeCreateStringHandle.
  • uFmt - формат данных. Для случая с Excel указывается константа CF_TEXT(1)
  • uType - код транзакции. Определяется комбинацией битовых флагов. В случае организации горячего канала выполняется транзакция XTYP_ADVSTART - для начала цикла получения данных из ячейки (подписки на ячейку) и XTYP_ADVSTOP - для прекращения цикла получения данных из ячейки (отписки от ячейки).
  • dwTimeout - тайм-аут для синхронных транзакций - максимальное время выполнения синхронной транзакции. Если в качестве параметра передать 0, то будет запущена асинхронная транзакция. При запуске синхронной транзакции, приложение ждет ее завершения. При этом максимальное время выполнения транзакции определяется значением параметра. При запуске асинхронной транзакции приложение не ждет завершения транзакции и продолжает свою работу. По завершению транзакции клиент получит транзакцию XTYP_XACT_COMPLETE.
  • pdwResult - ссылка на двойное слово, в которое будет записан код завершения транзакции. Изначально эта переменная должна быть приравнена к нулю. (По рекомендации Microsoft, не рекомендуется использовать этот параметр, так как, возможно, в дальнейшем он поддерживаться не будет).

Возвращает нулевое значение, если транзакция была выполнена с ошибкой, или ненулевую величину, смысл которой зависит от транзакции, (В нашем случае будет возвращена единица) при нормальном выполнении.

Для функции обратного вызова необходимо создать делегат, который имеет соответствующую сигнатуру, и указать его в качестве параметра в функции DdeInitialize:

Забегая вперед, отмечу, что для отображения необходимых функций и констант библиотеки DDEML в компоненте ExcelDDEHotConnection служит класс DDEML.

Ниже приведен список остальных функций для работы с DDE:

Делегат функции обратного вызова:

Отображение функции DdeInitialize:

Отображение функции DdeUninitialize:

Отображение функции DdeCreateStringHandle:

Отображение функции DdeFreeStringHandle:

Отображение функции DdeConnect:

Отображение функции DdeDisconnect:

Отображение функции DdeClientTransaction:

Отображение функции DdeGetData:

Отображение функции DdeQueryString:

4. Организация горячего канала Excel - приложение DDE.

В этой главе вкратце описано, как осуществить корректное подключение и отключение от ячеек Excel. Например, необходимо получить доступ к ячейке, расположенной во втором столбце и первой строке на странице с названием <Лист1> рабочей книги <Книга1>. Для начала необходимо зарегистрироваться в библиотеке DDEML и получить программный идентификатор idInst:

После этого создаем канал связи с нужным разделом. В нашем случае, как было упомянуто выше, название сервиса: <EXCEL>, а название раздела <[Книга1.xls]Лист1>. Необходимо помнить, что расширение файла необходимо указывать, если эта книга открыта из файла. Если осуществляется подключение к созданной, но еще не сохраненной книге, то расширение не указывается.

После создания канала информируем Excel о том, чтобы приложение получало содержимое нужной ячейки, как только оно изменится (<горячий канал>). Для этого посылаем Excel транзакцию XTYP_ADVSTART:

Отключение производим в обратном порядке, сначала информируем сервер о том, что данные из ячейки нам больше не нужны, посылая Excel транзакцию XTYP_ADVSTOP:

После завершения транзакции, закрываем канал:

И завершаем работу с библиотекой DDEML:

5. Компонент ExcelDDEConnection.

Ниже приведены основные методы и свойства класса ExcelDDEHotConnection:

НазваниеОписание
ExcelDDEHotConnection()Конструктор. Осуществляет регистрацию в библиотеке DDEML
TopicDescriptorCollection TopicsСвойство. Ссылка на коллекцию разделов. Раздел адресуется названием книги и названием страницы
void Dispose()Завершить работу объекта. Закрывает все каналы и производит отключение от библиотеки DDEML
event AdviseDelegate DataСобытие. Происходит при изменении содержимого любой из подписанных ячеек. Событие вызывается для каждой изменившейся ячейки.

Коллекция разделов TopicDescriptorCollection.

Коллекция разделов представляет собой набор объектов, описывающий разделы. При добавлении раздела в коллекцию, происходит автоматическое создание канала, а при удалении - закрытие канала. Коллекция не допускает дублирование одинаковых разделов. Раздел добавляется в коллекцию только в том случае, если удалось создать канал для этого раздела.

Дескриптор раздела TopicDescriptor.

Экземпляр класса описывает раздел данных. Каждый раздел содержит в себе коллекцию элементов данных типа ItemDescriptor, описывающих ячейки. При добавлении ячейки происходит отправка Excel транзакции на подписку на эту ячейку, при удалении - транзакция на завершение работы с ячейкой.

При работе с табличным процессором Эксель редко возникают проблемы. Этот продукт Microsoft довольно надежный и проверенный временем. Но иногда при открытии документов может возникать ошибка при направлении команды приложению Excel 2010 и в других версиях. Как поступать в подобной ситуации, расскажу в этой статье.

Почему так происходит? Причины - самые разнообразные. Не хотелось бы тратить Ваше время на такие детали. Лучше сразу перейти к рассмотрению решений.

Отключаем функцию игнорирования DDE

  • Необходимо открыть приложение Excel 2007 (не конкретный документ, а саму программу) и перейти к пункту главного меню «Файл». Потом выбираем раздел «Параметров»:

Параметры Эксель

  • Далее кликаем по вкладке «Дополнительно» и справа видим перечень опций. Нужно снять галочку с функции «Игнорировать DDE запросы…»:

Отключение игнорирования запросов DDE

  • Обязательно нажимаем на ОК, чтобы сохранить внесенные изменения.

Попробуйте теперь открыть проблемный файл, который приводил к появлению ошибки при направлении команды приложению Excel.

Используем открытие по умолчанию

  • Переходим в «Панель управления». Способов сделать это существует немало. В Windows 10 просто нажимаем Win + R и выбираем нужный пункт. Для «семерки» можно найти ПУ среди элементов меню «Пуск»:

Панель управления в результатах поиска Вин10

Запуск панели управления в виндовс 7

  • Если указан режим просмотра «Крупные значки» или «Категории» (справа вверху), то меняем на «Мелкие значки». Затем кликаем по «программам по умолчанию»:

Панель управления - Программы по умолчанию

  • Среди нескольких вариантов выбираем «Сопоставление типов…»:

Указание программ для типов файлов

  • Немножко ждем, пока не прогрузится список. Потом находим расширения «xls» и «xlsx», выбираем для их открытия программу Excel 2003, 2007 или любую другую версию, которая установлена на компьютере:

Выбор приложения для открытия документов

Ели среди предложенных программ нет Экселя, то придется нажать на ссылку «Найти другое приложение…» и указать путь к нему. Файл запуска excel.exe расположен в папке:

Устанавливаем обновления Office

Ошибка при направлении команды приложению способна появится после выхода очередного апдейта офисного пакета. Если причина в этом, то разработчики оперативно выпустят исправление. Поэтому, нужно периодически заходить в центр обновления Виндовс и проверять наличие обнов.

Кнопка проверки обновлений Win 10

Но, как показывает практика, истоки проблемы редко связаны с этим.

Чистая установка MS Office

Вдруг указанные выше методы окажутся неэффективными, тогда предстоит полностью удалить программу.

  • Запустите с официального сайта разработчиков диагностическую утилиту .
  • Нажмите Win + R и ведите команду:
  • Откроется папка AppData, внутри которой следует удалить все содержимое из каталогов:

Следы Office в каталоге Appdata

  • Теперь нужно перезагрузить ноутбук и произвести установку необходимых офисных приложений с нуля.

Такой вариант наверняка исправит ошибку, хотя отнимет больше времени. Будем надеяться, что Вам удалось устранить проблему другими способами.

Предлагаю посмотреть видео, чтобы лучше усвоить перечисленные в статье методы:

Обязательно оставляйте комментарии, если возникли вопросы ко мне по данной теме.

Из терминала QUIK можно выводить данные во внешние программы. Это удобно при использовании сторонних аналитических программ, роботов для торговли, либо для ведения журнала сделок. В этой статье расскажем, как вывести данные через DDE-сервер в MS Excel на примере окна котировок.

Перед началом вывода необходимо создать файл на компьютере. Если этого не сделать, терминал создаст произвольный файл на Рабочем столе и выгрузит информацию в него. После создания файла в терминале QUIK нажатием правой кнопкой мыши в стакане вызывается меню, в котором нужно выбрать пункт «Вывод через DDE-сервер».


В окне настроек вывода указывается DDE-сервер (если нажать «По умолчанию», будет указан Еxcel). В поле «Рабочая книга» нужно выбрать тот файл, который был создан. В данном случае это «Котировки.xlsx». После проставления отметки «Запускать приложение DDE-сервера автоматически» активизируются кнопки «Начать вывод» и «Вывести сейчас». Последняя предназначена для разового вывода данных. Если не указывается номер листа, ряда и колонки, то все значения принимаются за единицу и вывод начинается с первого листа. Название листа задаётся по названию выводимой таблицы. Отметка «С заголовками столбцов» означает, что будут выгружены названия столбцов из таблицы. Если есть пустые значения в таблице, то вместо них в файле автоматически будет указано «0». Если нужны пустые поля, как в самой таблице, то можно поставить отметку «Выводить пустые ячейки вместо нулей».


После нажатия кнопки «Начать вывод» откроется созданный файл, в который будет поступать информация из таблицы с постоянным обновлением данных. В случае с выводом котировок можно окрасить столбцы файла Еxcel в разные цвета для удобства работы с данными.


Таким образом можно вывести таблицы «Текущие торги», «Сделки» «Заявки», «Клиентский портфель», «Обезличенные сделки» и др. Например, для ведения журнала сделок удобно выводить данные сразу в созданный для этих целей файл. Записывать сделки отдельно не придётся. Важно помнить, что, если в ячейки файла осуществляется вывод данных, редактировать их, применять к ним фильтры и записывать в них другие данные нельзя, это приведёт к остановке процедуры вывода.

QUIK 7: настройка торгового терминала для торговли на бирже QUIK 7: покупка облигаций федерального займа через терминал QUIK 7: фьючерс на Индекс ММВБ в торговом терминале QUIK 7: как настроить стакан котировок для быстрого ввода/снятия заявок? QUIK 7: как использовать ODBC для экспорта информации? Что такое индикатор ожидаемой волатильности и как его использовать Что важно знать начинающим трейдерам для эффективной работы

Москва, ул. Летниковская, д. 2, стр. 4

Будьте в курсе новых публикаций!
Подпишитесь на дайджест «Открытого журнала» и получайте подборку публикаций за неделю.

Размещённые в настоящем разделе сайта публикации носят исключительно ознакомительный характер, представленная в них информация не является гарантией и/или обещанием эффективности деятельности (доходности вложений) в будущем. Информация в статьях выражает лишь мнение автора (коллектива авторов) по тому или иному вопросу и не может рассматриваться как прямое руководство к действию или как официальная позиция/рекомендация АО «Открытие Брокер». АО «Открытие Брокер» не несёт ответственности за использование информации, содержащейся в публикациях, а также за возможные убытки от любых сделок с активами, совершённых на основании данных, содержащихся в публикациях. 18+

АО «Открытие Брокер» (бренд «Открытие Инвестиции»), лицензия профессионального участника рынка ценных бумаг на осуществление брокерской деятельности № 045-06097-100000, выдана ФКЦБ России 28.06.2002 (без ограничения срока действия).

ООО УК «ОТКРЫТИЕ». Лицензия № 21-000-1-00048 от 11 апреля 2001 г. на осуществление деятельности по управлению инвестиционными фондами, паевыми инвестиционными фондами и негосударственными пенсионными фондами, выданная ФКЦБ России, без ограничения срока действия. Лицензия профессионального участника рынка ценных бумаг №045-07524-001000 от 23 марта 2004 г. на осуществление деятельности по управлению ценными бумагами, выданная ФКЦБ России, без ограничения срока действия.

Читайте также: