Accès aux fichiers DLL dans Excel
S’applique à: Excel 2013 | Office 2013 | Visual Studio
Vous pouvez accéder à une commande ou à une fonction DLL dans Microsoft Excel de plusieurs manières :
avec un module de code Microsoft�Visual�Basic pour Applications (VBA) dans lequel la fonction ou commande a �t� rendue disponible � l�aide d�une instruction Declare�;
avec une feuille macro XLM � l�aide des fonctions CALL ou REGISTER�;
directement � partir de la feuille de calcul ou d�un �l�ment personnalis� dans l�interface utilisateur.
Cette documentation ne couvre pas les fonctions XLM. Il est recommand� d�utiliser l�une des deux autres approches.
Pour pouvoir acc�der � la fonction ou � la commande directement � partir de la feuille de calcul ou d�un �l�ment personnalis� dans l�interface utilisateur, elles doivent pr�alablement �tre inscrites aupr�s d�Excel. Pour plus d�informations sur l�inscription des commandes et des fonctions, voir Acc�s au code XLL dans Excel (en anglais).
Appel des fonctions et commandes DLL à partir de VBA
Vous pouvez acc�der aux fonctions et commandes DLL dans VBA � l�aide de l�instruction Declare. Elle poss�de une syntaxe pour les commandes, et une syntaxe pour les fonctions.
Syntaxe�1�: commandes
[Public | Private] Declare Sub name Lib "libname" [Alias "aliasname"] [([arglist])]
Syntaxe�2�: fonctions
[Public | Private] Declare Function name Lib "libname" [Alias "aliasname"] [([arglist])] [As type]
Les mots cl�s facultatifs Public et Private indiquent la port�e de la fonction import�e, respectivement l�ensemble du projet Visual�Basic ou le module Visual�Basic. Le nom est celui que vous souhaitez utiliser dans le code VBA. S�il est diff�rent du nom dans DLL, vous devez utiliser le sp�cificateur Alias ��aliasname��, et vous devez indiquer le nom de la fonction comme export� par DLL. Si vous souhaitez acc�der � une fonction DLL en r�f�rence � un nombre ordinal DLL, vous devez fournir un nom d�alias, autrement dit l�ordinal pr�fix� par #.
Les commandes doivent renvoyer void. Les fonctions doivent renvoyer des types que VBA peut reconna�tre, ByVal. Cela signifie que certains types sont renvoy�s plus facilement en modifiant les arguments en place�: cha�nes, tableaux, types d�finis par l�utilisateur et objets.
Notes
[!REMARQUE] VBA ne peut pas v�rifier que la liste d�arguments et que le renvoi indiqu� dans le module Visual�Basic sont les m�mes que ceux cod�s dans DLL. Vous devez v�rifier cet �l�ment vous-m�me tr�s attentivement, car une erreur peut provoquer un incident d�Excel.
Lorsque les arguments de la fonction ou de la commande ne sont pas transmis par r�f�rence ou pointeur, ils doivent �tre pr�c�d�s du mot cl� ByVal dans la d�claration arglist. Lorsqu�une fonction C/C++ prend des arguments de pointeur, ou qu�une fonction C++ prend des arguments de r�f�rence, ils doivent �tre transmis ByRef. Le mot cl� ByRef peut �tre omis des listes d�arguments, car il s�agit de la valeur par d�faut dans VBA.
Types d’arguments dans C/C++ et VBA
Vous devez tenir compte de ce qui suit lorsque vous comparez les déclarations de types d’argument dans C/C++ et VBA.
Un �l�ment String VBA est transmis comme pointeur vers une structure BSTR de cha�ne d�octets lorsqu�il est transmis ByVal, et comme pointeur vers un pointeur lorsqu�il est transmis ByRef.
Un �l�ment Variant VBA contenant une cha�ne est transmis comme pointeur vers une structure BSTR de cha�ne de caract�res larges lorsqu�il est transmis ByVal, et comme un pointeur vers un pointeur lorsqu�il est transmis ByRef.
L��l�ment Integer VBA est un type de 16�bits �quivalent � un �l�ment signed short dans C/C++.
L��l�ment Long VBA est un type de 32�bits �quivalent � un �l�ment signed int dans C/C++.
VBA et C/C++ permettent de d�finir des types de donn�es d�finis par l�utilisateur, � l�aide des instructions Type et struct, respectivement.
VBA et C/C++ prennent en charge le type de donn�es Variant, d�fini pour C/C++ dans les fichiers d�en-t�te OLE/COM Windows en tant que VARIANT.
Les tableaux VBA sont des �l�ments SafeArrays OLE d�finis pour C/C++ dans les fichiers d�en-t�te OLE/COM Windows en tant que SAFEARRAY.
Le type de donn�es VBA Currency est transmis comme une structure de type CY, d�finie dans le fichier d�en-t�te Windows wtypes.h lorsqu�il est transmis ByVal, et comme un pointeur vers cet �l�ment lorsqu�il est transmis ByRef.
Dans VBA, les �l�ments de donn�es dans les types de donn�es d�finis par l�utilisateur sont compress�s aux limites de 4�octets, tandis que dans Visual�Studio, par d�faut, ils sont compress�s aux limites de 8�octets. Par conséquent, vous devez encadrer la définition de la structure C/C++ dans un bloc #pragma pack(4) … #pragma pack()
pour éviter l’alignement incorrect des éléments.
Voici un exemple de définitions de types d’utilisateur équivalentes.
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
Dans certains cas, VBA prend en charge une plage de valeurs plus grande qu�Excel. Le double de VBA est compatible IEEE, et prend en charge des num�ros inf�rieurs � la normale qui sont arrondis � z�ro sur la feuille de calcul. Le type Date VBA peut repr�senter des dates comme 1-Jan-0100 � l�aide de dates s�rialis�es n�gatives. Excel autorise uniquement les dates s�rialis�es sup�rieures ou �gales � z�ro. Le type Currency VBA (un nombre de 64�bits mis � l��chelle) peut atteindre une pr�cision non prise en charge par les doubles de 8�octets, et n�est donc pas mis en correspondance dans la feuille de calcul.
Excel transmet uniquement des variantes des types suivants � une fonction d�finie par l�utilisateur VBA.
Type de donn�es VBA | Indicateurs binaires de type Variant C/C++ | Description |
---|---|---|
Double |
VT_R8 |
|
Boolean |
VT_BOOL |
|
Date |
VT_DATE |
|
String |
VT_BSTR |
Cha�ne d�octets BSTR OLE |
Range |
VT_DISPATCH |
Références de plage et de cellule |
Variant contenant un tableau |
VT_VARIANT VT_ARRAY |
Tableaux de type litt�ral |
Ccy |
VT_CY |
Nombre entier de 64�bits mis � l��chelle pour autoriser 4�d�cimales de pr�cision. |
Variant contenant une erreur |
VT_ERROR |
|
VT_EMPTY |
Cellules vides ou arguments omis |
Vous pouvez v�rifier le type d�un �l�ment Variant transmis dans VBA � l�aide de VarType, sauf que la fonction renvoie le type des valeurs de la plage lorsqu�elle est appel�e avec des r�f�rences. Pour d�terminer si un �l�ment Variant est un objet de r�f�rence Range, vous pouvez utiliser la fonction IsObject.
Vous pouvez cr�er des �l�ments Variants qui contiennent des tableaux de variantes dans VBA � partir d�un �l�ment Range en affectant sa propri�t� Value � un �l�ment Variant. Toutes les cellules de la plage source qui sont mises en forme � l�aide du format de devise standard pour les param�tres r�gionaux en vigueur � ce moment-l� sont converties en �l�ments de tableau de type Currency. Toutes les cellules mises en forme en tant que dates sont converties en �l�ments de tableau de type Date. Les cellules contenant des cha�nes sont converties en variantes BSTR � caract�res larges. Les cellules contenant des erreurs sont converties en �l�ments Variants de type VT_ERROR. Les cellules contenant la valeur BooleanTrue ou False sont converties en variants de type VT_BOOL.
Notes
[!REMARQUE] L��l�ment Variant stocke True comme -1 et False comme 0. Les nombres non mis en forme en tant que dates ou montants en devise sont convertis en variantes de type VT_R8.
Arguments de variante et de chaîne
Excel utilise en interne des cha�nes Unicode � caract�res larges. Lorsqu�une fonction d�finie par l�utilisateur VBA est d�clar�e comme prenant un argument String, Excel convertit la cha�ne fournie en une cha�ne d�octets d�une mani�re propre aux param�tres r�gionaux. Si vous souhaitez que votre fonction soit transmise � une cha�ne Unicode, votre fonction d�finie par l�utilisateur VBA doit accepter un argument Variant au lieu d�un argument String. Votre fonction DLL peut ensuite accepter la cha�ne � caract�res larges BSTR Variant � partir de VBA.
Pour renvoyer des cha�nes Unicode � VBA � partir d�une DLL, vous devez modifier un argument de cha�ne de type Variant en place. Pour que cela fonctionne, vous devez déclarer la fonction DLL comme prenant un pointeur vers le variant et dans votre code C/C++, et déclarer l’argument dans le code VBA en tant que ByRef varg As Variant
. La m�moire de l�ancienne cha�ne doit �tre lib�r�e, et la nouvelle valeur de cha�ne cr��e � l�aide de la cha�ne BSTR OLE ne fonctionne que dans la DLL.
Pour renvoyer une cha�ne d�octets � VBA � partir d�une DLL, vous devez modifier un argument BSTR de cha�ne d�octets en place. Pour ce faire, vous devez d�clarer la fonction DLL comme prenant un pointeur vers un pointeur vers l��l�ment BSTR et dans votre code C/C++, et d�clarer l�argument dans le code VBA comme ByRef varg As String�.
Vous devez g�rer uniquement les cha�nes qui sont transmises de ces fa�ons � partir de VBA � l�aide des fonctions de cha�ne BSTR OLE pour �viter les probl�mes li�s � la m�moire. Par exemple, vous devez appeler SysFreeString pour lib�rer de la m�moire avant de remplacer la cha�ne transmise, et SysAllocStringByteLen ou SysAllocStringLen pour allouer de l�espace � une nouvelle cha�ne.
Vous pouvez cr�er des erreurs de feuille de calcul Excel en tant que Variants dans VBA � l�aide de la fonction CVerr avec des arguments, comme indiqu� dans le tableau suivant. Les erreurs de feuille de calcul peuvent �galement �tre renvoy�es � VBA � partir d�une DLL � l�aide d��l�ments Variants de type VT_ERROR, et avec les valeurs suivantes dans le champ ulVal.
Erreur | Valeur de type Variant ulVal | Argument CVerr |
---|---|---|
#NULL! |
2148141008 |
2000 |
#DIV/0! |
2148141015 |
2007 |
#VALUE! |
2148141023 |
2015 |
#REF! |
2148141031 |
2023 |
#NAME ? |
2148141037 |
2029 |
#NUM! |
2148141044 |
2036 |
#N/A |
2148141050 |
2042 |
La valeur variante ulVal indiquée équivaut à la valeur d’argument CVerr et à la valeur hexadécimale x800A0000.
Appel de fonctions DLL directement à partir de la feuille de calcul
Vous ne pouvez pas acc�der aux fonctions DLL�Win32 � partir de la feuille de calcul sans, par exemple, utiliser VBA ou XLM comme interfaces, ou sans informer Excel � l�avance de la fonction, de ses arguments et de son type de renvoi. Le processus de cette op�ration est appel� l�inscription.
Vous pouvez acc�der aux fonctions d�une DLL dans la feuille de calcul � l�aide des m�thodes suivantes�:
d�clarez la fonction dans VBA comme d�crit pr�c�demment, et acc�dez-y via une fonction d�finie par l�utilisateur VBA�;
appelez la fonction DLL � l�aide de l��l�ment CALL sur une feuille macro XLM, et acc�dez-y via une fonction d�finie par l�utilisateur XML�;
utilisez une commande XML ou VBA pour appeler la fonction REGISTER XML, qui fournit les informations dont Excel a besoin pour reconna�tre la fonction lorsqu�elle est saisie dans une cellule de feuille de calcul�;
transformez la DLL en un �l�ment XLL et inscrivez la fonction � l�aide de la fonction xlfRegister d�API�C lorsque XLL est activ�.
La quatrième approche est autonome : le code qui inscrit les fonctions et le code de fonction sont contenus dans le même projet de code. Apporter des modifications au complément n’implique pas d’apporter des modifications à une feuille XLM ou à un module de code VBA. Pour ce faire de manière bien gérée tout en restant dans les fonctionnalités de l’API C, vous devez transformer votre DLL en XLL et charger le complément résultant à l’aide du Gestionnaire de compléments. Cela permet à Excel d’appeler une fonction que votre DLL expose lorsque le complément est chargé ou activé, à partir de laquelle vous pouvez inscrire toutes les fonctions que contient votre XLL et effectuer toute autre initialisation DLL.
Appel de commandes DLL directement à partir d’Excel
Les commandes DLL�Win32 ne sont pas accessibles directement � partir des menus et bo�tes de dialogue Excel sans avoir une interface, telle que VBA, ou sans avoir inscrit les commandes � l�avance.
Vous pouvez acc�der aux commandes d�une DLL � l�aide des m�thodes suivantes :
d�clarez la commande dans VBA comme d�crit pr�c�demment, et acc�dez-y via une macro VBA�;
appelez la commande DLL � l�aide de l��l�ment CALL sur une feuille macro XLM, et acc�dez-y via une macro XML�;
utilisez une commande XML ou VBA pour appeler la fonction REGISTER XML, qui fournit les informations dont Excel a besoin pour reconna�tre la commande lorsqu�elle est saisie dans une bo�te de dialogue qui attend le nom d�une commande de macro�;
transformez la DLL en un �l�ment XLL et inscrivez la commande � l�aide de la fonction xlfRegister d�API�C.
Comme expliqu� plus haut dans le contexte des fonctions DLL, la quatri�me approche est la plus autonome, et conserve le code d�inscription proche du code de la commande. Pour r�aliser cette action, vous devez convertir votre DLL en un �l�ment XLL et charger le compl�ment obtenu � l�aide du gestionnaire de compl�ments. Le fait d�inscrire des commandes de cette fa�on vous permet �galement d�attacher la commande � un �l�ment de l�interface utilisateur, tel qu�un menu personnalis�, ou de configurer une interruption d��v�nement qui appelle la commande suite � une combinaison de touches donn�e ou � un autre �v�nement.
Toutes les commandes XLL inscrites aupr�s d�Excel sont consid�r�es comme �tant au format suivant.
int WINAPI my_xll_cmd(void)
{
// Function code...
return 1;
}
Notes
[!REMARQUE] Excel ignore la valeur de renvoi, sauf si elle est appel�e � partir d�une feuille macro XLM, auquel cas la valeur de retour est convertie en TRUE ou FALSE. Vous devez par cons�quent renvoyer 1 si votre commande a �t� ex�cut�e correctement, et 0 si elle a �chou� ou a �t� annul�e par l�utilisateur.
Mémoire DLL et instances multiples DLL
Lorsqu�une application charge une DLL, le code ex�cutable de la DLL est charg� dans le segment de m�moire global afin que vous puissiez l�ex�cuter, et de l�espace est allou� sur le segment de m�moire global pour ses structures de donn�es. Windows utilise le mappage de m�moire pour afficher ces zones de m�moire comme si elles faisaient partie du processus de l�application, de fa�on � ce que l�application puisse y acc�der.
Si une deuxi�me application charge ensuite la DLL, Windows ne r�alise pas une autre copie du code ex�cutable DLL, car cette m�moire est en lecture seule. Windows mappe la m�moire du code ex�cutable DLL aux processus des deux applications. Toutefois, il alloue un deuxi�me espace pour une copie priv�e des structures de donn�es de la DLL, et mappe cette copie au deuxi�me processus uniquement. Cela garantit qu�aucune application ne peut interf�rer avec les donn�es de la DLL de l�autre application.
Cela signifie que les d�veloppeurs DLL n�ont pas � se pr�occuper des variables statiques et globales, ni des structures de donn�es utilis�es par plusieurs applications, ou plusieurs instances de la m�me application. Chaque instance de chaque application obtient sa propre copie des donn�es de la DLL.
Les d�veloppeurs DLL doivent �tre concern�s par la m�me instance d�une application en appelant leur DLL plusieurs fois � partir de diff�rents threads, car cela peut entra�ner un conflit pour les donn�es de cette instance. Pour plus d’informations, reportez-vous à la rubrique Gestion de la mémoire dans Excel.