Как сделать dll для excel?
Содержание
- 1 Что такое EXCEL.DLL?
- 2 Что из себя представляют файлы DLL?
- 3 Почему у меня наблюдаются ошибки в файлах типа DLL?
- 4 В каких случаях появляются ошибки в файлах типа DLL?
- 4.1 Шаг 1: Зарегистрировать EXCEL.DLL вручную при помощи сервера регистрации Microsoft
- 4.2 Шаг 2: Исправить ошибочные записи реестра для EXCEL.DLL
- 4.3 Шаг 3: Удалить или восстановить файл EXCEL.DLL из Корзины Windows
- 4.4 Шаг 4: Проведите полное сканирование вашего компьютера на вредоносное ПО
- 4.5 Шаг 5: Обновите драйверы устройств на вашем компьютере
- 4.6 Шаг 6: Используйте Восстановление системы Windows, чтобы «Отменить» последние изменения в системе
- 4.7 Шаг 7: Удалите и установите заново программу MSDN Disc 2537.3, связанную с EXCEL.DLL
- 4.8 Шаг 8: Запустите проверку системных файлов Windows («sfc /scannow»)
- 4.9 Шаг 9: Установите все доступные обновления Windows
- 4.10 Шаг 10: Произведите чистую установку Windows
Установить необязательные продукты — WinThruster (Solvusoft) | Лицензия | Политика защиты личных сведений | Условия | Удаление
Обзор EXCEL.DLL
Что такое EXCEL.DLL?
EXCEL.DLL представляет собой разновидность файла DLL, связанного с MSDN Disc 2537.3, который разработан Microsoft для ОС Windows. Последняя известная версия EXCEL.DLL: 1.0.0.0, разработана для Windows. Данный файл DLL имеет рейтинг популярности 1 звезд и рейтинг безопасности «UNKNOWN».
Что из себя представляют файлы DLL?
Файлы DLL («динамически подключаемая библиотека»), такие как EXCEL.DLL – это небольшие программы, схожие с файлами EXE («исполняемыми»), которые позволяют множеству программ использовать одни и те же функции (например, печать).
Например, когда вы запускаете Windows и редактируете документ в Microsoft Word. Необходимо загружать файл DLL, контролирующий печать, только если его функции востребованы — например, когда вы решили свой документ. Когда вы выбираете «Печать», Microsoft Word вызывает файл принтера DLL, и он загружается в память (RAM). Если вы хотите документ в другой программе, например в Adobe Acrobat, будет использоваться тот же самый файл принтера DLL.
Почему у меня наблюдаются ошибки в файлах типа DLL?
Файлы DLL, будучи общими, существуют за пределами самого приложения. Давая множество преимуществ разработчикам программного обеспечения, такое разделение также открывает возможность для появления проблем.
Проще говоря, если Windows не может корректно загрузить файл EXCEL.DLL, вы получите сообщение об ошибке. Для получения дополнительной информации см. «Причины ошибок EXCEL.DLL» ниже.
В каких случаях появляются ошибки в файлах типа DLL?
Ошибки DLL, например, связанные с EXCEL.DLL, чаще всего появляются во время запуска компьютера, запуска программы или при попытке использования специфических функций в вашей программе (например, печать).
Распространенные сообщения об ошибках в EXCEL.DLL
Наиболее распространенные ошибки EXCEL.DLL, которые могут возникнуть на компьютере под управлением Windows, перечислены ниже:
- «EXCEL.DLL не найден.»
- «Файл EXCEL.DLL отсутствует.»
- «EXCEL.DLL нарушение прав доступа.»
- «Файл EXCEL.DLL не удалось зарегистрировать.»
- «Файл C:WindowsSystem32\EXCEL.DLL не найден.»
- «Не удалось запустить MSDN Disc 2537.3. Отсутствует необходимый компонент: EXCEL.DLL. Пожалуйста, установите MSDN Disc 2537.3 заново.»
- «Не удалось запустить данное приложение, так как не найден файл EXCEL.DLL. Повторная установка приложения может решить эту проблему.»
Такие сообщения об ошибках DLL могут появляться в процессе установки программы, когда запущена программа, связанная с EXCEL.DLL (например, MSDN Disc 2537.3), при запуске или завершении работы Windows, или даже при установке операционной системы Windows. Отслеживание момента появления ошибки EXCEL.DLL является важной информацией при устранении проблемы.
Большинство ошибок EXCEL.DLL связано с отсутствием или повреждениями файлов EXCEL.DLL. Тот факт, что EXCEL.DLL – внешний файл, открывает возможность для всяческих нежелательных последствий.
Непредвиденные завершения работы вашего компьютера или заражение вирусом может повредить EXCEL.DLL, что приведет к ошибкам DLL. Когда файл EXCEL.DLL повреждается, он не может быть нормально загружен и выведет сообщение об ошибке.
В других случаях ошибки файла EXCEL.DLL могут быть связаны с проблемами в реестре Windows. Нерабочие ссылки DLL файлов могут помешать зарегистрировать файл DLL должным образом и вызвать ошибку EXCEL.DLL. Эти нерабочие ключи реестра могут появиться в результате отсутствия файла DLL, перемещения файла DLL или ввиду наличия остаточной ссылки DLL файла в реестре Windows после неудачной установки или удаления программы.
Более конкретно, данные ошибки EXCEL.DLL могут быть вызваны следующими причинами:
Предупреждение: Мы не рекомендуем скачивать EXCEL.DLL с сайтов типа «DLL». Такие сайты распространяют файлы DLL, которые не одобрены официальным разработчиком файла EXCEL.DLL и часто могут поставляться в комплекте с инфицированными вирусом или другими вредоносными файлами. Если вам требуется копия файла EXCEL.DLL, настоятельно рекомендуется получить ее непосредственно у Microsoft.
Ниже описана последовательность действий по устранению ошибок, призванная решить проблемы EXCEL.DLL. Данная последовательность приведена в порядке от простого к сложному и от менее затратного по времени к более затратному, поэтому мы настоятельно рекомендуем следовать данной инструкции по порядку, чтобы избежать ненужных затрат времени и усилий.
Пожалуйста, учтите: Нажмите на изображение , чтобы развернуть инструкции по устранению проблем по каждому из шагов ниже. Вы также можете использовать изображение , чтобы скрывать инструкции по мере их выполнения.
Шаг 1: Зарегистрировать EXCEL.DLL вручную при помощи сервера регистрации Microsoft
При установке программного обеспечения, которое использует зависимости EXCEL.DLL, это программное обеспечение должно автоматически зарегистрировать этот файл. В некоторых случаях файл DLL может быть не зарегистрирован соответствующим образом, что в результате приведет к ошибке «EXCEL.DLL не зарегистрирован». К счастью, вы всегда можете воспользоваться встроенной утилитой под названием «Сервер регистрации Microsoft» (regsvr32.exe), чтобы заново зарегистрировать файл EXCEL.DLL.
Как заново зарегистрировать EXCEL.DLL из привилегированной командной строки (Windows XP, Vista, 7, 8 и 10):
- Нажмите на кнопку Начать.
- Введите «command» в строке поиска… ПОКА НЕ НАЖИМАЙТЕ ENTER!
- Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
- Будет выведено диалоговое окно для доступа.
- Нажмите Да.
- Введите следующую команду: regsvr32 /u EXCEL.DLL.
- Нажмите ENTER. Для файла будет ОТМЕНЕНА РЕГИСТРАЦИЯ.
- Введите следующую команду: regsvr32 /i EXCEL.DLL.
- Нажмите ENTER. Файл будет ЗАРЕГИСТРИРОВАН ЗАНОВО.
- Закройте окно командной строки.
- Перезапустить программу, связанную с ошибкой EXCEL.DLL.
Шаг 2: Исправить ошибочные записи реестра для EXCEL.DLL
Иногда ошибки EXCEL.DLL и другие системные ошибки DLL могут быть связаны с проблемами в реестре Windows. Несколько программ может использовать файл EXCEL.DLL, но когда эти программы удалены или изменены, иногда остаются «осиротевшие» (ошибочные) записи реестра DLL.
В принципе, это означает, что в то время как фактическая путь к файлу мог быть изменен, его неправильное бывшее расположение до сих пор записано в реестре Windows. Когда Windows пытается найти файл по этой некорректной ссылке (на расположение файлов на вашем компьютере), может возникнуть ошибка EXCEL.DLL. Кроме того, заражение вредоносным ПО могло повредить записи реестра, связанные с MSDN Disc 2537.3. Таким образом, эти поврежденные записи реестра DLL необходимо исправить, чтобы устранить проблему в корне.
Редактирование реестра Windows вручную с целью удаления содержащих ошибки ключей EXCEL.DLL не рекомендуется, если вы не являетесь специалистом по обслуживанию ПК. Ошибки, допущенные при редактировании реестра, могут привести к неработоспособности вашего ПК и нанести непоправимый ущерб вашей операционной системе. На самом деле, даже одна запятая, поставленная не в том месте, может воспрепятствовать загрузке компьютера!
В связи с подобным риском мы настоятельно рекомендуем использовать надежные инструменты очистки реестра, такие как WinThruster (разработанный Microsoft Gold Certified Partner), чтобы просканировать и исправить любые проблемы, связанные с EXCEL.DLL. Используя очистку реестра, вы сможете автоматизировать процесс поиска поврежденных записей реестра, ссылок на отсутствующие файлы (например, вызывающих ошибку EXCEL.DLL) и нерабочих ссылок внутри реестра. Перед каждым сканированием автоматически создается резервная копия, позволяющая отменить любые изменения одним кликом и защищающая вас от возможного повреждения компьютера. Самое приятное, что устранение ошибок реестра может резко повысить скорость и производительность системы.
Предупреждение: Если вы не являетесь опытным пользователем ПК, мы НЕ рекомендуем редактирование реестра Windows вручную. Некорректное использование Редактора реестра может привести к серьезным проблемам и потребовать переустановки Windows. Мы не гарантируем, что неполадки, являющиеся результатом неправильного использования Редактора реестра, могут быть устранены. Вы пользуетесь Редактором реестра на свой страх и риск.
Перед тем, как вручную восстанавливать реестр Windows, необходимо создать резервную копию, экспортировав часть реестра, связанную с EXCEL.DLL (например, MSDN Disc 2537.3):
- Нажмите на кнопку Начать.
- Введите «command» в строке поиска… ПОКА НЕ НАЖИМАЙТЕ ENTER!
- Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
- Будет выведено диалоговое окно для доступа.
- Нажмите Да.
- Черный ящик открывается мигающим курсором.
- Введите «regedit» и нажмите ENTER.
- В Редакторе реестра выберите ключ, связанный с EXCEL.DLL (например, MSDN Disc 2537.3), для которого требуется создать резервную копию.
- В меню Файл выберите Экспорт.
- В списке Сохранить в выберите папку, в которую вы хотите сохранить резервную копию ключа MSDN Disc 2537.3.
- В поле Имя файла введите название файла резервной копии, например «MSDN Disc 2537.3 резервная копия».
- Убедитесь, что в поле Диапазон экспорта выбрано значение Выбранная ветвь.
- Нажмите Сохранить.
- Файл будет сохранен с расширением .reg.
- Теперь у вас есть резервная копия записи реестра, связанной с EXCEL.DLL.
Следующие шаги при ручном редактировании реестра не будут описаны в данной статье, так как с большой вероятностью могут привести к повреждению вашей системы. Если вы хотите получить больше информации о редактировании реестра вручную, пожалуйста, ознакомьтесь со ссылками ниже.
Мы не несем никакой ответственности за результаты действий, совершенных по инструкции, приведенной ниже — вы выполняете эти задачи на свой страх и риск.
Windows XP
http://www.theeldergeek.com/windows_xp_registry.htm
Windows 7
http://www.theeldergeek.com/windows_7/registry_edits_for_win7.htm
Windows Vista
http://support.microsoft.com/kb/2688326 — LetMeFixItMyselfAlways
Шаг 3: Удалить или восстановить файл EXCEL.DLL из Корзины Windows
- Просто дважды щелкните по значку Корзина.
- В верхнем правом углу найдите EXCEL.DLL.
- Если файл EXCEL.DLL присутствует в результатах поиска, выберите его и переместите в следующую папку:
- Windows 95/98/Me = C:WindowsSystem32
- Windows NT/2000 = C:WindowsSystem32
- Windows XP, Vista, 7, 8, 10 = C:WindowsSystem32
- 64-bit Windows = C:WindowsSystem32
- После перемещения файла EXCEL.DLL перезагрузите компьютер.
Tip: If you are positive that you deleted the EXCEL.DLL file AND emptied the Recycle Bin, then you will need to use a file recovery program to restore the EXCEL.DLL file. Click here to download a highly recommended file recovery program.
Шаг 4: Проведите полное сканирование вашего компьютера на вредоносное ПО
Есть вероятность, что ошибка EXCEL.DLL может быть связана с заражением вашего компьютера вредоносным ПО. Эти вредоносные злоумышленники могут повредить или даже удалить файлы, связанные с DLL. Кроме того, существует возможность, что ошибка EXCEL.DLL связана с компонентом самой вредоносной программы.
Совет: Если у вас еще не установлены средства для защиты от вредоносного ПО, мы настоятельно рекомендуем использовать Emsisoft Anti-Malware (скачать). В отличие от других защитных программ, данная программа предлагает гарантию удаления вредоносного ПО.
Шаг 5: Обновите драйверы устройств на вашем компьютере
Ошибки EXCEL.DLL могут быть связаны с повреждением или устареванием драйверов устройств. Драйверы с легкостью могут работать сегодня и перестать работать завтра по целому ряду причин. Хорошая новость состоит в том, что чаще всего вы можете обновить драйверы устройства, чтобы устранить проблему с DLL.
В связи с временными затратами и общей сложностью обновления драйверов мы настоятельно рекомендуем использовать утилиту обновления драйверов, например DriverDoc (разработана Microsoft Gold Partner), для автоматизации этого процесса.
Пожалуйста, учтите: Ваш файл EXCEL.DLL может и не быть связан с проблемами в драйверах устройств, но всегда полезно убедиться, что на вашем компьютере установлены новейшие версии драйверов оборудования, чтобы максимизировать производительность вашего ПК.
Шаг 6: Используйте Восстановление системы Windows, чтобы «Отменить» последние изменения в системе
Восстановление системы Windows позволяет вашему компьютеру «отправиться в прошлое», чтобы исправить проблемы EXCEL.DLL. Восстановление системы может вернуть системные файлы и программы на вашем компьютере к тому времени, когда все работало нормально. Это потенциально может помочь вам избежать головной боли от устранения ошибок, связанных с DLL.
Пожалуйста, учтите: использование восстановления системы не повлияет на ваши документы, изображения или другие данные.
Чтобы использовать Восстановление системы (Windows XP, Vista, 7, 8 и 10):
- Нажмите на кнопку Начать.
- В строке поиска введите «Восстановление системы» и нажмите ENTER.
- В окне результатов нажмите Восстановление системы.
- Введите пароль администратора (при появлении запроса).
- Следуйте инструкциям Мастера для выбора точки восстановления.
- Восстановить ваш компьютер.
Шаг 7: Удалите и установите заново программу MSDN Disc 2537.3, связанную с EXCEL.DLL
Инструкции для Windows 7 и Windows Vista:
- Откройте «Программы и компоненты», нажав на кнопку Пуск.
- Нажмите Панель управления в меню справа.
- Нажмите Программы.
- Нажмите Программы и компоненты.
- Найдите MSDN Disc 2537.3 в столбце Имя.
- Нажмите на запись MSDN Disc 2537.3.
- Нажмите на кнопку Удалить в верхней ленте меню.
- Следуйте инструкциям на экране для завершения удаления MSDN Disc 2537.3.
Инструкции для Windows XP:
- Откройте «Программы и компоненты», нажав на кнопку Пуск.
- Нажмите Панель управления.
- Нажмите Установка и удаление программ.
- Найдите MSDN Disc 2537.3 в списке Установленные программы.
- Нажмите на запись MSDN Disc 2537.3.
- Нажмите на кнопку Удалить справа.
- Следуйте инструкциям на экране для завершения удаления MSDN Disc 2537.3.
Инструкции для Windows 8:
- Установите указатель мыши в левой нижней части экрана для показа изображения меню Пуск.
- Щелкните правой кнопкой мыши для вызова Контекстного меню Пуск.
- Нажмите Программы и компоненты.
- Найдите MSDN Disc 2537.3 в столбце Имя.
- Нажмите на запись MSDN Disc 2537.3.
- Нажмите Удалить/изменить в верхней ленте меню.
- Следуйте инструкциям на экране для завершения удаления MSDN Disc 2537.3.
После того, как вы успешно удалили программу, связанную с EXCEL.DLL (например, MSDN Disc 2537.3), заново установите данную программу, следуя инструкции Microsoft.
Совет: Если вы абсолютно уверены, что ошибка DLL связана с определенной программой Microsoft, удаление и повторная установка программы, связанной с EXCEL.DLL с большой вероятностью решит вашу проблему.
Шаг 8: Запустите проверку системных файлов Windows («sfc /scannow»)
Проверка системных файлов — важная утилита, включенная в состав Windows. Она позволяет сканировать файлы на наличие повреждений и восстанавливать системные файлы Windows, такие как EXCEL.DLL. Если утилита проверки системных файлов обнаружила проблему в EXCEL.DLL или другом важном системном файле, она предпримет попытку заменить проблемные файлы автоматически, используя Кэш DLL (%WinDir%System32Dllcache). Если файл EXCEL.DLL отсутствует в Кэше DLL, или Кэш DLL поврежден, утилита предложит вставить установочный диск Windows для восстановления оригинальных файлов.
Чтобы запустить проверку системных файлов (Windows XP, Vista, 7, 8 и 10):
- Нажмите на кнопку Начать.
- Введите «command» в строке поиска… ПОКА НЕ НАЖИМАЙТЕ ENTER!
- Удерживая клавиши CTRL-Shift на клавиатуре, нажмите ENTER.
- Будет выведено диалоговое окно для доступа.
- Нажмите Да.
- Черный ящик открывается мигающим курсором.
- Введите «sfc /scannow» и нажмите ENTER.
- Проверка системных файлов начнет сканирование на наличие проблем EXCEL.DLL и других системных файлов (проявите терпение — проверка может занять длительное время).
- Следуйте командам на экране.
Шаг 9: Установите все доступные обновления Windows
Microsoft постоянно обновляет и улучшает системные файлы Windows, связанные с EXCEL.DLL. Иногда для решения проблемы DLL нужно просто напросто обновить Windows при помощи последнего пакета обновлений или другого патча, которые Microsoft выпускает на постоянной основе.
Чтобы проверить наличие обновлений Windows (Windows XP, Vista, 7, 8 и 10):
- Нажмите на кнопку Начать.
- Введите «update» в строке поиска и нажмите ENTER.
- Будет открыто диалоговое окно Обновление Windows.
- Если имеются доступные обновления, нажмите на кнопку Установить обновления.
Шаг 10: Произведите чистую установку Windows
Предупреждение: Мы должны подчеркнуть, что переустановка Windows займет очень много времени и является слишком сложной задачей, чтобы решить проблемы EXCEL.DLL. Во избежание потери данных вы должны быть уверены, что вы создали резервные копии всех важных документов, изображений, программ установки программного обеспечения и других персональных данных перед началом процесса. Если вы сейчас е создаете резервные копии данных, вам стоит немедленно заняться этим (скачать рекомендованное решение для резервного копирования), чтобы защитить себя от безвозвратной потери данных.
Пожалуйста, учтите: Если проблема EXCEL.DLL не устранена после чистой установки Windows, это означает, что проблема DLL ОБЯЗАТЕЛЬНО связана с аппаратным обеспечением. В таком случае, вам, вероятно, придется заменить соответствующее оборудование, вызывающее ошибку EXCEL.DLL.
Сообщения об ошибках EXCEL.DLL могут появляться в любых из нижеперечисленных операционных систем Microsoft Windows:
Обращайтесь к нам в любое время в социальных сетях для получения дополнительной помощи:
Об авторе: Джей Гитер (Jay Geater) является президентом и генеральным директором корпорации Solvusoft — глобальной компании, занимающейся программным обеспечением и уделяющей основное внимание новаторским сервисным программам. Он всю жизнь страстно увлекался компьютерами и любит все, связанное с компьютерами, программным обеспечением и новыми технологиями.
Вы загружаете пробное программное обеспечение. Подписка на один год стоимостью $39,95 необходима для разблокировки всех функций приложения. Подписка обновляется автоматически по завершению (Узнать больше). Нажав на кнопку «Начать загрузку» и установив «Софт»», я подтверждаю, что прочитал(а) и согласен(на) с Пользовательским соглашением и Политикой конфиденциальности Solvusoft.
Problem/Question/Abstract:
How do I make delphi functions available to Excel users?
I have seen many articles telling how to control Excel from within Delphi. However, it is also appealing to give Excel users (which tend to be far less programming oriented guys) the power of tools built with Dephi, its flexibility and velocity.
Answer:
The idea is very simple and is based upon the variable types that are common to Excel’s VBA and to Delphi. Those include 32 bit integer, double precision floating point and, mainly, Excel ranges.
I found that Excel sometimes interprets incorrectly simple types when passed by reference and thus I limmited their usage to value parameters.
On the other hand, ranges can only be passed by reference and can be read from but not written to. This means that, within Delphi, you must use the reserved word CONST instead of VAR.
First, I defined within a simple unit a set of functions that convert simple Variant types to simple types and viceversa. Those are IntToVar,Double and VarTodouble (the real unit also includes a StrToVar function but not a VarToStr since this one is already included in the System unit), and are used within the procedures that do the real work (RangeToMatrix, RangeToVector,VectorToMatrix and VectortoRange).
All these functions (along with some others that you might find useful) are put together in a unit called «_Variants» whose source code is copied here (with some slight modifications).
In the real unit you will find that there fucntions that provide conversion between Excel ranges and SDL delphi component suite which I have found to be quite useful (refer to www.lohninger.com).
I shall restrict the examples, however to standard types.
Lets take first a simple function:
This function, called gamma_alfa, takes as input the mean and the variance of a population and returns the alfa parameter of a gamma distribution.
In Excel’s VBA it is declared as
Declare Function gamma_alfa Lib «c:archivosdel_filesf_auxiliares_delphi» Alias «gamma_alfa_XL» (ByVal media As Double, ByVal varianza As Double) As Double
note the lib statement that refers to name that the DLL actually has.
note also the ByVal modifiers used for declaring the variables as well as the «as double» statements.
These mean that both the input and the output will be simple types of type double.
In Delphi, the function is declared as
function gamma_alfa(media, varianza : double) : Double;stdcall;
Note the stdcall at the end of the declaration. This is to ensure that Delphi will use the Microsoft calling convention
Also note the inconsistency between the delphi function’s name and the «alias» statement in VBA.
This is set in the export clause of the DLL:
Для правильной работы проверьте путь до M2DLL.DLL в Declare VBA Excel!
Так получилось, что пришлось мне срочно заняться одной задачей на Excel. Проблема была в том, что нужно было выбирать информацию из большого текстового файла по определенным критериям и вставлять её в Excel. Сразу пришла мысль использовать VBA и при помощи него написать функцию, которая будет выдавать мне строку с информацией.
А почему бы не написать DLL, подумал я, ведь раньше я уже пытался писать DLL для VBA на C++. DLL это быстро, это интересно и позволяет отвлечься от каждодневной рутины. Но, так как я давно уже всё делаю на D, то и DLL решил писать на D. В качестве путеводителя по дебрям VBA я использовал замечательную книгу Брюса Мак-Кинни «Крепкий орешек 4 visual basic» 1996 года выпуска. Книга исключительно интересная и занимательная и ни сколько не потеряла своей актуальности.
Однако вернемся в D. Обращаю внимание, что все все примеры, которые представлены ниже, проверены только на Windows 32, Excel 2003 и dmd для Windows. Первым делом пишу строку сборки DLL, где исходный файл m2dll.d, а сама DLL будет называться m2dll.dll. Так же в сборке участвует файл dll.d входящий в поставку dmd и asc1251.d из QtE5.
dmd –ofm2dll.dll m2dll dll asc1251 -L/IMPLIB -release -shared
Небольшое введение. Существует несколько типов вызовов функций отличаются тем как передаются параметры их порядок в стеке и типами возвращаемых значений. Они все стандартизированы и в компиляторах имеются специальные дериктивы указывающие, как должен компилятор оформить функцию. Это следующие типы: pascal, stdcall, winapi и т.д. Более подробно читайте в интернете.
Итак, что у нас. У нас есть D у которого упращенно тип вызова «extern (D)». Есть Excel VBA в котором упрощенно тип вызова «extern (Windows)». DLL – это набор функций (в терминах C и C++) которые могут быть загружены во время работы приложения. Таким образом, у нас фактически будет набор функций, который мы будем вызывать из VBA. В самом VBA надо описать имя и параметры для вызываемой внешней функции.
Declare Function getAdrStringVBA Lib «r:m2dll.dll» Alias «_getAdr@4» (ByVal buf As String) As Long
Что здесь основное. Это Lib “r:m2dll.dll” – имя DLL и где она расположена, Function getAdrStringVBA – это как данная функция будет называться в VBA, Alias “_getAdr@4” – это как эта функция называется в DLL ну и напоследок список параметров и возвращаемых значений. Для D эта же функция будет выглядеть так:
export extern (Windows) int getAdr(char* buffer) { … }
Компилятору сказано «export» — быдет видна в DLL «extern (Windows)» это тип вызова, winApi и дальше параметры. Все понятно, кроме имени внутри DLL “_getAdr@4”. Это имя экспортированной функции. Есть много литературы описывающей как задавать эти имена (например в файле DEF и т.д.) но мне лень это все описывать и намного проще в TotalCommander посмотреть список экспортированных функций по кнопке F3 на полученной DLL.
Теперь о параметрах. Дело в том, что типы параметров в VBA и D (32 разр) совпадают лишь частично!
Int D == Long VBA
Long D == нет соответствия в 32 разр VBA
Таким образом, где нам нужно в D иметь int – значит в VBA это будет long. Когда VBA в функции имеет описание о передачи строки, значит передается адрес этой строки, вернее структуры содержащей в том числе и строку.
Мне было интересно проверить расположение данных в структурах VBA, типа как их обрабатывать в D. Для этого я пользовался интерпретатором VBA (окно Immediate в VBA Excel).
Первая задача – это научится смотреть дамп памяти структуры из VBA например строки. Как получить адрес строки в VBA, если самом VBA нет понятия указатель, вернее оно присутствует неявно. Первая наша функция в DLL будет возвращать адрес строки VBA. Их описание приведено выше. В VBA возвращается число (long) которое и есть адрес. Вторая наша функция dumpForVBA(), получая long из VBA, формирует строку С формата и записывает её в буфер, который сформирован VBA внутри функции dumpPointer():
Dim buf As String
buf = String(1000, 0)
Для испытаний, на уровне модуля VBA я определил две переменных:
Public str As String
Public adrStr As Long
Кстати, обращаю внимание, что все переменные в VBA должны быть объявлены явно, если этого не делать, то по умолчанию переменные получают тип Variant с которым D не умеет работать. Я опускаю передачу целых чисел в DLL и их возврат. Тут все просто, все передается и возвращается по значению. Это и понятно, работаем через аппаратный стек. Намного интереснее строки. Для исследования, я использую процедуру t1() в которой записан код VBA. Просмотр результата в окне Immediate. Если поставить текстовый курсор внутри процедуры t1() на любом операторе и нажать F5 – то будет выполнена эта процедура. Это избавляет от лишней писанины.
Sub t1() '1 - исследуем строку VBA str = "ABC" adrStr = getAdrStringVBA(str) 'Взяли адрес 'Распечатали содержимое по адресу Debug.Print adrStr, " --> " & dumpPointer(adrStr, 0) End Sub
Результат выполнения:
82468836 —> 65 — 66 — 67 — 0 — 0 — 0 — 0 — 0 — 108 — 0 — 0 — 0 – Действительно видна наша строка. Если верить «Крепкому орешку», то длина строки расположена в 32 разрядном слове левее нашей строки. Проверим. Для этого вычтем 4 (сместимся на 4 ячейки) и посмотрим дамп.
82468832 —> 3 — 0 — 0 — 0 — 65 — 66 — 67 — 0 — 0 — 0 — 0 — 0 – Отлично видно, что длина строки равна 3.
После нескольких попыток, выяснилось, что даже в рамках одной процедуры VBA перемещает строки. Вроде по этому адресу должна быть строка, а там её уже нет! Чудеса. Для избавления от этого эффекта пришлось изменить процедуры вызова.
Sub t1() Dim s1 As String, s2 As String str = "ABCD" adrStr = getAdrStringVBA(str) s1 = dumpPointer(adrStr, 0) s2 = dumpPointer(adrStr - 4, 0) Debug.Print adrStr, " --> " & s1 Debug.Print adrStr - 4, " --> " & s2 End Sub
Пришлось ввести две лишних переменных, чтобы предотвратить выделение памяти, которое приводит к перемещению строки в памяти VBA. Теперь результат стабильный.
82338988 —> 65 — 66 — 67 — 68 — 0 — 0 — 0 — 0 — 108 — 0 — 0 — 0 —
82338984 —> 4 — 0 — 0 — 0 — 65 — 66 — 67 — 68 — 0 — 0 — 0 — 0 —
Хорошо. Но надо проверить факт, как это утверждается в документации, того, что VBA всегда ставит 0 (ноль) в конце строки. Как бы это проверить…
Интересная вскрылась ситуация. Оказывается VBA все время меняет расположение строк в памяти. Фактически каждое новое присваивание чего-то строке меняет её адрес в памяти. Причем, старая строка просто занимается новым содержимым, при том уже в формате Unicode.
Dim ms1 As String ms1 = String(4, 65) adrStr = getAdrStringVBA(ms1) 'Взяли адрес s1 = dumpPointer(adrStr, 0) s2 = dumpPointer(adrStr - 4, 0) Debug.Print adrStr, " --> " & s1 Debug.Print adrStr - 4, " --> " & s2 ms1 = "BB" Dim adrStr2 As Long adrStr2 = getAdrStringVBA(ms1) 'Взяли адрес Debug.Print adrStr2 s1 = dumpPointer(adrStr, 0) s2 = dumpPointer(adrStr - 4, 0) Debug.Print adrStr, " --> " & s1 Debug.Print adrStr - 4, " --> " & s2 EndSub
Вывод:
72519660 —> 65 — 65 — 65 — 65 — 0 — 0 — 53 — 0 — 49 — 0 — 57 — 0 —72519656 —> 4 — 0 — 0 — 0 — 65 — 65 — 65 — 65 — 0 — 0 — 53 — 0 —7251986072519660 —> 66 — 0 — 66 — 0 — 0 — 0 — 32 — 0 — 0 — 0 — 57 — 0 —72519656 —> 4 — 0 — 0 — 0 — 66 — 0 — 66 — 0 — 0 — 0 — 32 — 0 —
Вначале создаётся строка из 4 букв A и это видно по адресу 72519660, потом я пытаюсь присвоить более короткую строку в надежде, что VBA экономя обращения к памяти, запишет её в тот же адрес. Однако ничего подобного не происходит. Создается совершенно новая переменная (её адрес 72519860), а в старый адрес записывается новая строка в формате Unicode.
Почитав документацию вижу следующую фразу: «VBA при обращении к внешним функциям DLL создаёт полную копию исходной строки, при этом конвертируя её из исходного формата Unicode в ASCII представление с конечным нулем для обработки функциями WinApi». Вот оно оказывается как. Теперь понятно почему оператор ms1 = «BB» вызвал создание новой копии. Это была подготовка к вызову внешней функции. Провожу ещё один эксперимент, пытаюсь понять, неужели VBA на каждое присваивание заново делает выделение памяти. Ниже кусочек кода:
ms1 = String(10, 65) ms1 = "BB" adrStr = getAdrStringVBA(ms1) s1 = dumpPointer(adrStr, 0) s2 = dumpPointer(adrStr - 4, 0) Debug.Print adrStr, " --> " & s1 Debug.Print adrStr - 4, " --> " & s2
Вывод:
72520940 —> 66 — 66 — 0 — 0 — 65 — 0 — 65 — 0 — 65 — 0 — 65 — 0 —72520936 —> 2 — 0 — 0 — 0 — 66 — 66 — 0 — 0 — 65 — 0 — 65 — 0 —
Вот и ответ. Забиваем строку 10 буквами A (код 65) и тут же присваиваем новое значение “BB” – которое явно короче и может использовать старый буфер. И точно – в ответе видно, что был использован предыдущий буфер, который был забит 10 буквами A в Unicod (65;0), но в него положили уже сконвертированное значение, подготовленное для передачи во внешнюю функцию.
Со строками разобрались. Вывод для работы со строками в DLL: обязательно нужна промежуточная функция на VBA, которая создаст локальный буфер большого размера, в который мы из DLL и будем записывать результирующие строки для возврата в VBA. Далее нужно извлечь из этого буфера нужное количество символов, которое мы вернем как возвращаемое значение. Пример такого подхода Public Function dumpPointer(pointer As Long, sw As Long) As String. Хорошо, а как быть со строками которые нужно отдать в DLL. А тут все просто, VBA сам выделяет буфер и ещё конвертирует из Unicode, да ещё и количество записывает, что для нас очень кстати, так как позволяет передавать и 0 в строке (фактически двоичные данные). Таким образом можно и передать и вернуть двоичные данные. Добраться до внутреннего представления строк VBA в Unicode возможно, но есть ли в этом надобность.
Рассмотрим массивы и их передачу в DLL. Начнем с массива целых чисел. Что бы получить адрес массива, мы воспользуемся той же функцией в DLL, что и для получения адреса строк. Единственно, что немного обманем VBA, написав новую декларацию.
Declare Function getAdrArrayVBA Lib «r:m2dll.dll» Alias «_getAdr@4» (ByRef buf As Long) As Long
В чем тут хитрость? В том, что мы фактически передаём ссылку на элемент массива. А как указать на весь массив, а просто передать ссылку на его первый элемент и количество таких элементов. Количество передать легко, а вот проверить возможность передачи адреса первого элемента надо.
Dim m(2) As Long m(0) = 1: m(1) = 3 adrStr = getAdrArrayVBA(m(0)) s1 = dumpPointer(adrStr, 0) s2 = dumpPointer(adrStr - 4, 0) Debug.Print adrStr, " --> " & s1 Debug.Print adrStr - 4, " --> " & s2
Вывод:
72514896 —> 1 — 0 — 0 — 0 — 3 — 0 — 0 — 0 — 0 — 0 — 0 — 0 —
72514892 —> 0 — 0 — 0 — 140 — 1 — 0 — 0 — 0 — 3 — 0 — 0 — 0 —
Мы забираем адрес первого элемента массива и в дампе фактически видим сам массив в разрезе четырех байт. Отсюда вывод о том, как работать с массивами. Создаём массив большого размера, в DLL его модифицируем, передавая новую длину, и уже в VBA копируем значимую часть для сохранения результата. Аналогичный должно быть и со структурами, но проверять мне было лень…
Теперь, когда более менее ясно как обмениваться данными из VBA в DLL, вернемся непосредственно в D. Фактически разработчики уже все за нас предусмотрели написав нам dll.d!
В ней описываются точки входа и инициализация GC и Phobos. Таким образом, делать практически ничего не нужно. НО! Есть маленькое но. Так как у нас функции extern (Windows) нам не позволено пользоваться в таких процедурах всеми возможностями динамического распределения памяти. Я не могу дать четкого ответа, чем можно пользоваться а чем нет, но есть выход. Определяем обычные функции (по умолчанию они будут вызова D) и спокойно в них делаем работу, а функции extern (Windows) используем только для обмена параметрами с VBA.
Исходный код m2dll.d с комментариями, а также все необходимые файлы прикреплены ниже. А вот базу с данными, которые передавались в Excel, к сожалению, предоставить не могу, ибо в ней конфиденциальная информация.
Файлы: vba_and_d.zip