L'écriture (non com) compléments excel dans delphi


l'Écriture de compléments Excel avec Delphi est un projet difficile. Je montre comment il peut être fait, et de mettre en évidence les différents pièges d'attente pour le voyageur involontaire dans cet en grande partie inexploré de la frontière.
l'Écriture de compléments Excel avec Delphi est un projet difficile. Ici, je montre comment on peut le faire, et mettre en évidence les différents pièges d'attente pour le voyageur involontaire dans cet en grande partie inexploré de la frontière.
en Dépit de Microsoft apparente de l'impopularité, dans certains quartiers, Excel devrait vraiment la place sur les listes des 'meilleurs logiciels jamais créé'. Bien sûr, en prenant bien plus de dix ans pour obtenir la droite aidé. Je pense qu'une force particulière de Excel est relativement ouvert API qui permet aux développeurs de créer des macros et Visual Basic Pour Excel/VBA pour les applications.
l'Un des moins connus fonctionnalités d'Excel est add-ins. Si vous pouvez les créer à l'aide de VBA, mais vous pouvez aussi écrire à l'ajout de Dll en C et Delphi. Pour ceux qui font de développement sérieux, vous devez acheter Excel 97 Developer Kit (ISBN 1-57231-498-2) (EDK) livre, mais bien sûr, sa C/C orienté et il y a quelques pièges pour le programmeur Delphi. Dans cet article je vous montre assez pour vous allez. En tant que développeur dans un fichier Excel de l'environnement de travail que j'ai développé avec succès de nombreux add-ins avec Delphi 3, et je ne connais connais pas d'autre à faire cela. Il n'y a Financière de CAO, une entreprise Canadienne dont les add-ins peuvent être utilisés à partir de Delphi, mais je pense qu'ils sont écrits en C . Hey je suis peut-être la seule personne au monde à faire cela!
Delphi compléments assurez-il facile pour vous d'étendre Excel dans de nombreuses façons telles que la capture de données à partir des ports série, flux de données, le tout avec la vitesse de Delphi code compilé qui est considérablement plus rapide que interprétée Excel VBA. Permet de débuter, il y a beaucoup de choses à couvrir.
d'Énormes Chaînes sont une Énorme Erreur
Comme le complément est une DLL et Excel utilise de courtes chaînes de caractères, vous devez vous assurer que les grandes Chaînes option du compilateur est clair (ou $H - utilisé). Vous pourriez probablement utiliser de longues chaînes en interne, mais assurez-vous de les convertir avant de les transmettre à Excel. Pour plus de sécurité utilisation de la fonctionnalité ShortString ou String[n] où n est 1 à 255. Même si vous avez Hugestrings activé, vous pouvez utiliser string[n] pour la transmission de paramètres que ceux-ci sont toujours de type shortstring. Juste rappelez-vous la règle d'or, pas de longues chaînes de caractères dans les paramètres passés ou des dossiers.
la Reconnaissance lors de la dernière
Excel ne reconnaît que votre DLL comme un complément si certaines fonctions sont exportées. Vous devez toujours fournir ces fonctions, ainsi que celles pour l'utilisateur. Ces xlAuto famille de fonctions sont listées dans le tableau ci-dessous et documentés dans le Edk livre et dans le code d'exemple avec cet article. L'ensemble de vos fonctions exportées doivent utiliser la convention d'appel STDCALL.
& nbsp & nbsp
FunctionPurpose
xlAutoFreeCalled par Excel gratuit le Complément de la mémoire allouée.
XlAutoAddCalled lorsque le Complément est enregistré en premier.
XlAutoOpenCalled lorsque Excel charge.
XlAutoCloseCalled lorsque Excel se ferme.
XlAutoRemoveCalled lorsque le Complément est supprimé à partir d'Excel.
XlAutoRegisterOnly appelée si une fonction n'a pas été enregistré.
XlAddInManagerInfoProvides une chaîne de texte description de l'Addin.
Pour utiliser intégré dans Excel la fonction votre fonction appelle la fonction Excel Excel4V. Ceci est défini comme
fonction de Excel4v(
xlfn: mot
operRes: lpxloper
count: integer
opers: tableau de lpxloper):integer
stdcall externe 'xlcall32.dll'
xlfn est le 'numéro de Fonction' de la Excel Fonction appelée.
Operfn est le résultat et est un pointeur vers une xloper appelé lpxloper (voir la section suivante)
Count est le nombre d'éléments dans Opers.
Opers est un tableau de lpxloper, c'est à dire un tableau de pointeurs xlopers.
Remarque: Pour beaucoup de fonction que vous pouvez passer une valeur null tableau pour l'Opers paramètre. En vertu de D3, le tableau vide de construction [] n'est pas permis .comme il est en D4 donc de l'utiliser [nil] en vertu de D3.
Mon développement, l'accent a été de donner aux utilisateurs de nouvelles fonctions. Le EDK documents comment ajouter des boutons et des commandes d'Excel, mais ceux qui sont un peu plus de travail et je ne traite pas avec eux ici. Si vous souhaitez envoyer les données dans Excel, il y a deux autres approches, à la fois shareware - la TadvExcel composant est très rapide de transfert de données à l'aide de DDE. Le TxlsReadWrite lire des composants de sortie mise en forme des données et des formules directement dans un classeur Excel fichiers.
Avant de vous commencer à appeler les fonctions d'Excel, vous devez savoir à propos de la XLOper type. C'est un pascal record (struct C) environ 10 octets la taille, alignés sur 16 octets paragraphes dans des tableaux qui correspond à des cellules dans une feuille de calcul Excel. La définition est illustrée ci-dessous. Blâmer Microsoft pour le bref noms de champ. Le Tval type utilise l'ancienne pascal variante type d'enregistrement, à ne pas confondre avec Windows OLE variantes, mais utilisé d'une manière similaire. Le xltype champ de XlOper spécifie lequel des 9 types utilisés est en jeu. Donc, si le xloper a un type de 1, val.num a un double précision valide nombre.
j'ai trouvé que les types 1, 2 et 8 sont les plus utilisés. Le Type 4 est renvoyée par Excel lorsque vous obtenez quelque chose de mal. Il y a un type integer (5), mais num (1) semble beaucoup plus commun. Le Type 6 est utilisé pour des gammes, de type 9 pour les collections de séparer les cellules où vous maintenez la touche Ctrl enfoncée lors de la sélection de cellules. Il n'y a pas de type 7.
Xloper Définition
TVal = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Cas de l'Octet de
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 1: (num: Double) (* xltypeNum *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 2: (str: ^ShortString) (* xltypeStr *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 3: (bool: Word) (* xltypeBool *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 4: (err: Word) (* xltypeErr *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 5: (w: Integer) (* xltypeInt *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 6: (sref : emballé enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp comte:mot
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ref: Xlref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 8: (_array : paniers d'Enregistrement (* xltypeMulti *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lparray: LPXLOPERArray
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lignes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp colonnes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 9: (mref : paniers d'enregistrement / de/ xltyperef
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lpmref : lpxlmref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp idsheet : entier
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin // tval
& nbsp & nbsp XlOper = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp val: TVal
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp xltype: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mannequin:array[0..5] de byte // plaquettes de 16 octets taille
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin
lpxloper = ^xloper
Problème avec Excel appels
à Partir de Delphi la grosse pierre d'achoppement avec les add-ins) est le paramètre supplémentaire après l'adresse de retour sur la pile. C'est livré gratuitement avec chaque appel à Excel. Je n'ai jamais trouvé ce qu'il détient, mais aussi longtemps que vous le jeter, votre add-in ne fonctionne correctement. Ajoutez la ligne de l'asm pop variable fin après chaque appel où la variable peut être à l'échelle mondiale, locale ou variable objet qui est d'au moins 4 octets entier long est très bien. Pour le répète, CE DOIT ÊTRE INCLUS après chaque Excel4v appel. Sinon, vous êtes en train de construire une bombe à retardement.
Exemple
Eresult:= Excel4V(xlfCaller,@xres,0,[nil])
asm pop évier fin // ne Jamais Enlever
Notez qu'avec Delphi syntaxe, si xres est un xloper, vous pouvez utiliser @xres de définir un lpxloper.
Attention - Recalcul d'Alerte!
Si les entrées de votre fonction sont calculées en quelque sorte, votre code doit vérifier l'état de l'Excel appel (Eresult dans l'exemple ci-dessus) ainsi que le résultat de la fonction Excel appel qui sera en xres ci-dessus. Rappelez-vous, vous appelez Excel4V de licences d'accès client la fonction spécifiée.
Eresult donne 0 si ok, ou un ensemble de bits pour indiquer des erreurs. Vous devez toujours gérer les valeurs 1 et 64. 1 est xlabort indiquant que l'utilisateur appuie sur la touche esc. 64 est un imprévue de la cellule de référence. Ce n'est pas une erreur, mais il arrive lorsque votre fonction utilise des fonctions ou des calculs sur la feuille de calcul qui sont complètement évalués à l'issue de votre routine est appelée en premier. Si cela se produit, vous code doit libérer toute la mémoire déjà allouée à l'appel et à la sortie. Excel va appeler votre fonction.
& nbsp
Structure de votre code comme ceci
1. Obtenir les Paramètres d'Entrée
2. Si une erreur 64 ou 1 (abandon de la clé) se produit, la sortie après la libération de la mémoire déjà allouée (le cas échéant) dans cette fonction.
3. Faire fonction principale de traitement.
Si l'étape 3 va être très coûteuse en temps, en disent plus que le 1/10ème de seconde, votre code doit vérifier l'abandon d'état en appelant xlAbort périodiquement.
Démarrage
Lorsque le complément est d'abord ajouté à Excel, chacune des fonctions exportées doivent être enregistrés. Cela implique l'appel de l'Excel Registre de routine pour chaque routine. Il y a huit paramètres passés comme XlOpers.
ParameterTypeUse
Module de textStringFull nom de la DLL avec chemin d'accès
ProcedureString ou numberFunction nom ou le numéro à appeler
Type de TextStringArgument et types de retour
Fonction de TextStringFunction nom dans l'Assistant fonction
l'Argument TextStringOptional Chaîne de Texte qui décrit les paramètres dans l'Assistant fonction
Macro TypeNumber0,1, ou 2
CategoryString ou NumberCategory en vertu de la fonction qui s'affiche
Raccourci TextStringOnly utilisé pour les commandes, passer la valeur null pour la fonction
le paramètre Le plus important pour vous inscrire est le type de texte. Il utilise les lettres A-R pour représenter la valeur de retour et les paramètres fournis. Les valeurs sont passées comme vous pouvez vous attendre dans un Api C par référence (c'est à dire de l'aiguille qui est toujours un lpxloper) ou par valeur.
E. g. la feuille de calcul Excel =MyFunction(a1:b1) passe une référence tout =obligation à taux d'intérêt('GBP') utilise une valeur.
Exemple
& ! & ! & ! & nbsp DLLName :=GetName // fonction pour renvoyer le nom/chemin d'accès à partir d'Excel
& ! & ! & ! & nbsp pxModuleText.SetStr(s) // Remarque (1)
& ! & ! & ! & nbsp pxProcedure.SetStr('AddDate') // Nom de la Fonction
& ! & ! & ! & nbsp pxTypeText.SetStr('JJDD!') // (2) le Type de Retour = J, Entrée = JDD
& ! & ! & ! & nbsp pxFunctionText.setStr('AddDate') // Nom de Fx Assistant
& ! & ! & ! & nbsp pxArgumentText.SetStr('Date,Période,la Monnaie') / / Parm texte dans le FX Wiz
& ! & ! & ! & nbsp pxMacrotype.SetNum(1) // Type = Sinmple func(3)
& ! & ! & ! & nbsp pxCategory.SetStr(AddInCategory) // Catégorie de la touche Func. wiz
& ! & ! & ! & nbsp EResult:=Excel4V(xlfregister,@res,8, // Passer à 8 parms
& ! & ! & ! & ! & ! & nbsp [pxModuletext.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxProcedure.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxTypeText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxFunctionText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxArgumentText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxMacroType.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxCategory.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp zlpxloper]) // Null
& nbsp & nbsp & nbsp asm pop évier fin // ne Jamais Enlever
& nbsp & nbsp & nbsp Résultat := trunc(res.val.num) // Code d'identification (4)
Le px variables sont toutes les txloper classe qui simplifie l'initialisation xlopers.
Notes
(1) Le DLLName et le chemin d'accès doit être obtenu à partir d'Excel, via le XlGetName fonction vous pouvez le voir utilisé dans l'exemple de code. Ne pas coder en dur elle car elle contient le chemin d'accès.
(2) Voir Registre (page 219 dans EdK) pour de plus amples informations de Type Texte. Le premier paramètre est le paramètre de retour (J=un entier de 32 bits) les 3 sont des entrées (JDD = Integer, String, String) et le ! signifie que Excel appelle toujours quand il recalcule. Sans! Excel appelle la fonction une fois, les loquets le résultat et utilise les verrouillé suite à des appels ultérieurs.
(3) de Type 1 = Fonction. D'autres types comprennent non cotées de la fonction (type 0) et les commandes (de type 2). Si vous souhaitez des fonctions qui n'apparaissent pas dans l'Assistant Fonction, utilisez 0.
(4) Après le succès de l'enregistrement, la valeur numérique res (res.val.num) contient un entier identifiant de code pour cette fonction, - la poignée. Enregistrer et passer à la suppression de l'inscription de la fonction lorsque la DLL est fermé. Oublier cela et vous aurez de la difficulté à utiliser des versions plus récentes de la bibliothèque..
Pour les Valeurs à partir d'une feuille de calcul Excel
les Valeurs peuvent être transmis, de trois façons.
1. Comme dans le passé par valeur. Eg =CalcMean(4,5,8) xltypenum ou xltypestr
2. Par une Simple référence, disons un la cellule a1 ou de la plage a3:b56. xltypesref
3. Comme un composite de Référence. Essentiellement une collection de disjoint des références de cellule. xltypemref
1 et 2 sont les plus courants. 3 est un peu bizarre, et, sauf si vraiment nécessaire, il est préférable de filtre. Si vous voulez l'utiliser, l'entrée est un tableau de références de cellule (type 2), de sorte que vous avez à les utiliser.
Excel va filtrer le type de données si vous spécifiez (nombre, chaîne de caractères, etc), mais si vous attendez une gamme, alors vous devriez pleinement vérifier le type et l'étendue des valeurs, des erreurs de déclaration, le cas échéant..
le Retour d'Erreurs
Votre fonction doit retourner un lpxloper (type R) si vous souhaitez retourner Excel codes d'Erreur. Pour définir une erreur dans Res (une xloper) il suffit de faire
res.xltype := xltypeerr
res.val.err := nombre de // retourne les valeurs suivantes, puis juste retour de @res de votre fonction
NumberExcel Err
0#NULL
7#DIV/0
15#la VALEUR
23#REF
29#NOM
36#NUM
42#N/A
Avec compliquées, beaucoup de paramètre de fonctions, je pense que excel standard erreurs sont un peu hostile et donc, je vous suggère fortement un GetlastError() fonction qui retourne la dernière erreur de chaîne de caractères. Toute fonction qui retourne une erreur doit définir la chaîne d'erreur renvoyé par GetLastError(). Cela permettra aux utilisateurs d'économiser beaucoup de temps lors de l'utilisation des fonctions pour la première fois.
la Lecture des Valeurs de Cellule
après Avoir été passé à une référence de cellule (xltypeSref) vous voulez obtenir les valeurs contenues dans les cellules. Pour ce faire, vous devez 'forcer' la référence de la cellule xloper. Ce forcer (une fonction Excel) et les forces de Excel pour construire un vecteur de xlopers, avec exactement (#Lignes * #Cols) xlopers. C'est à dire pour un 2 x 3 tableau de cellules, vous obtenez six xlopers. La cible xloper devient un en-tête avec le xltype champ = 64 (xltypearray). Le val._array membre contient le nombre de lignes et de colonnes et un pointeur vers le corps xloper.
Ces xlopers sont disposés en ligne de commande afin de les six cellules en deux lignes sur 3 colonnes est stockée en tant que
1 2 3
4 5 6
Chacun aura le type fondamental (xltype num ou Str) et de la valeur.
Exemple de Contrainte
Desttype.xltype := xltypeInt
Desttype.val.w := xltypeMulti
Eresult := Excel4v(xlcoerce,@Xval,2,[Valeurs,@desttype])
asm pop évier fin // ne Jamais Enlever
& nbsp & nbsp
Le xlopers/lpxlopers utilisés ici sont
Desttype - Un xloper qui spécifie la coercition type de destination (xltypemulti - Excelle nom pour un tableau de xlopers)
les Valeurs Du passé dans la cellule de référence - un lpxloper
Xval - La cible xloper. Après avoir réussi à forcer, c'est l'en-tête d'un tableau. Avec les 2 x 3 tableau, il y aura six xlopers, chacune ayant une valeur de cellule.
Excel a alloué la mémoire sur votre compte et ce qui doit être fait, mais plus sur cela plus tard..
Exemple d'utilisation de l'valeurs
Cet exemple vérifie l'
si xval.val._array.les lignes<>1 then
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Erreur('ne Devrait avoir qu'une ligne')
& ! & ! & ! & nbsp goto myexit
& nbsp & nbsp fin
xlar := xval.val._array.lparray
indice:=0
col:= 1 to xr.NumCols ne
& nbsp & nbsp commencer
& ! & ! & ! & nbsp si xlar^[index].xltype <> xltypenum puis
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp Erreur ('Élément' inttostr(ligne), 'Pas un nombre')
& ! & ! & ! & ! & ! & ! & ! & nbsp pause
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp Valeur[col] := xlar^[index].val.num
& ! & ! & ! & nbsp inc(index)
& nbsp & nbsp fin
xlar est un pointeur vers un tableau de xlopers. Dans cet exemple vérifie qu'il existe une ligne de données non numériques. Puis il copie les valeurs dans la Valeur de tableau [].
Mettre des valeurs dans des Cellules Excel
Bien qu'il existe un équivalent (en quelque sorte) de xlcoerce, appelé xlset, il ne peut être appelé à partir d'une commande de menu ou un bouton de barre d'outils) et non pas à partir d'une fonction. Son très anti-social, de toute façon viens de vider un tas de valeurs dans une feuille de calcul, il pourrait simplement remplacer un matin de travail non enregistrées et ne fait pas qu'améliorer votre popularité!
l'Un n'est pas si bien connu de la Excel Fonction appelée Tableaux (ou une formule tableaux) est ce qui est nécessaire. Si vous n'êtes pas familier avec eux, essayez ceci sur un vide de la feuille Excel.
1. Sélectionnez une zone rectangulaire avec la souris. Maintenant, cliquez sur le montage de la ligne (juste en dessous de la barre d'outils, au-dessus des cellules) et tapez =g1. À ce stade, vous devriez voir =g1 dans la ligne d'édition et de la zone sélectionnée doit toujours être sélectionné. Si vous avez désactivé la sélection par erreur, revenez en arrière et essayez à nouveau.
2. Maintenant, maintenez les touches ctrl et maj enfoncées et appuyez sur entrée. L' =g1 doit être collé dans toutes les cellules de la zone sélectionnée.
Vous devez également remarquer certaines choses à ce sujet si vous cliquez sur une cellule dans ce domaine.
1. La ligne d'édition montre l'équation entre parenthèses.
2. Vous ne pouvez pas modifier ou effacer la cellule.
3. Il n'a pas régler la référence de la cellule.
C'est le seul moyen (pour autant que j'ai pu faire) pour mettre des valeurs dans des cellules Excel. Votre fonction excel doit construire un tableau de xlopers, avec l'en-tête pointant vers le corps. Si votre fonction renvoie un tableau, vous devez utiliser une Fonction de Tableau pour afficher le résultat. Excel est tout à fait à l'aise avec cela. Si vous retournez un 3 x 5 domaine et l'utilisateur colle une Fonction de la Matrice de 4 x 6 rectangle, le supplément dans les cellules de tous show N/A.
la Gestion de la Mémoire
Si un Excel4v appel renvoie un xloper avec un pointeur (chaînes ou xltypemulti par exemple) puis, lorsque votre code a fini avec la valeur de votre code doit toujours faire appel à xlfree sur le xloper. En fait, en règle générale, l'appel de xlfree sur toute xloper ne pas nuire à tous.
Il y a deux allocation de mémoire cas que votre code DOIT gérer..
1. Vous avez appelé une routine qui renvoie un xloper avec les données qu'il contient, par exemple, xlcoerce pour convertir un xltypesref/xltyperef à un xltypemulti (tableau). Excel attribue à sa propre mémoire et lorsque vous avez terminé avec les données, vous devez OU dans la valeur de $1000 (4096 décimal) à la xltype - ce 1000 $de la valeur est connue en tant que xlbitXLfree. Lorsque vous appelez xlfree, il libère de l' 'Excel alloué la mémoire.
2. Si votre code renvoie un tableau de xlopers qui, Excel affiche comme une fonction de tableau, vous devez vous OU dans la valeur de 4 000 $(16384 décimal) à la xltype champ, avant que la fonction se termine. Après avoir copié les valeurs Excel va faire un rappel à votre xlAutoFree fonction (vous n'en œuvre n'est-ce pas?) avec un lpxloper à vos données. Vous pouvez ensuite gratuit. Si vous avez créé un tableau à n éléments (n 1) xlopers, où nom_tableau[0] est l'en-tête qui pointe vers nom_tableau[1] alors que le pointeur retourné points de nom_tableau[0] et freemem(retour d'appel pointeur) sera alors libre de les corriger pointeur.
Un exemple De complément
L'exemple qui accompagne cet article est autonome dans environ 650 lignes de code sans non delphi de composants ou d'unités nécessaires. Il implémente une Fonction de Distribution Cumulée GetCDF qui prend un nombre dans la plage de -4 à 4 en entrée et renvoie la hauteur en vertu de l'ogive de la courbe. Je sais que Excel est livré avec plusieurs Normal des fonctions de distribution, mais il sert d'exemple. Il a été testé sur Excel 95 et 97 avec Delphi 3 sur win 95/98 et NT, et s'est avéré être solide comme un roc. Je ne peux pas souligner à quel point il est important de vérifier toutes les entrées et essayer et obtenir votre code aussi robuste que possible. Rien de méchant sera probablement à la bombe ou à accrocher Excel et les utilisateurs vont rapidement devenir des agresseurs. N'oubliez pas le Stdcalls sur toutes les fonctions exportées!
en dehors de l'obligation de xlauto famille de fonctions, il comprend cinq autres fonctions, dont deux sont invisibles. Ces deux GetXlStack et FreeRam sont destinées à l'utilisation par le développeur. Les trois autres (GetCDF, LastError et Version) sont destinés à l'utilisateur. Vous pouvez utiliser les deux types de fonctions directement, mais seulement à ceux qui sont visibles seront vus dans l'Assistant Fonction. Et n'oubliez pas les crochets sur les appels de fonction. Excel sera heureux =Version (sans ()) et renvoie une valeur de -30408699 (je n'en ai aucune idée) quand vous entendre =Version().
j'ai inclus seulement le principal excel numéros de fonction utilisé dans le programme, la liste complète de près de 400. La CDIP a l'ensemble du lot et comprend C-têtes qui peuvent facilement être modifiée.
c'est un peu démodé, non-OOP programme. J'ai choisi de cette façon, à l'origine, comme je me sentais de mon chemin de ronde, les compléments excel, et je ne voulais pas avoir de problèmes avec les Objets en même temps. La seule classe que j'ai utilisé ici est Txloper pour simplifier la création de Xlopers mais c'était pour garder concis. Envoyer vos requêtes et les offres de travail à [email protected].
Le fichier ci-dessous est complet - source pour une dll. Assurez-vous que l'extension est .xll

{$A ,B,C ,D ,E,F,G ,H,I ,J ,K,L ,M,N ,O,P ,Q ,R,S,T,U,V ,W ,X ,Y,Z1}
bibliothèque cdfcalc

& nbsp & nbsp SysUtils,
& nbsp & nbsp windows,
& nbsp & nbsp dialogues,
& nbsp & nbsp formes,
& nbsp & nbsp Classes,
& nbsp & nbsp Math
// XLREF structure
& nbsp & nbsp type xlref = paniers enregistrement
& ! & ! & ! & ! & nbsp rwFirst : smallint
& ! & ! & ! & ! & nbsp rwLast : smallint
& ! & ! & ! & ! & nbsp colFirst : octet
& ! & ! & ! & ! & nbsp colLast : byte
& nbsp & nbsp fin
& nbsp & nbsp // Renvoie une plage de sélection
& nbsp & nbsp XlRangeRecord = paniers enregistrement
& ! & ! & ! & ! & nbsp Count : mot // doit toujours être $1
& ! & ! & ! & ! & nbsp Sref : xlref
& nbsp & nbsp fin
& nbsp & nbsp xlmref= paniers enregistrement
& ! & ! & ! & ! & ! & ! & ! & nbsp count : mot
& ! & ! & ! & ! & ! & ! & ! & nbsp RefTbl : array[0..1000] de XlRef
& nbsp & nbsp fin
& nbsp & nbsp lpxloper = ^XLOPER
& nbsp & nbsp lpxloperArray = ^XLArray
& nbsp & nbsp lpxlmref = ^xlmref
& nbsp & nbsp TVal = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Cas de l'Octet de
& ! & ! & ! & nbsp & ! & ! & ! & ! & ! & ! & nbsp 1: (num : Double) // xltypeNum
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 2: (str : ^ShortString) // xltypeStr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 3: (bool : Word) // xltypeBool
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 4: (err : Mot) // xltypeErr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 5: (w : Integer) // xltypeInt
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 6: (sref : emballé enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Comte : mot
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ref : Xlref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 8: (_array : paniers d'Enregistrement / de/ xltypeMulti
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lparray: lpxloperArray
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lignes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp colonnes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 9: (mref : paniers d'enregistrement / de/ xltyperef
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lpmref : lpxlmref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp idsheet : entier
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin // tval
& nbsp & nbsp XLOPER = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp val : TVal
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp xltype : MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mannequin:array[0..5] de byte // remplissage
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin
xlarray=array[0..1000] de xloper
lpxlarray=^xlarray
txloper = la classe // Simple xloper classe de soutien
& nbsp & nbsp privé
& ! & ! & ! & nbsp fxloper : xloper
& ! & ! & ! & nbsp fActualStr : ShortString
& ! & ! & ! & nbsp fonction Getlpxloper:lpxloper
& nbsp & nbsp public
& ! & ! & ! & nbsp constructeur Créer

& ! & ! & ! & nbsp Destructeur de Détruire remplacer
& ! & ! & ! & nbsp Constructeur Create_Str(NewStr : ShortString)
& ! & ! & ! & nbsp procédure SetStr(NewStr : ShortString)
& ! & ! & ! & nbsp procédure SetNum(NewNumber : Entier)
& ! & ! & ! & nbsp procédure SetInt(NewNumber : Entier)
& ! & ! & ! & nbsp procédure SetErr
& ! & ! & ! & nbsp propriété thelpxloper : lpxloper lire Getlpxloper
fin
// Excel
fonction de Excel4v(xlfn:word operRes:lpxloper count:integer opers:tableau de lpxloper):integer
stdcall externe 'xlcall32.dll'
// XLMREF structure Décrit plusieurs rectangulaire références.
const
& nbsp xltypeNum = $0001
& nbsp xltypeStr = $0002
& nbsp xltypeBool = $0004
& nbsp xltypeRef = $0008
& nbsp xltypeErr = $0010
& nbsp xltypeFlow = $0020
& nbsp xltypeMulti = $0040
& nbsp xltypeMissing = $0080
& nbsp xltypeNil = $0100
& nbsp xltypeSRef = $0400
& nbsp xltypeInt = $0800
& nbsp xlbitXLFree = $1000
& nbsp xlbitDLLFree = $4000
& nbsp xltypeBigData =xltypeStr ou xltypeInt
// codes d'Erreur Utilisé pour val.err champ de XLOPER structure
& nbsp xlerrNull =0
& nbsp xlerrDiv0 =7
& nbsp xlerrValue =15
& nbsp xlerrRef =23
& nbsp xlerrName =29
& nbsp xlerrNum =36
& nbsp xlerrNA =42
// les codes de Retour
& nbsp xlretSuccess =0 // succès
& nbsp xlretAbort =1 // macro stoppé
& nbsp xlretInvXlfn =2 // fonction non valide
& nbsp xlretInvCount =4 // nombre d'arguments incorrect
& nbsp xlretInvXloper =8 // invalide OPER de la structure
& nbsp xlretStackOvfl =16 // stack overflow
& nbsp xlretFailed =32 // echec de la commande
& nbsp xlretUncalced =64 // uncalced cellulaire
// Fonction du nombre de bits
& nbsp xlCommand = $8000
& nbsp xlSpecial = $4000
& nbsp xlIntl = $2000
& nbsp xlPrompt = $1000
// fonction Spéciale numéros
& nbsp xlFree =(0 ou xlspecial)
& nbsp xlStack =(1 ou xlspecial)
& nbsp xlCoerce =(2 ou xlspecial)
& nbsp xlSet =(3 ou xlspecial)
& nbsp xlSheetId =(4 ou xlspecial)
& nbsp xlSheetNm =(5 ou xlspecial)
& nbsp xlAbort =(6 ou xlspecial)
& nbsp xlGetInst =(7 ou xlspecial)
& nbsp xlGetHwnd =(8 ou xlspecial)
& nbsp xlGetName =(9 ou xlspecial)
& nbsp xlEnableXLMsgs =(10 ou xlspecial)
& nbsp xlDisableXLMsgs =(11 ou xlspecial)
& nbsp xlDefine inaryName =(12 ou xlspecial)
& nbsp xlGetBinaryName =(13 ou xlspecial)
// fonctions définies par l'Utilisateur, nécessaire pour appeler les fonctions d'Excel
& nbsp & nbsp xlfCaller=89
& nbsp & nbsp xlfRegister=149
& nbsp & nbsp xlfUnregister=201
//
& nbsp & nbsp DLLversion:shortstring='CDF Calc V1.02'
& nbsp & nbsp AddInCategory='CDF Calculatrice'
& nbsp & nbsp const zlpxloper=lpxloper(nil)
& nbsp & nbsp type retarray=array[0..1000] de xloper
& nbsp & nbsp pretarray=^retarray
var // données Globales
& nbsp & nbsp res : xloper
& nbsp & nbsp GetCDF_Id : Entier
& nbsp & nbsp xlStack_Id : Integer
& nbsp & nbsp EResult : Integer
& nbsp & nbsp évier : integer
& nbsp & nbsp GetStack_Id : Integer
& nbsp & nbsp LastError_Id :








L'ecriture (non com) complements excel dans delphi


L'ecriture (non com) complements excel dans delphi : Plusieurs milliers de conseils pour vous faciliter la vie.


l'Ecriture de complements Excel avec Delphi est un projet difficile. Je montre comment il peut etre fait, et de mettre en evidence les differents pieges d'attente pour le voyageur involontaire dans cet en grande partie inexplore de la frontiere.
l'Ecriture de complements Excel avec Delphi est un projet difficile. Ici, je montre comment on peut le faire, et mettre en evidence les differents pieges d'attente pour le voyageur involontaire dans cet en grande partie inexplore de la frontiere.
en Depit de Microsoft apparente de l'impopularite, dans certains quartiers, Excel devrait vraiment la place sur les listes des 'meilleurs logiciels jamais cree'. Bien sûr, en prenant bien plus de dix ans pour obtenir la droite aide. Je pense qu'une force particuliere de Excel est relativement ouvert API qui permet aux developpeurs de creer des macros et Visual Basic Pour Excel/VBA pour les applications.
l'Un des moins connus fonctionnalites d'Excel est add-ins. Si vous pouvez les creer a l'aide de VBA, mais vous pouvez aussi ecrire a l'ajout de Dll en C et Delphi. Pour ceux qui font de developpement serieux, vous devez acheter Excel 97 Developer Kit (ISBN 1-57231-498-2) (EDK) livre, mais bien sûr, sa C/C oriente et il y a quelques pieges pour le programmeur Delphi. Dans cet article je vous montre assez pour vous allez. En tant que developpeur dans un fichier Excel de l'environnement de travail que j'ai developpe avec succes de nombreux add-ins avec Delphi 3, et je ne connais connais pas d'autre a faire cela. Il n'y a Financiere de CAO, une entreprise Canadienne dont les add-ins peuvent etre utilises a partir de Delphi, mais je pense qu'ils sont ecrits en C . Hey je suis peut-etre la seule personne au monde a faire cela!
Delphi complements assurez-il facile pour vous d'etendre Excel dans de nombreuses façons telles que la capture de donnees a partir des ports serie, flux de donnees, le tout avec la vitesse de Delphi code compile qui est considerablement plus rapide que interpretee Excel VBA. Permet de debuter, il y a beaucoup de choses a couvrir.
d'Enormes Chaînes sont une Enorme Erreur
Comme le complement est une DLL et Excel utilise de courtes chaînes de caracteres, vous devez vous assurer que les grandes Chaînes option du compilateur est clair (ou $H - utilise). Vous pourriez probablement utiliser de longues chaînes en interne, mais assurez-vous de les convertir avant de les transmettre a Excel. Pour plus de securite utilisation de la fonctionnalite ShortString ou String[n] ou n est 1 a 255. Meme si vous avez Hugestrings active, vous pouvez utiliser string[n] pour la transmission de parametres que ceux-ci sont toujours de type shortstring. Juste rappelez-vous la regle d'or, pas de longues chaînes de caracteres dans les parametres passes ou des dossiers.
la Reconnaissance lors de la derniere
Excel ne reconnaît que votre DLL comme un complement si certaines fonctions sont exportees. Vous devez toujours fournir ces fonctions, ainsi que celles pour l'utilisateur. Ces xlAuto famille de fonctions sont listees dans le tableau ci-dessous et documentes dans le Edk livre et dans le code d'exemple avec cet article. L'ensemble de vos fonctions exportees doivent utiliser la convention d'appel STDCALL.
& nbsp & nbsp
FunctionPurpose
xlAutoFreeCalled par Excel gratuit le Complement de la memoire allouee.
XlAutoAddCalled lorsque le Complement est enregistre en premier.
XlAutoOpenCalled lorsque Excel charge.
XlAutoCloseCalled lorsque Excel se ferme.
XlAutoRemoveCalled lorsque le Complement est supprime a partir d'Excel.
XlAutoRegisterOnly appelee si une fonction n'a pas ete enregistre.
XlAddInManagerInfoProvides une chaîne de texte description de l'Addin.
Pour utiliser integre dans Excel la fonction votre fonction appelle la fonction Excel Excel4V. Ceci est defini comme
fonction de Excel4v(
xlfn: mot
operRes: lpxloper
count: integer
opers: tableau de lpxloper):integer
stdcall externe 'xlcall32.dll'
xlfn est le 'numero de Fonction' de la Excel Fonction appelee.
Operfn est le resultat et est un pointeur vers une xloper appele lpxloper (voir la section suivante)
Count est le nombre d'elements dans Opers.
Opers est un tableau de lpxloper, c'est a dire un tableau de pointeurs xlopers.
Remarque: Pour beaucoup de fonction que vous pouvez passer une valeur null tableau pour l'Opers parametre. En vertu de D3, le tableau vide de construction [] n'est pas permis .comme il est en D4 donc de l'utiliser [nil] en vertu de D3.
Mon developpement, l'accent a ete de donner aux utilisateurs de nouvelles fonctions. Le EDK documents comment ajouter des boutons et des commandes d'Excel, mais ceux qui sont un peu plus de travail et je ne traite pas avec eux ici. Si vous souhaitez envoyer les donnees dans Excel, il y a deux autres approches, a la fois shareware - la TadvExcel composant est tres rapide de transfert de donnees a l'aide de DDE. Le TxlsReadWrite lire des composants de sortie mise en forme des donnees et des formules directement dans un classeur Excel fichiers.
Avant de vous commencer a appeler les fonctions d'Excel, vous devez savoir a propos de la XLOper type. C'est un pascal record (struct C) environ 10 octets la taille, alignes sur 16 octets paragraphes dans des tableaux qui correspond a des cellules dans une feuille de calcul Excel. La definition est illustree ci-dessous. Blamer Microsoft pour le bref noms de champ. Le Tval type utilise l'ancienne pascal variante type d'enregistrement, a ne pas confondre avec Windows OLE variantes, mais utilise d'une maniere similaire. Le xltype champ de XlOper specifie lequel des 9 types utilises est en jeu. Donc, si le xloper a un type de 1, val.num a un double precision valide nombre.
j'ai trouve que les types 1, 2 et 8 sont les plus utilises. Le Type 4 est renvoyee par Excel lorsque vous obtenez quelque chose de mal. Il y a un type integer (5), mais num (1) semble beaucoup plus commun. Le Type 6 est utilise pour des gammes, de type 9 pour les collections de separer les cellules ou vous maintenez la touche Ctrl enfoncee lors de la selection de cellules. Il n'y a pas de type 7.
Xloper Definition
TVal = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Cas de l'Octet de
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 1: (num: Double) (* xltypeNum *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 2: (str: ^ShortString) (* xltypeStr *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 3: (bool: Word) (* xltypeBool *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 4: (err: Word) (* xltypeErr *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 5: (w: Integer) (* xltypeInt *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 6: (sref : emballe enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp comte:mot
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ref: Xlref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 8: (_array : paniers d'Enregistrement (* xltypeMulti *)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lparray: LPXLOPERArray
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lignes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp colonnes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 9: (mref : paniers d'enregistrement / de/ xltyperef
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lpmref : lpxlmref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp idsheet : entier
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin // tval
& nbsp & nbsp XlOper = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp val: TVal
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp xltype: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mannequin:array[0..5] de byte // plaquettes de 16 octets taille
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin
lpxloper = ^xloper
Probleme avec Excel appels
a Partir de Delphi la grosse pierre d'achoppement avec les add-ins) est le parametre supplementaire apres l'adresse de retour sur la pile. C'est livre gratuitement avec chaque appel a Excel. Je n'ai jamais trouve ce qu'il detient, mais aussi longtemps que vous le jeter, votre add-in ne fonctionne correctement. Ajoutez la ligne de l'asm pop variable fin apres chaque appel ou la variable peut etre a l'echelle mondiale, locale ou variable objet qui est d'au moins 4 octets entier long est tres bien. Pour le repete, CE DOIT ETRE INCLUS apres chaque Excel4v appel. Sinon, vous etes en train de construire une bombe a retardement.
Exemple
Eresult:= Excel4V(xlfCaller,@xres,0,[nil])
asm pop evier fin // ne Jamais Enlever
Notez qu'avec Delphi syntaxe, si xres est un xloper, vous pouvez utiliser @xres de definir un lpxloper.
Attention - Recalcul d'Alerte!
Si les entrees de votre fonction sont calculees en quelque sorte, votre code doit verifier l'etat de l'Excel appel (Eresult dans l'exemple ci-dessus) ainsi que le resultat de la fonction Excel appel qui sera en xres ci-dessus. Rappelez-vous, vous appelez Excel4V de licences d'acces client la fonction specifiee.
Eresult donne 0 si ok, ou un ensemble de bits pour indiquer des erreurs. Vous devez toujours gerer les valeurs 1 et 64. 1 est xlabort indiquant que l'utilisateur appuie sur la touche esc. 64 est un imprevue de la cellule de reference. Ce n'est pas une erreur, mais il arrive lorsque votre fonction utilise des fonctions ou des calculs sur la feuille de calcul qui sont completement evalues a l'issue de votre routine est appelee en premier. Si cela se produit, vous code doit liberer toute la memoire deja allouee a l'appel et a la sortie. Excel va appeler votre fonction.
& nbsp
Structure de votre code comme ceci
1. Obtenir les Parametres d'Entree
2. Si une erreur 64 ou 1 (abandon de la cle) se produit, la sortie apres la liberation de la memoire deja allouee (le cas echeant) dans cette fonction.
3. Faire fonction principale de traitement.
Si l'etape 3 va etre tres coûteuse en temps, en disent plus que le 1/10eme de seconde, votre code doit verifier l'abandon d'etat en appelant xlAbort periodiquement.
Demarrage
Lorsque le complement est d'abord ajoute a Excel, chacune des fonctions exportees doivent etre enregistres. Cela implique l'appel de l'Excel Registre de routine pour chaque routine. Il y a huit parametres passes comme XlOpers.
ParameterTypeUse
Module de textStringFull nom de la DLL avec chemin d'acces
ProcedureString ou numberFunction nom ou le numero a appeler
Type de TextStringArgument et types de retour
Fonction de TextStringFunction nom dans l'Assistant fonction
l'Argument TextStringOptional Chaîne de Texte qui decrit les parametres dans l'Assistant fonction
Macro TypeNumber0,1, ou 2
CategoryString ou NumberCategory en vertu de la fonction qui s'affiche
Raccourci TextStringOnly utilise pour les commandes, passer la valeur null pour la fonction
le parametre Le plus important pour vous inscrire est le type de texte. Il utilise les lettres A-R pour representer la valeur de retour et les parametres fournis. Les valeurs sont passees comme vous pouvez vous attendre dans un Api C par reference (c'est a dire de l'aiguille qui est toujours un lpxloper) ou par valeur.
E. g. la feuille de calcul Excel =MyFunction(a1:b1) passe une reference tout =obligation a taux d'interet('GBP') utilise une valeur.
Exemple
& ! & ! & ! & nbsp DLLName :=GetName // fonction pour renvoyer le nom/chemin d'acces a partir d'Excel
& ! & ! & ! & nbsp pxModuleText.SetStr(s) // Remarque (1)
& ! & ! & ! & nbsp pxProcedure.SetStr('AddDate') // Nom de la Fonction
& ! & ! & ! & nbsp pxTypeText.SetStr('JJDD!') // (2) le Type de Retour = J, Entree = JDD
& ! & ! & ! & nbsp pxFunctionText.setStr('AddDate') // Nom de Fx Assistant
& ! & ! & ! & nbsp pxArgumentText.SetStr('Date,Periode,la Monnaie') / / Parm texte dans le FX Wiz
& ! & ! & ! & nbsp pxMacrotype.SetNum(1) // Type = Sinmple func(3)
& ! & ! & ! & nbsp pxCategory.SetStr(AddInCategory) // Categorie de la touche Func. wiz
& ! & ! & ! & nbsp EResult:=Excel4V(xlfregister,@res,8, // Passer a 8 parms
& ! & ! & ! & ! & ! & nbsp [pxModuletext.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxProcedure.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxTypeText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxFunctionText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxArgumentText.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxMacroType.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp pxCategory.thelpxloper,
& ! & ! & ! & ! & ! & ! & nbsp zlpxloper]) // Null
& nbsp & nbsp & nbsp asm pop evier fin // ne Jamais Enlever
& nbsp & nbsp & nbsp Resultat := trunc(res.val.num) // Code d'identification (4)
Le px variables sont toutes les txloper classe qui simplifie l'initialisation xlopers.
Notes
(1) Le DLLName et le chemin d'acces doit etre obtenu a partir d'Excel, via le XlGetName fonction vous pouvez le voir utilise dans l'exemple de code. Ne pas coder en dur elle car elle contient le chemin d'acces.
(2) Voir Registre (page 219 dans EdK) pour de plus amples informations de Type Texte. Le premier parametre est le parametre de retour (J=un entier de 32 bits) les 3 sont des entrees (JDD = Integer, String, String) et le ! signifie que Excel appelle toujours quand il recalcule. Sans! Excel appelle la fonction une fois, les loquets le resultat et utilise les verrouille suite a des appels ulterieurs.
(3) de Type 1 = Fonction. D'autres types comprennent non cotees de la fonction (type 0) et les commandes (de type 2). Si vous souhaitez des fonctions qui n'apparaissent pas dans l'Assistant Fonction, utilisez 0.
(4) Apres le succes de l'enregistrement, la valeur numerique res (res.val.num) contient un entier identifiant de code pour cette fonction, - la poignee. Enregistrer et passer a la suppression de l'inscription de la fonction lorsque la DLL est ferme. Oublier cela et vous aurez de la difficulte a utiliser des versions plus recentes de la bibliotheque..
Pour les Valeurs a partir d'une feuille de calcul Excel
les Valeurs peuvent etre transmis, de trois façons.
1. Comme dans le passe par valeur. Eg =CalcMean(4,5,8) xltypenum ou xltypestr
2. Par une Simple reference, disons un la cellule a1 ou de la plage a3:b56. xltypesref
3. Comme un composite de Reference. Essentiellement une collection de disjoint des references de cellule. xltypemref
1 et 2 sont les plus courants. 3 est un peu bizarre, et, sauf si vraiment necessaire, il est preferable de filtre. Si vous voulez l'utiliser, l'entree est un tableau de references de cellule (type 2), de sorte que vous avez a les utiliser.
Excel va filtrer le type de donnees si vous specifiez (nombre, chaîne de caracteres, etc), mais si vous attendez une gamme, alors vous devriez pleinement verifier le type et l'etendue des valeurs, des erreurs de declaration, le cas echeant..
le Retour d'Erreurs
Votre fonction doit retourner un lpxloper (type R) si vous souhaitez retourner Excel codes d'Erreur. Pour definir une erreur dans Res (une xloper) il suffit de faire
res.xltype := xltypeerr
res.val.err := nombre de // retourne les valeurs suivantes, puis juste retour de @res de votre fonction
NumberExcel Err
0#NULL
7#DIV/0
15#la VALEUR
23#REF
29#NOM
36#NUM
42#N/A
Avec compliquees, beaucoup de parametre de fonctions, je pense que excel standard erreurs sont un peu hostile et donc, je vous suggere fortement un GetlastError() fonction qui retourne la derniere erreur de chaîne de caracteres. Toute fonction qui retourne une erreur doit definir la chaîne d'erreur renvoye par GetLastError(). Cela permettra aux utilisateurs d'economiser beaucoup de temps lors de l'utilisation des fonctions pour la premiere fois.
la Lecture des Valeurs de Cellule
apres Avoir ete passe a une reference de cellule (xltypeSref) vous voulez obtenir les valeurs contenues dans les cellules. Pour ce faire, vous devez 'forcer' la reference de la cellule xloper. Ce forcer (une fonction Excel) et les forces de Excel pour construire un vecteur de xlopers, avec exactement (#Lignes * #Cols) xlopers. C'est a dire pour un 2 x 3 tableau de cellules, vous obtenez six xlopers. La cible xloper devient un en-tete avec le xltype champ = 64 (xltypearray). Le val._array membre contient le nombre de lignes et de colonnes et un pointeur vers le corps xloper.
Ces xlopers sont disposes en ligne de commande afin de les six cellules en deux lignes sur 3 colonnes est stockee en tant que
1 2 3
4 5 6
Chacun aura le type fondamental (xltype num ou Str) et de la valeur.
Exemple de Contrainte
Desttype.xltype := xltypeInt
Desttype.val.w := xltypeMulti
Eresult := Excel4v(xlcoerce,@Xval,2,[Valeurs,@desttype])
asm pop evier fin // ne Jamais Enlever
& nbsp & nbsp
Le xlopers/lpxlopers utilises ici sont
Desttype - Un xloper qui specifie la coercition type de destination (xltypemulti - Excelle nom pour un tableau de xlopers)
les Valeurs Du passe dans la cellule de reference - un lpxloper
Xval - La cible xloper. Apres avoir reussi a forcer, c'est l'en-tete d'un tableau. Avec les 2 x 3 tableau, il y aura six xlopers, chacune ayant une valeur de cellule.
Excel a alloue la memoire sur votre compte et ce qui doit etre fait, mais plus sur cela plus tard..
Exemple d'utilisation de l'valeurs
Cet exemple verifie l'
si xval.val._array.les lignes<>1 then
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Erreur('ne Devrait avoir qu'une ligne')
& ! & ! & ! & nbsp goto myexit
& nbsp & nbsp fin
xlar := xval.val._array.lparray
indice:=0
col:= 1 to xr.NumCols ne
& nbsp & nbsp commencer
& ! & ! & ! & nbsp si xlar^[index].xltype <> xltypenum puis
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & nbsp Erreur ('Element' inttostr(ligne), 'Pas un nombre')
& ! & ! & ! & ! & ! & ! & ! & nbsp pause
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & nbsp Valeur[col] := xlar^[index].val.num
& ! & ! & ! & nbsp inc(index)
& nbsp & nbsp fin
xlar est un pointeur vers un tableau de xlopers. Dans cet exemple verifie qu'il existe une ligne de donnees non numeriques. Puis il copie les valeurs dans la Valeur de tableau [].
Mettre des valeurs dans des Cellules Excel
Bien qu'il existe un equivalent (en quelque sorte) de xlcoerce, appele xlset, il ne peut etre appele a partir d'une commande de menu ou un bouton de barre d'outils) et non pas a partir d'une fonction. Son tres anti-social, de toute façon viens de vider un tas de valeurs dans une feuille de calcul, il pourrait simplement remplacer un matin de travail non enregistrees et ne fait pas qu'ameliorer votre popularite!
l'Un n'est pas si bien connu de la Excel Fonction appelee Tableaux (ou une formule tableaux) est ce qui est necessaire. Si vous n'etes pas familier avec eux, essayez ceci sur un vide de la feuille Excel.
1. Selectionnez une zone rectangulaire avec la souris. Maintenant, cliquez sur le montage de la ligne (juste en dessous de la barre d'outils, au-dessus des cellules) et tapez =g1. A ce stade, vous devriez voir =g1 dans la ligne d'edition et de la zone selectionnee doit toujours etre selectionne. Si vous avez desactive la selection par erreur, revenez en arriere et essayez a nouveau.
2. Maintenant, maintenez les touches ctrl et maj enfoncees et appuyez sur entree. L' =g1 doit etre colle dans toutes les cellules de la zone selectionnee.
Vous devez egalement remarquer certaines choses a ce sujet si vous cliquez sur une cellule dans ce domaine.
1. La ligne d'edition montre l'equation entre parentheses.
2. Vous ne pouvez pas modifier ou effacer la cellule.
3. Il n'a pas regler la reference de la cellule.
C'est le seul moyen (pour autant que j'ai pu faire) pour mettre des valeurs dans des cellules Excel. Votre fonction excel doit construire un tableau de xlopers, avec l'en-tete pointant vers le corps. Si votre fonction renvoie un tableau, vous devez utiliser une Fonction de Tableau pour afficher le resultat. Excel est tout a fait a l'aise avec cela. Si vous retournez un 3 x 5 domaine et l'utilisateur colle une Fonction de la Matrice de 4 x 6 rectangle, le supplement dans les cellules de tous show N/A.
la Gestion de la Memoire
Si un Excel4v appel renvoie un xloper avec un pointeur (chaînes ou xltypemulti par exemple) puis, lorsque votre code a fini avec la valeur de votre code doit toujours faire appel a xlfree sur le xloper. En fait, en regle generale, l'appel de xlfree sur toute xloper ne pas nuire a tous.
Il y a deux allocation de memoire cas que votre code DOIT gerer..
1. Vous avez appele une routine qui renvoie un xloper avec les donnees qu'il contient, par exemple, xlcoerce pour convertir un xltypesref/xltyperef a un xltypemulti (tableau). Excel attribue a sa propre memoire et lorsque vous avez termine avec les donnees, vous devez OU dans la valeur de $1000 (4096 decimal) a la xltype - ce 1000 $de la valeur est connue en tant que xlbitXLfree. Lorsque vous appelez xlfree, il libere de l' 'Excel alloue la memoire.
2. Si votre code renvoie un tableau de xlopers qui, Excel affiche comme une fonction de tableau, vous devez vous OU dans la valeur de 4 000 $(16384 decimal) a la xltype champ, avant que la fonction se termine. Apres avoir copie les valeurs Excel va faire un rappel a votre xlAutoFree fonction (vous n'en œuvre n'est-ce pas?) avec un lpxloper a vos donnees. Vous pouvez ensuite gratuit. Si vous avez cree un tableau a n elements (n 1) xlopers, ou nom_tableau[0] est l'en-tete qui pointe vers nom_tableau[1] alors que le pointeur retourne points de nom_tableau[0] et freemem(retour d'appel pointeur) sera alors libre de les corriger pointeur.
Un exemple De complement
L'exemple qui accompagne cet article est autonome dans environ 650 lignes de code sans non delphi de composants ou d'unites necessaires. Il implemente une Fonction de Distribution Cumulee GetCDF qui prend un nombre dans la plage de -4 a 4 en entree et renvoie la hauteur en vertu de l'ogive de la courbe. Je sais que Excel est livre avec plusieurs Normal des fonctions de distribution, mais il sert d'exemple. Il a ete teste sur Excel 95 et 97 avec Delphi 3 sur win 95/98 et NT, et s'est avere etre solide comme un roc. Je ne peux pas souligner a quel point il est important de verifier toutes les entrees et essayer et obtenir votre code aussi robuste que possible. Rien de mechant sera probablement a la bombe ou a accrocher Excel et les utilisateurs vont rapidement devenir des agresseurs. N'oubliez pas le Stdcalls sur toutes les fonctions exportees!
en dehors de l'obligation de xlauto famille de fonctions, il comprend cinq autres fonctions, dont deux sont invisibles. Ces deux GetXlStack et FreeRam sont destinees a l'utilisation par le developpeur. Les trois autres (GetCDF, LastError et Version) sont destines a l'utilisateur. Vous pouvez utiliser les deux types de fonctions directement, mais seulement a ceux qui sont visibles seront vus dans l'Assistant Fonction. Et n'oubliez pas les crochets sur les appels de fonction. Excel sera heureux =Version (sans ()) et renvoie une valeur de -30408699 (je n'en ai aucune idee) quand vous entendre =Version().
j'ai inclus seulement le principal excel numeros de fonction utilise dans le programme, la liste complete de pres de 400. La CDIP a l'ensemble du lot et comprend C-tetes qui peuvent facilement etre modifiee.
c'est un peu demode, non-OOP programme. J'ai choisi de cette façon, a l'origine, comme je me sentais de mon chemin de ronde, les complements excel, et je ne voulais pas avoir de problemes avec les Objets en meme temps. La seule classe que j'ai utilise ici est Txloper pour simplifier la creation de Xlopers mais c'etait pour garder concis. Envoyer vos requetes et les offres de travail a [email protected].
Le fichier ci-dessous est complet - source pour une dll. Assurez-vous que l'extension est .xll

{$A ,B,C ,D ,E,F,G ,H,I ,J ,K,L ,M,N ,O,P ,Q ,R,S,T,U,V ,W ,X ,Y,Z1}
bibliotheque cdfcalc

& nbsp & nbsp SysUtils,
& nbsp & nbsp windows,
& nbsp & nbsp dialogues,
& nbsp & nbsp formes,
& nbsp & nbsp Classes,
& nbsp & nbsp Math
// XLREF structure
& nbsp & nbsp type xlref = paniers enregistrement
& ! & ! & ! & ! & nbsp rwFirst : smallint
& ! & ! & ! & ! & nbsp rwLast : smallint
& ! & ! & ! & ! & nbsp colFirst : octet
& ! & ! & ! & ! & nbsp colLast : byte
& nbsp & nbsp fin
& nbsp & nbsp // Renvoie une plage de selection
& nbsp & nbsp XlRangeRecord = paniers enregistrement
& ! & ! & ! & ! & nbsp Count : mot // doit toujours etre $1
& ! & ! & ! & ! & nbsp Sref : xlref
& nbsp & nbsp fin
& nbsp & nbsp xlmref= paniers enregistrement
& ! & ! & ! & ! & ! & ! & ! & nbsp count : mot
& ! & ! & ! & ! & ! & ! & ! & nbsp RefTbl : array[0..1000] de XlRef
& nbsp & nbsp fin
& nbsp & nbsp lpxloper = ^XLOPER
& nbsp & nbsp lpxloperArray = ^XLArray
& nbsp & nbsp lpxlmref = ^xlmref
& nbsp & nbsp TVal = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Cas de l'Octet de
& ! & ! & ! & nbsp & ! & ! & ! & ! & ! & ! & nbsp 1: (num : Double) // xltypeNum
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 2: (str : ^ShortString) // xltypeStr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 3: (bool : Word) // xltypeBool
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 4: (err : Mot) // xltypeErr
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 5: (w : Integer) // xltypeInt
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 6: (sref : emballe enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Comte : mot
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ref : Xlref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 8: (_array : paniers d'Enregistrement / de/ xltypeMulti
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lparray: lpxloperArray
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lignes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp colonnes: MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp 9: (mref : paniers d'enregistrement / de/ xltyperef
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp lpmref : lpxlmref
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp idsheet : entier
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin // tval
& nbsp & nbsp XLOPER = paniers Enregistrement
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp val : TVal
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp xltype : MOT
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mannequin:array[0..5] de byte // remplissage
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Fin
xlarray=array[0..1000] de xloper
lpxlarray=^xlarray
txloper = la classe // Simple xloper classe de soutien
& nbsp & nbsp prive
& ! & ! & ! & nbsp fxloper : xloper
& ! & ! & ! & nbsp fActualStr : ShortString
& ! & ! & ! & nbsp fonction Getlpxloper:lpxloper
& nbsp & nbsp public
& ! & ! & ! & nbsp constructeur Creer

& ! & ! & ! & nbsp Destructeur de Detruire remplacer
& ! & ! & ! & nbsp Constructeur Create_Str(NewStr : ShortString)
& ! & ! & ! & nbsp procedure SetStr(NewStr : ShortString)
& ! & ! & ! & nbsp procedure SetNum(NewNumber : Entier)
& ! & ! & ! & nbsp procedure SetInt(NewNumber : Entier)
& ! & ! & ! & nbsp procedure SetErr
& ! & ! & ! & nbsp propriete thelpxloper : lpxloper lire Getlpxloper
fin
// Excel
fonction de Excel4v(xlfn:word operRes:lpxloper count:integer opers:tableau de lpxloper):integer
stdcall externe 'xlcall32.dll'
// XLMREF structure Decrit plusieurs rectangulaire references.
const
& nbsp xltypeNum = $0001
& nbsp xltypeStr = $0002
& nbsp xltypeBool = $0004
& nbsp xltypeRef = $0008
& nbsp xltypeErr = $0010
& nbsp xltypeFlow = $0020
& nbsp xltypeMulti = $0040
& nbsp xltypeMissing = $0080
& nbsp xltypeNil = $0100
& nbsp xltypeSRef = $0400
& nbsp xltypeInt = $0800
& nbsp xlbitXLFree = $1000
& nbsp xlbitDLLFree = $4000
& nbsp xltypeBigData =xltypeStr ou xltypeInt
// codes d'Erreur Utilise pour val.err champ de XLOPER structure
& nbsp xlerrNull =0
& nbsp xlerrDiv0 =7
& nbsp xlerrValue =15
& nbsp xlerrRef =23
& nbsp xlerrName =29
& nbsp xlerrNum =36
& nbsp xlerrNA =42
// les codes de Retour
& nbsp xlretSuccess =0 // succes
& nbsp xlretAbort =1 // macro stoppe
& nbsp xlretInvXlfn =2 // fonction non valide
& nbsp xlretInvCount =4 // nombre d'arguments incorrect
& nbsp xlretInvXloper =8 // invalide OPER de la structure
& nbsp xlretStackOvfl =16 // stack overflow
& nbsp xlretFailed =32 // echec de la commande
& nbsp xlretUncalced =64 // uncalced cellulaire
// Fonction du nombre de bits
& nbsp xlCommand = $8000
& nbsp xlSpecial = $4000
& nbsp xlIntl = $2000
& nbsp xlPrompt = $1000
// fonction Speciale numeros
& nbsp xlFree =(0 ou xlspecial)
& nbsp xlStack =(1 ou xlspecial)
& nbsp xlCoerce =(2 ou xlspecial)
& nbsp xlSet =(3 ou xlspecial)
& nbsp xlSheetId =(4 ou xlspecial)
& nbsp xlSheetNm =(5 ou xlspecial)
& nbsp xlAbort =(6 ou xlspecial)
& nbsp xlGetInst =(7 ou xlspecial)
& nbsp xlGetHwnd =(8 ou xlspecial)
& nbsp xlGetName =(9 ou xlspecial)
& nbsp xlEnableXLMsgs =(10 ou xlspecial)
& nbsp xlDisableXLMsgs =(11 ou xlspecial)
& nbsp xlDefine inaryName =(12 ou xlspecial)
& nbsp xlGetBinaryName =(13 ou xlspecial)
// fonctions definies par l'Utilisateur, necessaire pour appeler les fonctions d'Excel
& nbsp & nbsp xlfCaller=89
& nbsp & nbsp xlfRegister=149
& nbsp & nbsp xlfUnregister=201
//
& nbsp & nbsp DLLversion:shortstring='CDF Calc V1.02'
& nbsp & nbsp AddInCategory='CDF Calculatrice'
& nbsp & nbsp const zlpxloper=lpxloper(nil)
& nbsp & nbsp type retarray=array[0..1000] de xloper
& nbsp & nbsp pretarray=^retarray
var // donnees Globales
& nbsp & nbsp res : xloper
& nbsp & nbsp GetCDF_Id : Entier
& nbsp & nbsp xlStack_Id : Integer
& nbsp & nbsp EResult : Integer
& nbsp & nbsp evier : integer
& nbsp & nbsp GetStack_Id : Integer
& nbsp & nbsp LastError_Id :

L'écriture (non com) compléments excel dans delphi

L'écriture (non com) compléments excel dans delphi : Plusieurs milliers de conseils pour vous faciliter la vie.
Recommander aux amis
  • gplus
  • pinterest

Messages récents

Commentaire

Laisser un commentaire

évaluation