5 / 5 / 0 Регистрация: 14.06.2012 Сообщений: 174 |
|
1 |
|
12.12.2014, 17:34. Показов 2827. Ответов 13
Добрый день,
0 |
40 / 35 / 9 Регистрация: 01.01.2014 Сообщений: 201 |
|
12.12.2014, 20:03 |
2 |
Ты хоть сам понимаешь что спрашиваешь?
0 |
1300 / 506 / 63 Регистрация: 09.08.2012 Сообщений: 2,056 |
|
12.12.2014, 21:33 |
3 |
Goodlord, вам сюда: Добавлено через 1 минуту
через vb.net при чем здесь vb.net ? dll написанную на vb.net добавить в эксель?
0 |
10229 / 6607 / 498 Регистрация: 28.12.2010 Сообщений: 21,159 Записей в блоге: 1 |
|
12.12.2014, 22:06 |
4 |
Может не добавить, а использовать (вызвать функции)?
0 |
Памирыч |
12.12.2014, 23:49
|
Не по теме: Razvedka2020, emenem97, raxp, почувствуйте себя сисадминами
0 |
5 / 5 / 0 Регистрация: 14.06.2012 Сообщений: 174 |
|
13.12.2014, 19:58 [ТС] |
6 |
Программа написанная на vb.net должна устанавливать dll в Excel
0 |
10229 / 6607 / 498 Регистрация: 28.12.2010 Сообщений: 21,159 Записей в блоге: 1 |
|
13.12.2014, 20:42 |
7 |
Зачем ее там устанавливать, что вы под этим подразумеваете — какова конечная цель?
0 |
5 / 5 / 0 Регистрация: 14.06.2012 Сообщений: 174 |
|
15.12.2014, 09:46 [ТС] |
8 |
Программа, которая написана на vb.net, должна установить библиотеку (dll) в Add-ins Excel.
0 |
1706 / 1194 / 227 Регистрация: 23.12.2010 Сообщений: 1,526 |
|
15.12.2014, 15:51 |
10 |
Программа, которая написана на vb.net, должна установить библиотеку (dll) в Add-ins Excel. Надстройка для Excel, но реализованная в виде скомпиллированной библиотеки, так?
1 |
Goodlord 5 / 5 / 0 Регистрация: 14.06.2012 Сообщений: 174 |
||||
15.12.2014, 18:53 [ТС] |
11 |
|||
А через
это можно сделать?
0 |
1706 / 1194 / 227 Регистрация: 23.12.2010 Сообщений: 1,526 |
|
16.12.2014, 10:26 |
12 |
А через а что ЭТО ? Добавлено через 11 минут Добавлено через 10 часов 22 минуты Не по теме: Не, ну за спасибо, конечно, спасибо. Но вопрос так и завис: что же все-таки нужно?
1 |
5 / 5 / 0 Регистрация: 14.06.2012 Сообщений: 174 |
|
16.12.2014, 10:52 [ТС] |
13 |
Не, ну за спасибо, конечно, спасибо. Но вопрос так и завис: что же все-таки нужно? Лежит dll в какой то папке, программа на vb.net зная место нахождения этой dll заносит путь к этой dll в COM Add-Ins Excel, но, желательно не трогая реестр.
0 |
Юпатов Дмитрий 1706 / 1194 / 227 Регистрация: 23.12.2010 Сообщений: 1,526 |
||||
16.12.2014, 11:18 |
14 |
|||
Сообщение было отмечено Памирыч как решение Решение А…
не пробовал сам, но МСДН вроде его рекомендует. Добавлено через 1 минуту
желательно не трогая реестр Ну в реестр запись добавится, ЯТД. Это сам Эксель сделает, чтобы в будущем помнить о ней.
0 |
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
hi i am using vs2008+vsto to create excel add in (ribbon)…
is it possible to make it a dll, like myaddin.dll so that users will have to only add this dll… and use, or can you suggest any better approach, thanks a lot!
asked Jul 16, 2009 at 20:11
Yes, you can. However, dlls used in Excel need to be suscribed in the GAC and some registry keys need to be changed (basically telling Excel where to find the dll). So it is best to use a setup to install the dll. The process is somewhat complicated an it is best described here and continued here.
answered Jul 20, 2009 at 2:08
WilhelmWilhelm
1,85814 silver badges21 bronze badges
To correct the above comments…
-
GACing the assembly is not necessary, however registering the assembly for COM automation is necessary. As stated above this is most easily achieved using the MSDN doco on EXCEL Com addins and a setup project for deploying the required keys.
The advantage to strongly naming and GACing the assembly is that it will be fully trusted, this may be an easier way (for some ppl) of getting around permission exceptions (than using CAS).
However in practise unless you are selling your addin externally this is not a show stopper. -
XLA/XLAM is not necessary, it is an alternative to using a COM Addin (either VB6, c++ or .net) XLA is a lighter weight option if you wish to quickly develop and build a solution.
answered Jul 22, 2009 at 23:04
Anonymous TypeAnonymous Type
3,0202 gold badges26 silver badges45 bronze badges
As far as I know, an Excel addin has to be an xla/xlam file. You could have a dll called from the xla, but you’ll still need the xla.
answered Jul 16, 2009 at 20:14
TamarTamar
2,0061 gold badge15 silver badges26 bronze badges
You can do it by writing your Excel add-in in C# as a COM automation object. Then, when you go to the Add-Ins dialog in Excel you can select a COM object or browse to a Com .dll. Excel will create an instance of the objects that you can then call.
answered Jul 16, 2009 at 20:25
SeanSean
60.5k11 gold badges97 silver badges134 bronze badges
2
Introduction
Excel versions 2002 (XP) and 2003 introduce the concept of an Automation Add-In.
Automation Add-Ins allow public functions in COM libraries to act as
User-Defined Functions (UDFs) in Excel, thus to be referenced directly from
cell formulae.
This article provides a detailed walk-through of how to create an Automation Add-In
for Excel using Visual Studio .NET.
Background
Some relevant knowledge base articles that discuss Automation Add-Ins are:
- Q291392 — INFO: Excel COM Add-ins and Automation Add-ins.
-
Q285337 — How To Create a Visual Basic Automation Add-in for Excel Worksheet
Functions. - Q278328 — XL2002: How to Mark an Automation Add-In Function as Volatile.
A commercial library that presents equivalent (and more) functionality, and makes
this all very easy is ManagedXLL.
However, this library is quite expensive and requires run-time licenses to
distribute user code. It uses the native XLL API for creating an add-in to
Excel, and thus also supports older versions of Excel.
The exact requirements for creating a COM server that can be used as an Automation
Add-In are poorly documented, complicated by the fact that the default options
in Visual Basic 6.0 seem to work perfectly.
When creating a COM library using .NET, an attempt to add the library as an
Automation Add-In in Excel causes the error: “The file you selected does not
contain a new Automation Server, or you do not have sufficient privileges to
register the Automation Server”.
Here, I describe how to create an Automation Add-In in .NET, using C#. The
techniques should apply to any .NET language.
There seem to be three tricks for implementing an Automation Add-In for Excel using
.NET:
-
The library needs to be registered for use through COM. This can be done by
marking the project to ‘Register for COM Interop’ or by manual
registration usingRegAsm.exe
. -
The
‘Programmable’
registry key needs to be added in the registry,
underHKCRCLSID{xxx}
. This can be automated by adding
appropriateComRegisterFunction
methods to the class. -
The class needs to be marked with the
ClassInterface
attribute,
with valueClassInterfaceType.AutoDual
(explicit interface
implementations can work too). The default class interface that is generated is
a dispatch interface — Excel seems to ignore the dispatch interface for
Automation Add-Ins.
Walk-through
- Create the library:
- Create a new C# Class Library Project, called NAddIn.
-
Select the project’s properties; under ‘Configuration Properties’, ‘Build’, set ‘Register
for COM Interop’
to True. -
Rename the class, add a namespace declaration, set the
ClassInterface
attribute of the class, and add a function to be used from Excel:using System; using System.Runtime.InteropServices; namespace NAddIn { [ClassInterface(ClassInterfaceType.AutoDual)] public class Functions { public Functions() { } public double Add2(double v1, double v2) { return v1 + v2; } [ComRegisterFunctionAttribute] public static void RegisterFunction(Type t) { Microsoft.Win32.Registry.ClassesRoot.CreateSubKey( "CLSID\{" + t.GUID.ToString().ToUpper() + "}\Programmable"); } [ComUnregisterFunctionAttribute] public static void UnregisterFunction(Type t) { Microsoft.Win32.Registry.ClassesRoot.DeleteSubKey( "CLSID\{" + t.GUID.ToString().ToUpper() + "}\Programmable"); } } }
- Build the NAddIn project to create bindebugNAddIn.dll.
-
Test the Add-In in Excel:
- Open a new workbook in Excel.
- Select Tools, Add-Ins, Automation.
-
NAddIn.Functions
should be listed — select it. OK. -
In a cell, type
=Add2(3,4)
- The cell should display 7.
To register the .dll after moving it, run regasm
with the
/codebase
flag (typically as
c:WINDOWSMicrosoft.NETFrameworkv1.1.4322RegAsm
/codebase NAddIn.dll
).
You will get a warning about the assembly being unsigned — you can ignore this
(or sign the assembly as documented).
History
- Initial version — 19 July 2004.
- Removed type library embedding instructions — 19 July 2004.
-
Added
ComRegisterFunction
bits to automate registry changes — 30 July 2004.
This member has not yet provided a Biography. Assume it’s interesting and varied, and probably something to do with programming.
- Remove From My Forums
-
Question
-
Hi,
Good day.
I have a DLL created in native Visual C++ that has being used successfully in Excel VBA, by including Declare Function declaration at the top of the VBA module.
Now I want to use the same functions in the DLL in XLL add-in. What I need to do?
Regards, Akira
Answers
-
Hi,
Since there is no response it is time to move on?
Akira
-
Marked as answer by
AkiraC
Friday, June 6, 2014 8:21 PM
-
Marked as answer by
All replies
-
Copy the *.h file and *.lib file to your project directory.
Add reference the header files of the DLL.
try to see:
http://msdn.microsoft.com/en-us/library/ms235636.aspx
-
Marked as answer by
Marvin_Guo
Thursday, May 29, 2014 2:12 AM -
Unmarked as answer by
AkiraC
Thursday, May 29, 2014 8:53 PM
-
Marked as answer by
-
-
Edited by
Jeffrey_Chen_
Monday, May 26, 2014 2:32 AM -
Marked as answer by
Marvin_Guo
Thursday, May 29, 2014 2:12 AM -
Unmarked as answer by
AkiraC
Thursday, May 29, 2014 8:53 PM
-
Edited by
-
Hi,
Thanks for the quick replies.
_Beverly:
I had tried the method that you pointed out a while ago (more than a year ago). I was able to compile the XLL, that references the dynamic linked library, without error. But when I tried to open the XLL in Excel it crashes. Note that if
the library is complied into the XLL as static library then XLL works as expected in Excel.Jeffrey-Chen:
Creating XLL is not the issue. The issue is getting the dynamic linked library to work and without crashing when the XLL is open in Excel.
Has anyone experience the same problem? May be the DLL has to be in same folder where the Excel.exe is in (I have to recreated the DLL, but will take a while, to see if this works). That is the reason I mentioned about using external DLL in Excel VBA
where you have to specify the the full path of the DLL (if the DLL is not in the Windows directory).My question is how to specify the full path of the DLL in C++. That is if there is a way to using DLL in XLL the ways it is done in Excel VBA. If I am not mistaken it could be done this way in Delphi.
Regards, Akira
-
Hi,
Since there is no response it is time to move on?
Akira
-
Marked as answer by
AkiraC
Friday, June 6, 2014 8:21 PM
-
Marked as answer by
-
There’s one more little wrinkle that they don’t tell you about: the DLL you’re trying to call from your XLL must either
(a) be sitting right beside Excel in the OfficeXX folder, or
(b) be located somewhere on your Windows search path (that’s right; the old DOS search path!) so that Excel can find it.
Otherwise everything will compile/link without issues but Excel will fail to load the add-in — even if the DLL is sitting RIGHT BESIDE THE XLL in your build configuration folder — and will give you a message something like «The file you are trying
to open, ‘MyTestXL.xll’, is in a different format than specified by the file extension.»I found that the most expedient thing was simply to append the add-ins folder (hidden under Documents and Settings/[myname]/Application Data/Microsoft/AddIns) to the search path (My Computer | Properties | Advanced | Environment Variables | User variables
for [myname]). Now I can automatically copy both XLL and DLL to that folder in my post-build step and Excel will consistently know where to find it.-
Proposed as answer by
Rudisaurus
Tuesday, April 14, 2015 11:16 PM -
Edited by
Rudisaurus
Tuesday, April 14, 2015 11:38 PM
-
Proposed as answer by
-
Thank you Rudisaurus.
At the end I put all the code in a single XLL.