Excel vba load dll

title manager ms.date ms.audience ms.topic keywords ms.assetid ms.localizationpriority

Access DLLs in Excel

soliver

03/09/2015

Developer

overview

accessing dlls [excel 2007],DLLs [Excel 2007], accessing in Excel

e2bfd6ea-efa3-45c1-a5b8-2ccb8650c6ab

high

Access DLLs in Excel

Applies to: Excel 2013 | Office 2013 | Visual Studio

You can access a DLL function or command in Microsoft Excel in several ways:

  • Through a Microsoft Visual Basic for Applications (VBA) code module in which the function or command has been made available using a Declare statement.

  • Through an XLM macro sheet by using the CALL or REGISTER functions.

  • Directly from the worksheet or from a customized item in the user interface (UI).

This documentation does not cover XLM functions. It is recommended that you use either of the other two approaches.

To be accessed directly from the worksheet or from a customized item in the UI, the function or command must first be registered with Excel. For information about registering commands and functions, see Accessing XLL Code in Excel.

Calling DLL functions and commands from VBA

You can access DLL functions and commands in VBA by using the Declare statement. This statement has one syntax for commands and one for functions.

  • Syntax 1 — commands

    [Public | Private] Declare Sub name Lib "libname" [Alias "aliasname"] [([arglist])]
  • Syntax 2 — functions

    [Public | Private] Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]

The optional Public and Private keywords specify the scope of the imported function: the entire Visual Basic project or just the Visual Basic module, respectively. The name is the name that you want to use in the VBA code. If this differs from the name in the DLL, you must use the Alias «aliasname» specifier, and you should give the name of the function as exported by the DLL. If you want to access a DLL function by reference to a DLL ordinal number, you must provide an alias name, which is the ordinal prefixed by #.

Commands should return void. Functions should return types that VBA can recognize ByVal. This means that some types are more easily returned by modifying arguments in place: strings, arrays, user-defined types, and objects.

[!NOTE]
VBA cannot check that the argument list and return stated in the Visual Basic module are the same as coded in the DLL. You should check this yourself very carefully, because a mistake could cause Excel to crash.

When the function or command’s arguments are not passed by reference or pointer, they must be preceded by the ByVal keyword in the arglist declaration. When a C/C++ function takes pointer arguments, or a C++ function takes reference arguments, they should be passed ByRef. The keyword ByRef can be omitted from argument lists because it is the default in VBA.

Argument types in C/C++ and VBA

You should note the following when you compare the declarations of argument types in C/C++ and VBA.

  • A VBA String is passed as a pointer to a byte-string BSTR structure when passed ByVal, and as a pointer to a pointer when passed ByRef.

  • A VBA Variant that contains a string is passed as a pointer to a Unicode wide-character string BSTR structure when passed ByVal, and as a pointer to a pointer when passed ByRef.

  • The VBA Integer is a 16-bit type equivalent to a signed short in C/C++.

  • The VBA Long is a 32-bit type equivalent to a signed int in C/C++.

  • Both VBA and C/C++ allow the definition of user-defined data types, using the Type and struct statements respectively.

  • Both VBA and C/C++ support the Variant data type, defined for C/C++ in the Windows OLE/COM header files as VARIANT.

  • VBA arrays are OLE SafeArrays, defined for C/C++ in the Windows OLE/COM header files as SAFEARRAY.

  • The VBA Currency data type is passed as a structure of type CY, defined in the Windows header file wtypes.h, when passed ByVal, and as a pointer to this when passed ByRef.

In VBA, data elements in user-defined data types are packed to 4-byte boundaries, whereas in Visual Studio, by default, they are packed to 8-byte boundaries. Therefore you must enclose the C/C++ structure definition in a #pragma pack(4) … #pragma pack() block to avoid elements being misaligned.

The following is an example of equivalent user type definitions.

Type VB_User_Type
    i As Integer
    d As Double
    s As String
End Type
#pragma pack(4)
struct C_user_type
{
    short iVal;
    double dVal;
    BSTR bstr; // VBA String type is a byte string
}
#pragma pack() // restore default

VBA supports a greater range of values in some cases than Excel supports. The VBA double is IEEE compliant, supporting subnormal numbers that are currently rounded down to zero on the worksheet. The VBA Date type can represent dates as early as 1-Jan-0100 using negative serialized dates. Excel only allows serialized dates greater than or equal to zero. The VBA Currency type—a scaled 64-bit integer—can achieve accuracy not supported in 8-byte doubles, and so is not matched in the worksheet.

Excel only passes Variants of the following types to a VBA user-defined function.

VBA data type C/C++ Variant type bit flags Description
Double VT_R8
Boolean VT_BOOL
Date VT_DATE
String VT_BSTR OLE Bstr byte string
Range VT_DISPATCH Range and cell references
Variant containing an array VT_ARRAY VT_VARIANT Literal arrays
Ccy VT_CY 64-bit integer scaled to permit 4 decimal places of accuracy.
Variant containing an error VT_ERROR
VT_EMPTY Empty cells or omitted arguments

You can check the type of a passed-in Variant in VBA using the VarType, except that the function returns the type of the range’s values when called with references. To determine if a Variant is a Range reference object, you can use the IsObject function.

You can create Variants that contain arrays of variants in VBA from a Range by assigning its Value property to a Variant. Any cells in the source range that are formatted using the standard currency format for the regional settings in force at the time are converted to array elements of type Currency. Any cells formatted as dates are converted to array elements of type Date. Cells containing strings are converted to wide-character BSTR Variants. Cells containing errors are converted to Variants of type VT_ERROR. Cells containing Boolean True or False are converted to Variants of type VT_BOOL.

[!NOTE]
The Variant stores True as -1 and False as 0. Numbers not formatted as dates or currency amounts are converted to Variants of type VT_R8.

Variant and string arguments

Excel works internally with wide-character Unicode strings. When a VBA user-defined function is declared as taking a String argument, Excel converts the supplied string to a byte-string in a locale-specific way. If you want your function to be passed a Unicode string, your VBA user-defined function should accept a Variant instead of a String argument. Your DLL function can then accept that Variant BSTR wide-character string from VBA.

To return Unicode strings to VBA from a DLL, you should modify a Variant string argument in place. For this to work, you must declare the DLL function as taking a pointer to the Variant and in your C/C++ code, and declare the argument in the VBA code as ByRef varg As Variant. The old string memory should be released, and the new string value created by using the OLE Bstr string functions only in the DLL.

To return a byte string to VBA from a DLL, you should modify a byte-string BSTR argument in place. For this to work, you must declare the DLL function as taking a pointer to a pointer to the BSTR and in your C/C++ code, and declare the argument in the VBA code as ‘ ByRef varg As String‘.

You should only handle strings that are passed in these ways from VBA using the OLE BSTR string functions to avoid memory-related problems. For example, you must call SysFreeString to free the memory before overwriting the passed in string, and SysAllocStringByteLen or SysAllocStringLen to allocate space for a new string.

You can create Excel worksheet errors as Variants in VBA by using the CVerr function with arguments as shown in the following table. Worksheet errors can also be returned to VBA from a DLL using Variants of type VT_ERROR, and with the following values in the ulVal field.

Error Variant ulVal value CVerr argument
#NULL! 2148141008 2000
#DIV/0! 2148141015 2007
#VALUE! 2148141023 2015
#REF! 2148141031 2023
#NAME? 2148141037 2029
#NUM! 2148141044 2036
#N/A 2148141050 2042

Note that the Variant ulVal value given is equivalent to the CVerr argument value plus x800A0000 hexadecimal.

Calling DLL functions directly from the worksheet

You cannot access Win32 DLL functions from the worksheet without, for example, using VBA or XLM as interfaces, or without letting Excel know about the function, its arguments, and its return type in advance. The process of doing this is called registration.

The ways in which the functions of a DLL can be accessed in the worksheet are as follows:

  • Declare the function in VBA as described previously and access it via a VBA user-defined function.

  • Call the DLL function using CALL on an XLM macro sheet, and access it via an XLM user-defined function.

  • Use an XLM or VBA command to call the XLM REGISTER function, which provides the information that Excel needs to recognize the function when it is entered into a worksheet cell.

  • Turn the DLL into an XLL and register the function using the C API xlfRegister function when the XLL is activated.

The fourth approach is self-contained: the code that registers the functions and the function code are both contained in the same code project. Making changes to the add-in does not involve making changes to an XLM sheet or to a VBA code module. To do this in a well-managed way while still staying within the capabilities of the C API, you must turn your DLL into an XLL and load the resulting add-in by using the Add-in Manager. This enables Excel to call a function that your DLL exposes when the add-in is loaded or activated, from which you can register all of the functions your XLL contains, and carry out any other DLL initialization.

Calling DLL commands directly from Excel

Win32 DLL commands are not accessible directly from Excel dialog boxes and menus without there being an interface, such as VBA, or without the commands being registered in advance.

The ways in which you can access the commands of a DLL are as follows:

  • Declare the command in VBA as described previously and access it via a VBA macro.

  • Call the DLL command using CALL on an XLM macro sheet, and access it via an XLM macro.

  • Use an XLM or VBA command to call the XLM REGISTER function, which provides the information Excel needs to recognize the command when it is entered into a dialog box that expects the name of a macro command.

  • Turn the DLL into an XLL and register the command using the C API xlfRegister function.

As discussed earlier in the context of DLL functions, the fourth approach is the most self-contained, keeping the registration code close to the command code. To do this, you must turn your DLL into an XLL and load the resulting add-in using the Add-in Manager. Registering commands in this way also lets you attach the command to an element of the user interface, such as a custom menu, or to set up an event trap that calls the command on a given keystroke or other event.

All XLL commands that are registered with Excel are assumed by Excel to be of the following form.

int WINAPI my_xll_cmd(void)
{
// Function code...
    return 1;
}

[!NOTE]
Excel ignores the return value unless it is called from an XLM macro sheet, in which case the return value is converted to TRUE or FALSE. You should therefore return 1 if your command executed successfully, and 0 if it failed or was canceled by the user.

DLL memory and multiple DLL instances

When an application loads a DLL, the DLL’s executable code is loaded into the global heap so that it can be run, and space is allocated on the global heap for its data structures. Windows uses memory mapping to make these areas of memory appear as if they are in the application’s process so that the application can access them.

If a second application then loads the DLL, Windows does not make another copy of the DLL executable code, as that memory is read-only. Windows maps the DLL executable code memory to the processes of both applications. It does, however, allocate a second space for a private copy of the DLL’s data structures and maps this copy to the second process only. This ensures that neither application can interfere with the DLL data of the other.

This means that DLL developers do not have to be concerned about static and global variables and data structures being accessed by more than one application, or more than one instance of the same application. Every instance of every application gets its own copy of the DLL’s data.

DLL developers do need to be concerned about the same instance of an application calling their DLL many times from different threads, because this can result in contention for that instance’s data. For more information, see Memory Management in Excel.

See also

  • Developing DLLs
  • Calling into Excel from the DLL or XLL

I am trying to call function from dll which I have made in Visual Studio. I receive error message 

«Run-time error ‘453’:

Cant find DLL entry point SGR in

C:UsersAcasourcereposPERMHP_1PERMHP_1binDebugPERMHP_1.dll»

I have made dll under visual basic project: Class Library (.NET Framework).

I have added my dll to VBA project references

Can anyone help how to call function?

DLL CODE:

Option Strict On
Option Explicit On
Public Class Residual_SGR

    Public Function SGR(VISW As Double, VISO As Double, FI As Double, PB As Double, T As Double, RSPB As Double, CW As Double, GAMAO As Double, PMIN As Double, SWEX As Double, EQSW As Double, AK As Double, PCM As Double) As Double
        Dim A, B, X, C As Double

        PB = PB * 14.22334
        T = T * 1.8 + 32.0
        RSPB = RSPB * 5.6145821
        GAMAO = 141.5 / GAMAO - 131.5
        PMIN = PMIN * 14.22334
        A = -758.0 + 0.86 * FI + 5.29 * CW - 0.0444 * CW ^ 2 - 77.2 * Math.Log(CW) - 0.0386 * RSPB
        B = A + 0.0000533 * RSPB ^ 2 + 4.06 * GAMAO - 0.057 * GAMAO ^ 2
        X = 0.000156 * (PB / PMIN) ^ 2
        C = B + X + 2.02 * Math.Log(PB / PMIN) + 0.0123 * PB - 0.00000369 * PB ^ 2
        SGR = C - 3.71 * T + 0.00643 * T ^ 2 + 253.0 * Math.Log(T)
        Return SGR
    End Function
End Class

VBA CODE:

Option Explicit

Private Declare PtrSafe Function SGR Lib "C:UsersAcasourcereposPERMHP_1PERMHP_1binDebugPERMHP_1.dll" _
(ByRef VISW As Double, ByRef VISO As Double, ByRef FI As Double, ByRef PB As Double, ByRef T As Double, ByRef RSPB As Double, ByRef CW As Double, _
ByRef GAMAO As Double, ByRef PMIN As Double, ByRef SWEX As Double, ByRef EQSW As Double, ByRef AK As Double, ByRef PCM As Double) As Double


' using the function from VBA
Sub Button1_Click()
   MsgBox SGR(0.4406, 0.42512, 22.2, 141, 82.5, 95.8, 35.8, 0.82, 50, 2, 0.2, 0, 0)
End Sub

  • Moved by

    Friday, June 8, 2018 7:37 AM

Modular Programming

As you recall from our computer programming lessons, one of the key concepts in good software design is modularity: breaking our code into functional subroutines or functions, each responsible for a specific task with a clear interface for calling it.

Once encapsulated in a self-contained function, this functionality can be re-used in many locations in your program. This improves the size, quality, maintainability and readability of your program. Also, without modular design, your program can only grow so much before you lose your arms and legs.

I’d go as much to say that a good modular design is one of the first signs I look for in judging the quality of a programmer.

Using Functions Outside of Excel

Expanding on the modularity concept, why limit ourselves to functions we coded in our VBA application? There are many functions out there already developed by others and proven robust and performant – why not break the boundaries of Excel VBA and consume them, or CALL them from our Excel VBA program?

Some of the things we would like to do can’t even be achieved without using an external function that is not part of Excel VBA or that we can write ourselves without consuming such a function.

Consider, for example, the need to control the Window properties (maybe size or position) of another application running on our Windows operating system, from Excel VBA. This Window is governed by the operating system and we have no access to it without calling a Windows function that has access to that Window and can manipulate it.

What is a DLL?

A DLL (Dynamic Link Library) is a package of functions/subroutines callable by other programs running in the Windows operating system.

Typically, a DLL file has the .dll extension, although other extensions are possible for certain types of files (e.g. .ocx for ActiveX controls).

Most of the Windows operating system functionality itself is implemented by DLLs, each calling and called by other programs. One such example would be the Comdlg32.DLL file, offering a function to open the File Open dialog box for selecting file(s) – a functionality needed by many programs running on Windows.

Almost every program that is installed on a Windows machine registers its own DLLs in the Windows registry.

Once a DLL is properly registered with Windows, its published functions can be consumed and called by any other program running on that machine, and that includes Excel VBA, of course!

Almost every program developed for running on Windows makes use of existing DLL files and contributes its own DLL files to the party.

For an elaborate discussion on DLLs, read this Microsoft article.

Calling a DLL from Excel VBA

In order to gain access to the functions/subroutines included in a DLL file, you need to first declare your intentions to do that, using the Declare statement.

If you intent to call the PlayMusic sub exposed by the (imaginary) FunActivities.DLL file, your declaration statement may look like this:

Declare Sub PlayMusic Lib “FunActivities” ()

If the PlayMusic sub expects arguments, the declaration must also include those arguments (passed ByRef by default):

Declare Sub PlayMusic Lib “FunActivities” (ByVal Duration as Long)

As with any declaration in VBA, you can precede the declaration with the Public or Private qualifiers to contol for the scope of the sub in your VBA project:

Public Declare Sub PlayMusic Lib “FunActivities” ()

Declaring a function is very similar, with the notable return type expected as with any function:

Private Declare Function CountPixels Lib “PixelsInfo” () As Long

Sometimes, a function name as exposed by the DLL may be in conflict with VBA or other variables used in your program. To circumvent this, you can specify a local name to reference that function by in your VBA program, instead of the original name as determined by the DLL developer. In this case, you will add the Alias qualifier to reference the original function name, while the declared name will be your own local flavor:

Declare Sub MyPlayMusic Lib “FunActivities” Alias “PlayMusic”()

Another way of referencing a function in the DLL, instead of by its published (or exported) name, would be by its index, or ordinal number, as defined by the developer. In this case, we must use the Alias qualifier and the “#” character to indicate an ordinal number:

Declare Sub PlayMusic Lib “FunActivities” Alias “#241”()

Referencing by ordinal number guaranties consistency even if the function name will be changed in future versions, but developers are very aware not to mess with function names in DLLs, and this way is rarely used nowadays.

For a complete and detailed explanation of the Declare statement, read this Microsoft article.

Calling a DLL Sub from Excel VBA Example

The following example is implemented in The Ultimate Excel Date Picker. If you got this neat perk already, you may be familiar with the following code, as the Date Picker comes with its VBA code open.

In developing The Ultimate Excel Date Picker, I needed to reference several DLL services, one of which is to simulate a keyboard TAB pressed.

I could have used the SendKeys() VBA function, but let me tell you – it has more promise than it delivers. I would not rely on this statement at all in any of my programs.

However, the Windows user32.DLL file offers a keyboard event sub, directly from Windows, not VBA. Here’s the declaration part I have:

#If VBA7 Then   

    Private Declare PtrSafe Sub keybd_event Lib "user32.dll" _

    (ByVal bVk As Byte, ByVal bScan As Byte, _

     ByVal dwFlags As LongPtr, ByVal dwExtraInfo As LongPtr)

#Else

    ' Code is NOT running in 32-bit or 64-bit VBA7

    Private Declare Sub keybd_event Lib "user32.dll" _

    (ByVal bVk As Byte, ByVal bScan As Byte, _

     ByVal dwFlags As Long, ByVal dwExtraInfo As Long)

#End If

And here’s the function implementing a TAB keypress. Two calls are invoked here, one for pressing the TAB key, another for releasing it:

Public Sub PressTab()

    keybd_event VB_TAB, 0, 0, 0

    keybd_event VB_TAB, 0, KEYEVENTF_KEYUP, 0

End Sub

The two Constants used are declared as usual at the top of the module:

Const VB_TAB = 9

Const KEYEVENTF_KEYUP = &H2

I know I know, you must be thinking: what’s that PtrSafe qualifier I did not talk about, and what’s the story with the “IF VBA7 clause and LongPtr… All about that in next week’s Blog post!

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

#1

07.06.2018 06:36:16

Здравствуйте, создал тестовую DLL с помощью def файла:
Код С++ (*.cpp)

Код
 
double __stdcall square(double & x)
{
   return x * x;
}

Код С++ (*.def)

Код
 
LIBRARY "square"
EXPORT
square

Затем пытаюсь подключить к VBA так:

Код
Declare PtrSafe Function square _
Lib "C:UsersOSAsourcerepossquarex64Debugsquare.dll" _
(ByRef x As Double) As Double

В ячейке пишу формулу с подключенной функцией «square»:

Код
=square(10)

И в ячейке получаю ошибку «ЗНАЧ!»
Использую Excel 2016 x 64. Помогите разобраться где ошибка.

Прикрепленные файлы

  • Dll.rar (114.88 КБ)

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

Доброе время суток.
Не ваш

случай

? По позже

bedvit

подтянется, подскажет как правильно. Он спец.

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Спасибо Андрей. Сейчас в пути, поэтому посмотреть могу через час. Используйте функцию square в VBA, а не на листе. Вы декларируете в заголовке ее для транслятора VBA. Что бы лист понимал функцию, ее надо обернуть в VBA. Да и библу можно собрать в Relise, в Debug работает медленнее и весит больше.

«Бритва Оккама» или «Принцип Калашникова»?

 

Дмитрий Щербаков

Пользователь

Сообщений: 14181
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#4

07.06.2018 09:08:10

Согласен с Андрей VG и bedvit, не хватает вызова функции. Типа того:

Код
Declare PtrSafe Function square _Lib "C:UsersOSAsourcerepossquarex64Debugsquare.dll" _
(ByRef x As Double) As Double
'создаем функцию для вызова декларированной в DLL функции
Function CallSQ(x as double)
CallSQ = square(x)
end function

ведь сами по себе функции API не могут быть вызваны с листа.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Дмитрий Щербаков, все верно, потому как декларация это  ссылка для транслятора VBA. Лист про нее ничего не знает. А на листе вызывать CallSQ.

«Бритва Оккама» или «Принцип Калашникова»?

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

А если собрать .xll, то и декларировать ничего не нужно и VBA не нужен. Правда в этом случае регистрацию все равно надо писать, но в самой библе. Зато пользователю одни плюшки — открыл, пользуйся.

«Бритва Оккама» или «Принцип Калашникова»?

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

#7

07.06.2018 14:26:20

Благодарю за уделенное внимание. Собрал dll в Relise,  сделал функцию как посоветовали:

Код
Declare PtrSafe Function square _
Lib "C:UsersOSADesktopDllsquarex64Releasesquare.dll" _
(ByRef x As Double) As Double

Function CallSQ(x As Double)
CallSQ = square(x)
End Function

В ячейке ввел:

Код
=CallSQ(10)

Получил ту же ошибку.
Вначале  делал все так же как в  этом

видеоролике

, у автора видео функция сработала сразу на листе, не понимаю почему у меня не получается. Может быть в 2016 версии Excel нужно что то добавить или поменять в коде?

Прикрепленные файлы

  • Dll.rar (155.96 КБ)

Изменено: OSA91307.06.2018 14:29:27

 

Дмитрий Щербаков

Пользователь

Сообщений: 14181
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#8

07.06.2018 14:30:00

А Вы пробовали вызывать функцию процедурой?

Код
Sub CallSQ_S(x As Double)
msgbox square(x)
End sub

ошибок не появляется, все работает? Может сборку произвели для 64 бит, а офис 32-битный?

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

#9

07.06.2018 14:49:20

Попробовал процедурой таким образом:

Код
Sub qq()
CallSQ (5)
End Sub

Получил ошибку 453: «Can’t find DLL entry point square in»
офис и виндоус 64й

Изменено: OSA91307.06.2018 14:50:27

 

Дмитрий Щербаков

Пользователь

Сообщений: 14181
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

Вероятно, DLL-ку надо регистрировать в системе.

Хотя туплю, судя по ошибке функция неверно декларирована в коде. Т.е. система не видит эту функцию. Проверьте написание везде, что ли…Пока только так видится проблема.

Изменено: Дмитрий Щербаков07.06.2018 14:53:26

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Нет, регистрировать не нужно. Вы в какой разрядности собираете? должна быть разрядность такая же как Excel.

«Бритва Оккама» или «Принцип Калашникова»?

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

Попробовал Tools-References-Browse…, выбрал файл длл. выскочило сообщение «Can’t add a reference to the specified file.»

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

#13

07.06.2018 14:56:11

приложите исходники, я гляну. Собираете библу в студии?

У вас Excel 64-разрядный?

увидел, что да — х64

Цитата
написал:
Tools-References-Browse..

— это для COM

Изменено: bedvit07.06.2018 15:01:31

«Бритва Оккама» или «Принцип Калашникова»?

 

Дмитрий Щербаков

Пользователь

Сообщений: 14181
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

Кстати, у Вас в проекте в «defFile.def» вместо EXPORTS записано EXPORT. Уверены, что S там лишняя?

Изменено: Дмитрий Щербаков07.06.2018 15:03:15

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

#15

07.06.2018 15:04:27

Цитата
Дмитрий Щербаков написал:
вместо EXPORTS записано EXPORT.

Правильно EXPORTS

«Бритва Оккама» или «Принцип Калашникова»?

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

Собирал в Visual Studio 2017

Прикрепленные файлы

  • Dll.rar (155.96 КБ)

 

OSA913

Пользователь

Сообщений: 248
Регистрация: 03.01.2016

Спасибо огромное, теперь работает))

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Пересобрал — проект рабочий, если правильно экспортировать функцию — в defFile.def — «EXPORTS».

«Бритва Оккама» или «Принцип Калашникова»?

 

RainMan

Пользователь

Сообщений: 23
Регистрация: 27.11.2015

#19

16.12.2019 16:46:34

Прошу и мне помочь. У меня win 7 64bit и Exel 2010 64bit. Просмотрел эту тему, взял уже готовый макрос с библиотекой от OSA913 (dll.rar). Распаковал. Положил библиотеку в C:Test. Немного изменил код VBA (указан ниже). При попытке выполнить процедуру Test выдает  — Can’t faind Dll entry points square in C:Testsquare.dll.

Код
Declare PtrSafe Function square Lib "C:Testsquare.dll" (ByRef x As Double) As Double
Function CallSQ(x As Double)
CallSQ = square(x)
End Function
Sub Test()
   a = CallSQ(2)
End Sub

Подскажите что неправилно делаю? Ведь уже был выложен готовый, рабочий код?

Изменено: RainMan16.12.2019 16:47:14

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

#20

17.12.2019 10:46:04

Это потому, что сборка с ошибкой, см. пост 14,15
Вот правильная версия.

Прикрепленные файлы

  • Dll.zip (100.91 КБ)

«Бритва Оккама» или «Принцип Калашникова»?

  • Home
  • VBForums
  • Visual Basic
  • Office Development
  • Loading DLL to Excel VBA macro

  1. Sep 27th, 2018, 11:40 AM


    #1

    usercc is offline

    Thread Starter


    New Member


    Loading DLL to Excel VBA macro

    I am trying to integrate a DLL that has provided me with a supplier in a macro of calculation and selection of components.

    The way to load the DLL is (the Start Job function is one that needs to be called and its input and output variables are predefined):

    Public Declare PtrSafe Function StartJob Lib «C: Users Carlos Desktop DLL_Calculo_Componentes calcdll.dll» (ByRef p1 as double, ByRef p2 as variant, ByRef p3 as variant) As Boolean

    But when I try to run, I get the following errors, depending on whether you enter the full path or just the name of the DLL:

    — Error ’48’ occurred at runtime: Error loading DLL library
    — Error ’53’ occurred at runtime: File not found

    I have already reviewed the path indicated in the declare statement and it is the correct one, and the dll is in that folder.
    The dll is in the same directory as the macro that uses it.
    I use the «ptrsafe» instruction because my system is in 64 bits.
    It does not allow loading the DLL through «tools -> references».

    Why is there an error?
    What is another way to load the DLL?

    Thank you very much for the help.


  2. Sep 29th, 2018, 09:36 PM


    #2

    Re: Loading DLL to Excel VBA macro

    with the arguments being passed to the function, looks like 32 bit API, so may not work with 64 bit excel
    i would suggest contacting the people who supplied the dll, for better information

    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete


  • Home
  • VBForums
  • Visual Basic
  • Office Development
  • Loading DLL to Excel VBA macro


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
  • BB code is On
  • Smilies are On
  • [IMG] code is On
  • [VIDEO] code is On
  • HTML code is Off

Forum Rules


Click Here to Expand Forum to Full Width

Like this post? Please share to your friends:
  • Excel vba getobject excel application
  • Excel vba listobjects querytable
  • Excel vba get worksheet
  • Excel vba get selected value
  • Excel vba get row from range