Article
FONT SIZE :
fontsize_dec
fontsize_inc
Auteur: Admin
Vues: 11
Temps: 19:40:13 | 3 années depuis

Rédaction (non com) Compléments Excel dans Delphi


Rédaction add-in Excel avec Delphi est un projet ambitieux. Je montre comment vous pouvez faire, et mettre en lumière les différents pièges attendant le voyageur ignorant dans cette frontière en grande partie inexploré.

écrit add-in Excel avec Delphi est un projet ambitieux. Voici où je montre comment vous pouvez faire, et mettre en évidence les différents pièges qui attendent le voyageur ignorant dans cette frontière en grande partie inexploré.



Malgré l'impopularité apparente de Microsoft dans certains milieux, Excel devrait vraiment mettre sur le dessus de la liste pour 'meilleur logiciel jamais créé ». Bien sûr, en prenant plus de dix ans pour faire les choses a aidé. Je pense que une force particulière d'Excel est son API relativement ouvert, permettant aux développeurs de créer des macro et utilisent Visual Basic, applications Excel/VBA.



Une des caractéristiques d'Excel est moins add-ons connus. Bien que vous pouvez créer avec VBA, mais vous pouvez aussi écrire add-in DLL en Delphi et C ++. Pour ceux qui ne le développement sérieux, vous devez acheter le kit de Excel 97 Developer (ISBN 1-57231-498-2) (CDPE) livre, mais bien sûr son C/C ++ orienté et il ya des pièges pour le programmeur Delphi. Dans cet article, je vous montre assez pour vous permettre de continuer. En tant que développeur dans une feuille de calcul Excel que j'ai développé avec succès de nombreux composants supplémentaires avec Delphi 3, et je sais que personne d'autre pour le faire. Il CAD financière, une entreprise canadienne dont les add-ons peuvent être utilisés par Delphi, mais je pense qu'ils sont écrits en C ++. Hé, je pourrais être la seule personne au monde à le faire!



Delphi add-ons, il est facile pour vous d'étendre Excel à bien des égards, tels que l'acquisition de données à partir des ports série, des flux de données, le tout à la vitesse de Delphi code compilé qui est nettement plus rapide que interprété Excel VBA. Commençons, theres beaucoup à couvrir.

Les chaînes sont une énorme erreur énorme



Parce que l'add-in est une DLL et Excel utilisant des chaînes courtes, vous devez vous assurer que les chaînes d'option de compilateur énorme est clair (ou $ H utilisé). Vous pourriez probablement utiliser des chaînes longues en interne, mais assurez-vous de convertir avant de passer à Excel. Pour de plus amples utilisation fonction de sécurité ShortString ou String [n] où n est 1-255 types. Même si vous avez activé Hugestrings, vous pouvez utiliser string [n] pour passer des paramètres que ce sont toujours de type ShortString. Rappelez-vous la règle d'or, pas de longues chaînes ou des paramètres passés dossier.



Reconnaissance à la fin

Excel va reconnaître que la DLL comme un add-in si certaines fonctions sont exportés. Vous devez toujours fournir ces fonctions, ainsi que ceux de l'utilisateur. Ces xlAuto famille de fonctions sont répertoriés dans le tableau ci-dessous et documenté dans le livre et Edk dans l'exemple de code dans cet article. Tous vos fonctions exportées doivent utiliser la convention d'appel STDCALL.



Fonction Objectif

xlAutoFree appelé par Excel pour libérer la mémoire allouée de l'Addin.

XlAutoAdd Appelé lorsque Addin est d'abord enregistré.

XlAutoOpen appelée lorsque Excel charge.

XlAutoClose appelé lorsque vous quittez Excel.

XlAutoRemove Appelé lorsque Addin est retiré à partir d'Excel.

XlAutoRegister appelée que si une fonction n'a pas été enregistré.

XlAddInManagerInfo Fournit une chaîne texte de description de la Addin.



Pour utiliser l'une de l'intégré dans Excel Fonction votre fonction appelle la fonction Excel4V Excel. Elle est définie comme



Fonction Excel4v (

xlfn: mot;

operRes: lpxloper;

compter: integer;

opers: tableau de lpxloper): integer;

stdcall; Extérieur »Xlcall32.dll ';



xlfn est la fonction «numéro de fonction» dans Excel appelé.

Operfn est le résultat et est un pointeur vers un XLOPER appelé lpxloper (voir la section suivante)

Count est le nombre d'éléments dans Les Opérateurs.

Les Opérateurs est un tableau de lpxloper, qui est un tableau de pointeurs vers xlopers.



Remarque: Pour de nombreuses fonctions, vous pouvez passer une matrice nulle pour les Les Opérateurs de paramètres. Sous D3, le bâtiment vide array [] n'est pas autorisé, .as est en D4 à utiliser [néant] sous D3.



Les italiques sont de développement de la mine a été de fournir aux utilisateurs de nouvelles fonctions. Les documents CDIP comment ajouter des boutons et des contrôles dans Excel, mais ceux-ci sont un peu «travail» plus et je ne traitent pas avec eux ici. Si vous voulez envoyer les données dans Excel, il existe deux autres approches, à la fois composant base- shareware TadvExcel a transfert de données très rapide en utilisant DDE. Les composants peuvent lire TxlsReadWrite forme et les formules des données de sortie directement dans le fichier de classeur Excel.



Avant de commencer à appeler les fonctions d'Excel, il est nécessaire de connaître le type XLOPER. Il s'agit d'un record pascal (structure C) environ 10 octets, alignés sur les paragraphes 16 octets en tableau qui correspond à des cellules dans une feuille de calcul dans Excel. La définition est illustré ci-dessous. Blâmer Microsoft pour les noms de champs courts. Le type de TVAL utiliser l'ancienne variante Pascal Type d'enregistrement, à ne pas confondre avec les variantes de Windows OLE, s'il est utilisé d'une manière similaire. Le champ de xltype XLOPER préciser lequel des 9 types est utilisé dans le jeu. Donc, si la XLOPER a un type de 1, val.num a un nombre double précision valide.



J'ai trouvé que les types 1, 2 et 8 sont les plus utilisés. Type 4 est retourné à Excel lorsque vous obtenez quelque chose de mal. Il est un type entier (5), mais num (1) semble beaucoup plus fréquente. Type 6 est utilisé pour les plages, avec le type 9 pour la collecte de cellules séparées, où vous maintenez la touche Ctrl tout en sélectionnant les cellules. Il n'y a pas de type 7.

XLOPER Définition



TVAL = packed record

Octet de cas de

1: (num: deux); (* XltypeNum *)

2: (str: ^ ShortString); (* XltypeStr *)

3: (bool: Word); (* XltypeBool *)

4: (err: Word); (* XltypeErr *)

5: (w: Integer); (* XltypeInt *)

6: (sref: emballé dossier

compter: mot;

ref: Xlref;

fin);

8: (_array: emballé enregistrement (* xltypeMulti *)

lparray: LPXLOPERArray;

lignes: Word;

colonne: WORD;

Fin);

9: (Mref: xltyperef // packed record

lpmref: lpxlmref;

idsheet: integer;

Fin);

Fin; // TVAL



XLOPER = packed record

val: TVAL;

xltype: WORD;

mannequin: array [] 0..5 octets; // Pads à 16 octets

Fin;

lpxloper = ^ XLOPER;

Problème avec les appels vers Excel

De la grande roche avec Delphi add-ons est le paramètre supplémentaire après l'adresse de retour sur la pile. Cette livré gratuitement avec chaque appel dans Excel. Je n'ai jamais compris ce qu'il faut, mais tant qu'il est jeté, l'add-in fonctionne très bien. Ajouter l'asm pop de ligne variable; fin; après chaque appel où variable peut être une variable locale ou un objet global qui est d'au moins 4 octets entier est bien. Ce doit être inclus pour répétée après chaque appel Excel4v. Sinon, vous construisez une bombe.



Exemple

EResult: = Excel4V (xlfCaller, @ xres, 0 [zéro]);

évier pop asm; fin; // Jamais Retirer



Notez que la syntaxe Delphi, si xres est un XLOPER, il est possible de définir un lpxloper de utilizzarexres.



Attention- recalcul alerte!

Si les entrées à votre fonction sont calculés en aucune façon, le code doit vérifier l'état de l'appel Excel (eResult dans l'exemple ci-dessus), ainsi que le résultat de la fonction dans Excel qui xres dessus de l'appel. Rappelez-vous, il est appelé CAL Excel4V à la fonction spécifiée.



EResult donne 0 si ok, ou un peu réglé pour indiquer l'erreur. Vous devez toujours manipuler les valeurs 1 et 64 est xlabort 1 indique que l'utilisateur appuie sur la touche esc. 64 est une référence de cellule non calculés. Ce n'est pas une erreur, mais il arrive quand la fonction utilise des fonctions ou des calculs sur la feuille de calcul qui sont entièrement évaluée après votre routine sera appelée en premier. Si cela se produit, le code nécessaire pour libérer de la mémoire déjà alloués à l'appel et la sortie. Excel pour appeler à nouveau la fonction.



Structurez votre code comme ceci



1 Paramètres d'entrée

2 Si une erreur se produit 64 ou 1 (abandon clé), sortie après libération de la mémoire déjà alloué (le cas échéant) dans cette fonction.

3. faire la fonction principale de traitement.



Si la phase 3 sera une longue période, soit plus de 1/10 ème de seconde, le code doit vérifier l'état de l'interruption appelant périodiquement xlAbort.

Démarrage

Lorsque le complément est d'abord ajouté à Excel, chacune des fonctions exportées doivent être enregistrés. Il s'agit de l'appel de la routine de registre Excel pour chaque routine. Il ya huit paramètres passés comme XlOpers.



Type de paramètre Use

Module chaîne de texte Nom complet de la DLL avec le chemin

Comment cordes ou le numéro le nom de la fonction ou le numéro à appeler

Tapez argument chaîne de texte et types de retour

Fonction Fonction Nom chaîne de texte dans l'Assistant de fonction

Sujet texte String String texte facultatif qui décrit les paramètres dans l'Assistant de fonction

Macro Type Nombre de 0,1 ou 2

Catégorie chaîne ou catégorie Nombre dans lequel il apparaît la fonction

Raccourci String Texte Seulement utilisé pour les commandes, aller à nulle pour la fonction



Le paramètre le plus important à être enregistrée est le type de texte. Celui-ci utilise les lettres AR pour représenter la valeur de retour et les paramètres fournis. Les valeurs sont transmises comme on pouvait s'y attendre dans une API C pour référence (c.-à-pointeur- qui est toujours un lpxloper) ou par valeur.



Par exemple, la feuille de calcul Excel = MyFunction (a1: b1) en passant une référence en InterestRate = («EUR») utilise une valeur.



Exemple

Dllname: = GetName; // Fonction renvoie le nom/chemin à partir d'Excel

pxModuleText.SetStr (s); // Note (1)

pxProcedure.SetStr ('adddate'); // Nom de la fonction

pxTypeText.SetStr ('JJDD!'); // (2) Type de retour = J = entrée JDD

pxFunctionText.setStr ('adddate'); Nom Assistant de Fx

pxArgumentText.SetStr («date, l'heure, la monnaie"); // Parm du texte dans FX Wiz

pxMacrotype.SetNum (1); // Type = func Sinmple (3)

pxCategory.SetStr (AddInCategory); Catégorie // pour Func. as



EResult: = Excel4V (xlfregister, @ res, 8, // passent 8 parms

[PxModuletext.thelpxloper,

pxProcedure.thelpxloper,

pxTypeText.thelpxloper,

pxFunctionText.thelpxloper,

pxArgumentText.thelpxloper,

pxMacroType.thelpxloper,

pxCategory.thelpxloper,

zlpxloper]); // Null

évier pop asm; fin; // Jamais Retirer

Résultat: = tronc (res.val.num); // Code d'identification (4)



Les variables sont toutes sortes de px qui simplifie txloper xlopers initialisation.

Remarques

(1) Le Dllname et le chemin d'accès doivent être obtenus à partir d'Excel, en utilisant la fonctionnelle XlGetName vous pouvez voir ce utilisé dans l'exemple de code. Ne pas coder en dur car il comprend le chemin.

(2) Voir registre (page 219 dans CDIP) pour plus de détails de type text. Le premier paramètre est le paramètre de retour (J = 32 bits entier), les 3 suivants sont les entrées (JDD = Integer, String, String) et l '! signifie que Excel appelle toujours la fonction quand il recalcule. Sans le '!, Excel appelle la fonction une fois, en prise avec le résultat et utilise le résultat de verrouillage pour des appels ultérieurs.

(3) Type 1 = fonction. D'autres types comprennent la fonction non cotées (type 0) et les contrôles (type 2). Si vous voulez des fonctionnalités qui ne figurent pas dans l'Assistant fonction, utilisez 0.

(4) Une fois que vous avez enregistré avec succès, la valeur numérique de résolution (res.val.num) contient un code entier de id pour cette fonctionnellement la poignée. Enregistrer ce et passer à la fonction Deregister lorsque la DLL est fermée. Oubliez cela et vous aurez des problèmes avec les versions les plus récentes de la bibliothèque ..

Obtenir les valeurs à partir d'une feuille de calcul Excel

Les valeurs peuvent être transmises, de trois façons.



1-par-valeur passée. CalcMean Eg = (4,5,8); xltypenum ou xltypestr

2 Comment facile référence, dire une cellule ou une plage a1 a3: B56. xltypesref

3 en tant que composé de référence. Fondamentalement, une collection de références de cellules disjointes. xltypemref



1 et 2 sont les plus courants. 3 est un peu étrange, si ce n'est pas vraiment nécessaire, il est préférable de filtrer cette. Si vous voulez utiliser, l'entrée est un tableau de références de cellules (de type 2), vous devez donc utiliser chacun d'eux.



Excel filtrer le type de données si vous indiquez que (nombre, chaîne, etc), mais si vous attendez une gamme, alors vous devriez contrôler totalement le type et la gamme de valeurs, les rapports d'erreurs le cas échéant ..



Revenant erreurs

La fonction doit renvoyer une lpxloper (type R), si vous voulez renvoyer des codes d'erreur Excel. Pour définir une erreur dans Res (un XLOPER) il suffit de faire



res.xltype: = xltypeerr;

res.val.err: = nombre; // Renvoie les valeurs suivantes de votre fonction alors tornareres juste



Nombre Err Excel

0 #NULL

7 # DIV/0

15 #VALEUR

23 #REF

29 #NAME

36 #NUM

42 # N/A



Par compliqué, je pense que beaucoup de fonctions paramétriques excellent erreurs types sont un peu raide et je suggère fortement une fonction GetLastError (), qui retourne la dernière chaîne d'erreur. Chaque fonction renvoie une erreur doit définir la chaîne d'erreur renvoyé par GetLastError (). Cela permettra d'économiser les utilisateurs beaucoup de temps lorsque vous utilisez les fonctions pour la première fois.



La lecture des valeurs de cellules

Après avoir été adopté une référence de cellule (xltypeSref) que vous voulez obtenir les valeurs dans les cellules. Pour ce faire, vous devez «force» la référence de la cellule de XLOPER. Cette force (fonction d'Excel) oblige Excel pour construire un vecteur de xlopers, avec exactement (#Rows * #Cols) xlopers. C'est à dire pour un tableau 2 x 3 cellules, on obtient six xlopers. L'objectif de XLOPER devient un en-tête avec le xltype de terrain = 64 (xltypearray). Le val._array membre contient le nombre de lignes et de colonnes et un pointeur vers la XLOPER du corps.



Ces xlopers sont disposés en une rangée de sorte que les six cellules en deux rangées de trois colonnes sont stockées en tant que

1 2 3

4 5 6



Tout le monde aura le type de base (xltype num ou Str) et la valeur.

Exemple de coercition

Desttype.xltype: = xltypeInt;

Desttype.val.w: = xltypeMulti;

EResult: = Excel4v (XlCoerce, @ ValX, 2, [Valeurs, @ Desttype]);

évier pop asm; fin; // Jamais Retirer



Xlopers I/lpxlopers utilisées ici sont



Desttype - Un XLOPER qui spécifie la coercition de type de destination (xltypemulti- excellent nom pour une série de xlopers)

Valeurs - Le passé dans la référence d'une cellule lpxloper

ValX - La cible XLOPER. Après contraindre un succès, c'est la tête de matrice. Avec 2 x 3 tableau, il y aura six xlopers, tenant chacun une valeur de cellule.



Excel a alloué la mémoire sur votre compte, et ce doit être abordée, mais plus sur cela plus tard ..

Exemple d'utilisation des valeurs

Cet exemple vérifie l'

alors si xval.val._array.rows1

commencer

Erreur ("Vous devriez avoir une seule ligne ');

myexit goto;

fin;

xlar: = xval.val._array.lparray;

Indice: = 0;

pour col: = 1 pour faire xr.NumCols

commencer

si xlar ^ [index] .xltype xltypenum alors

commencer

Erreur ('Element' + IntToStr (ligne) + "n'est pas un nombre");

break;

fin;

Valeur [col]: = xlar ^ [index] .val.num;

inc (index);

fin;



xlar est un pointeur sur un tableau de xlopers. Dans cet exemple, on vérifie qu'il existe une ligne de données non-numériques. Il copie ensuite les valeurs de la valeur de tableau [].



Mettre les valeurs dans les cellules Excel

Même si il ya un équivalent (ou presque) XlCoerce appelé xlset, ne peut être appelée par une commande (bouton ou un menu barre d'outils) et non une fonction. Il est très antisocial de toute façon à juste vider un tas de valeurs dans une feuille de calcul pourrait être juste écraser un travail non enregistré dans la matinée et pas seulement d'améliorer votre popularité!



Une caractéristique qui n'est pas si bien connu de Excel appelée fonction Array (ou formule matricielle) est ce qui est nécessaire. Si vous n'êtes pas familier avec eux, essayer sur une feuille de blanc Excel.



1 Sélectionnez une zone rectangulaire avec la souris. Maintenant, cliquez sur la ligne d'édition (juste en dessous des barres d'outils au-dessus des cellules) et type = g1. À ce stade, vous devriez voir = g1 doit toujours être sélectionné dans la ligne d'édition et la zone sélectionnée. Si vous effacez la sélection par erreur, revenir en arrière et essayer à nouveau.

2 Tout en maintenant la touche Ctrl et Maj et appuyez sur Entrée. I = g1 doivent être collées dans toutes les cellules de la zone sélectionnée précédemment.



Vous devriez également remarquer quelques choses au sujet de cette si vous cliquez sur n'importe quelle cellule dans ce domaine.

1 La ligne d'édition représente l'équation entre parenthèses.

2 Vous ne pouvez pas modifier ou supprimer la cellule.

3 Il ne règle pas la référence de cellule.



C'est le seul moyen (pour autant que je puisse dire) de mettre les valeurs dans les cellules d'Excel. La fonction Excel doit construire une série de xlopers, avec l'en-tête de l'organisme. Si votre fonction retourne un tableau, vous devez utiliser une fonction de tableau pour montrer le résultat. Excel est assez intelligent avec cela. Si vous retournez une superficie de 3 x 5 et vous collez une fonction de tableau dans un rectangle de 4 x 6, les cellules supplémentaires seront tout montrer N/A.



Gestion de la mémoire

Si un appel renvoie une Excel4v XLOPER avec un pointeur (ou chaînes xltypemulti par exemple) alors que le code a fini avec la valeur du code doit toujours appeler xlfree sur XLOPER. En fait, en règle générale, appelant xlfree tout XLOPER ne fait pas mal du tout.



Il existe deux cas de l'allocation de mémoire que le code doit gérer ..



1 Vous avez appelé une routine qui renvoie un XLOPER comportant des données, par exemple, pour convertir un XlCoerce xltypesref/xltyperef un xltypemulti (tableau). Excel attribue sa propre mémoire et lorsque vous avez terminé avec les données, vous devriez ou valeur $ 1000 (4096 décimal) à la valeur de 1000 $ xltype- ceci est connu comme xlbitXLfree. Lorsque vous appelez xlfree, il libère la mémoire »d'Excel alloué.

2 Si le code renvoie un tableau de xlopers que Excel affiche comme une fonction de tableau, vous devez OU de la valeur de $ 4000 (16384 décimal) à la xltype de domaine avant la fin de la fonction. Après avoir copié les valeurs d'Excel pour faire une fonction de rappel pour votre xlAutoFree (vous avez fait mettre en œuvre un vrai?) Avec un lpxloper à vos données. Vous pouvez ensuite le libérer. Si vous avez créé le tableau de n éléments (n + 1), où xlopers arrayname [0] est l'en-tête qui indique ArrayName [1], puis le pointeur de retour à ArrayName [0] et FreeMem (rappel pointeur ) sera ensuite libérer correctement le pointeur.



Un exemple Add-In

L'exemple qui accompagne cet article est autonome dans environ 650 lignes de code sans composants ou les unités Delphi n'est pas nécessaire. Il met en œuvre une fonction de distribution cumulative GetCDF qui prend un nombre de -4 à 4 comme entrée et retourne la hauteur sous la courbe spinner. Je sais que Excel a un certain nombre de fonctions de la distribution normale, mais il sert à titre d'exemple. E 'a été testé sur Excel 95 et 97 avec Delphi 3 sur Windows 95/98 et NT et prouvé pour être solide comme le roc. Je ne peux pas souligner à quel point il est important de contrôler toutes les entrées et essayer d'obtenir votre code plus robuste possible. Toute mauvaise chose probablement la bombe ou coup Excel et les utilisateurs seront rapidement devenir des agresseurs. Ne pas oublier les Stdcalls sur toutes les fonctions exportées!



En plus de la famille de xlauto obligatoire de fonctions, y compris les cinq autres fonctions, dont deux sont invisibles. Ces deux GetXlStack FreeRAM et sont destinés à être utilisés uniquement par le développeur. Les trois autres (GetCDF, et LastError Version) sont fournies à l'utilisateur. Vous pouvez utiliser les deux types de fonctions directement, mais seulement ceux qui sont visibles, vous verrez dans l'Assistant Fonction. Et n'oubliez pas les supports des appels de fonction. Excel fera un plaisir de prendre = Version (sans ()) et renvoyer une valeur de -30408699 (je n'ai aucune idée) quand vous dites effectivement = Version ().



J'ai inclus uniquement les principales figures de la fonction Excel utilisée dans le programme, la liste complète a près de 400 La CDIP a l'ensemble du lot et comprend les en-têtes C qui peuvent être facilement modifiées.



À bien des égards, c'est un peu «d'un vieux programme, non-POO. J'ai d'abord choisi de cette façon que je sentais mon chemin Compléments Excel et je ne voulais pas avoir de problèmes avec des 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 le garder concis. Envoyez vos questions et emplois david@darkgames.com.



Le fichier ci-dessous est complète - source à 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;



utilisations

SysUtils,

des fenêtres,

boîtes de dialogue,

formes,

Classes

Math;



// Structure XLREF

Type xlref = packed record

rwFirst: smallint;

rwLast: smallint;

colFirst: octet;

colLast: octet;

fin;



// Retourne une gamme de sélection

XlRangeRecord = packed record

Conte: mot; // Doit toujours 1 $

Sref: xlref;

fin;



xlmref = packed record

compter: mot;

RefTbl: array [0..1000] de XlRef;

fin;

lpxloper = ^ XLOPER;

lpxloperArray = ^ XLArray;

lpxlmref = ^ xlmref;



TVAL = packed record

Octet de cas de

1: (num: deux); // XltypeNum

2: (str: ^ ShortString); // XltypeStr

3: (bool: Word); // XltypeBool

4: (err: Word); // XltypeErr

5: (w: Integer); // XltypeInt

6: (sref: emballé dossier

Conte: mot;

ref: Xlref;

fin);

8: (_array: emballé enregistrement // xltypeMulti

lparray: lpxloperArray;

lignes: Word;

colonne: WORD;

Fin);

9: (Mref: xltyperef // packed record

lpmref: lpxlmref;

idsheet: integer;

Fin);

Fin; // TVAL



XLOPER = packed record

val: TVAL;

xltype: WORD;

mannequin: array [] 0..5 octets; // Filler

Fin;



xlarray = array [0..1000] de XLOPER;

lpxlarray = ^ xlarray;



txloper = classe classe d'aide // simples XLOPER

privé

fxloper: XLOPER;

fActualStr: ShortString;

Fonction Getlpxloper: lpxloper;



public

Créez le fabricant;

Destructeur Destroy; ignorer;

Fabricant Create_Str (newstr: ShortString);

Procédure setstr (newstr: ShortString);

Procédure SetNum (NewNumber: Integer);

Procédure SETINT (NewNumber: Integer);

procédure de SetErr;

thelpxloper propriétés: lpxloper lire Getlpxloper;

fin;



// Excel

travailler Excel4v (xlfn: mot; operRes: lpxloper; compter: Integer; opers: tableau de lpxloper): integer;

stdcall; Extérieur »Xlcall32.dll ';



La structure // XLMREF décrit des références rectangulaire.



const

xltypeNum = $ 0001;

xltypeStr = $ 0002;

xltypeBool = $ 0004;

xltypeRef = $ 0008;

xltypeErr = $ 0010;

xltypeFlow = $ 0020;

xltypeMulti = $ 0040;

xltypeMissing = $ 0080;

xltypeNil = $ 0100;

xltypeSRef = $ 0400;

xltypeInt = $ 0800;

xlbitXLFree = $ 1000;

xlbitDLLFree = $ 4000;

xltypeBigData = xltypeStr ou xltypeInt;



// des codes d'erreur d'occasion pour le champ ESTERR la structure XLOPER

xlerrNull = 0;

xlerrDiv0 = 7;

xlerrValue = 15;

xlerrRef = 23;

xlerrName = 29;

xlerrNum = 36;

xlerrNA = 42;



// Codes de retour

xlretSuccess = 0; // Succès

xlretAbort = 1; // Macro arrêté

xlretInvXlfn = 2; // Nombre de fonction invalide

xlretInvCount = 4; // Nombre incorrect d'arguments

xlretInvXloper = 8; // Structure OPER invalide

xlretStackOvfl = 16; // Stack Overflow

xlretFailed = 32; // Commande a échoué

xlretUncalced = 64; // cellules uncalced



// Bit numéro de fonction

xlCommand = $ 8000;

xlSpecial = $ 4000;

xlIntl = $ 2000;

xlPrompt = $ 1000;



// Numéros de fonction spéciale

xlFree = (0 ou xlspecial);

xlStack = (1 ou xlspecial);

XlCoerce = (2 ou xlspecial);

xlSet = (3 ou xlspecial);

xlSheetId = (4 ou xlspecial);

xlSheetNm = (5 ou xlspecial);

xlAbort = (6 ou xlspecial);

xlGetInst = (7 ou xlspecial);

xlGetHwnd = (8 ou xlspecial);

xlGetName = (9 ou xlspecial);

xlEnableXLMsgs = (10 ou xlspecial);

xlDisableXLMsgs = (11 ou xlspecial);

xlDefineBinaryName = (12 ou xlspecial);

xlGetBinaryName = (13 ou xlspecial);



// fonctions définies par l'utilisateur, vous avez besoin d'appeler des fonctions Excel

xlfCaller = 89;

xlfRegister = 149;

xlfUnregister = 201;

//

DLLVersion: ShortString = 'CDF Calc V1.02 »;

AddInCategory = 'CDF Calculator »;



zlpxloper lpxloper = const (zéro);

Type de retarray = array [0..1000] de XLOPER;

pretarray = ^ retarray;



var // données mondiale

res: XLOPER;

GetCDF_Id: Integer;

xlStack_Id: Integer;

EResult: Integer;

évier: integer;

GetStack_Id: Integer;

LastError_Id: Integer;

FreeRam_Id: Integer;

Version_id: Integer;

LastErrorxl: XLOPER;

LastErrorStr: ShortString;

BRC: integer;

FUNCNAME: String [64];



pxModuleText, pxProcedure, pxTypetext, pxFunctiontext,

pxArgumentText, pxMacroType, pxCategory, pxShortcutText: txloper;

HaveRegistered: booléen;

xValue: XLOPER;



procédure de setxlcols (tête var: array of XLOPER; numrows, numColumns: mot);

commencer

FillChar (tête [0], sizeof (tête [0]), 0);

FillChar (tête [1], sizeof (tête [1]), 0);

tête [0] .xltype: = 64;

tête [0] .val._array.rows: = numrows; //

tête [0] .val._array.columns: = numColumns; //

tête [0] .val._array.lparray: = tête [1];

fin;



Procédure Setval (var v: XLOPER; NUMVAL: deux);

commencer

FillChar (v, sizeof (c), 0);

v.xltype: = 1;

v.val.num: = NUMVAL;

fin;



Procédure SetFunctionName (S: String);

commencer

FUNCNAME: = s;

fin;



Procédure d'erreur (S: ShortString);

commencer

Si nous LastErrorStrs

LastErrorStr: = FUNCNAME + ":" + S;

fin;



Fonction GetSheetName: ShortString;

xres Var, xsheetname: XLOPER;

ResStr: ShortString;

commencer

ResStr: = '';

EResult: = Excel4V (xlfCaller, @ xres, 0 [zéro]);

évier pop asm; fin; // Jamais Retirer

si eResult = 16 alors

ResStr: = 'Aucune Caller ID'

autre

commencer

eResult: = Excel4V (xlsheetnm, @ xSheetname, 1, [@ Xres]);

évier pop asm; fin; // Jamais Retirer

si eResult = 0 alors

commencer

ResStr: = xsheetname.val.str ^;

fin

fin;

EResult: = Excel4V (xlfree, zéro, 1, [@ xres]);

évier pop asm; fin; // Jamais Retirer

EResult: = Excel4V (xlfree, zéro, 1, [@ xsheetname]);

évier pop asm; fin; // Jamais Retirer

Résultat: = ResStr;

fin;



// Retourne le chemin complet et le nom de la DLL

fonction GetName: ShortString;

commencer

EResult: = Excel4V (xlGetName, @ res, 1, [zéro]);

évier pop asm; fin; // Jamais Retirer

Résultat: = res.val.str ^;

EResult: = Excel4V (xlfree, zéro, 1, [@ res]);

évier pop asm; fin; // Jamais Retirer

fin;





CONST

X1 = -4,0; // Gauche point final

+ X2 = 4,0; // Droit point final

NUMINV = 40000; // Nombre d'incréments



Vector TYPE = array [-NUMINV..NUMINV] double;



VAR

K: integer; // Contre

DELTA: Double; Étape //

X: Double; Point de // intervalle réel

ABSCISSE: ^ VECTOR; // Vecteur de valeurs de points d'intervalle

FX: ^ VECTOR; // Vectorielle des valeurs de la fonction de densité

CDF: VECTOR; // Vectorielle des valeurs de la fonction de densité cumulée



// Génère une valeur de la fonction de densité gaussienne norme}



La fonction f (x: Double): Double;

Commencer

F: = EXP (-X * X/2)/RACINE (PI + PI);

Fin;



PROCÉDURE gaussien; {Obtenir la fonction de densité normale}

Commencer

FillChar (cdf, sizeof (cdf), 0);

cdf [0] = 0,5;

cdf [-1]: = 0,5;

CDF [1]: = 0,5;

DELTA: NUMINV * = 2;

DELTA: = (X2-X1)/DELTA; {La plus haute résolution d'écran possible}

X: = X1-DELTA;

K: = - NUMINV;

REPEAT

inc (k);

X: = X + DELTA;

ABSCISSE ^ [K]: = X; {Les valeurs de l'axe X}

FX ^ [K]: = F (X); {Les valeurs de l'axe Y}

UP K = NUMINV;

Fin;



procédure generateCDF;

Gamme Const = 0.2316419; a1 =, 319 381 530;

a2 = -0,356563782; a3 = 1,781477937;

a4 = -1,821255987; A5 = 1,330274429;



VAR

k1, k2, K3, K4, K5: DOUBLE;

I: Integer;



Commencer

nouveau (fx);

nouveau (abscisse);

Gaussienne;

POUR I: = 0 pour une NUMINV

SE ABSCISSE ^ [I]> 0.0 PUIS

Commencer

k1: = 1.0/(1.0 + gamme * ABSCISSE ^ [I]);

k2: = SQR (k1);

k3: = k1 * k2;

K4: = SQR (K2);

k5: k4 = k1 *;

cdf [I]: = 1,0 - FX ^ [I] * (a1 * k1 + k2 + a2 * a3 * + k3 k4 k5 * A4 * + a5);

Fin;

pour i: = -1 -NUMINV à faire

cdf [I]: = 1-cdf [-i];

disposer (en abscisse);

disposer (fx);

Fin;



Entrez // avec -4
travailler GetCDF (xd: double): Double; stdcall;

var x: Double;

commencer

x: = xd;

si x> 4.0 puis

x: = 4,0;

si x <-4,0 alors

x: = - 4,0;

Résultat: = CDF [tout (x * 10000)];

fin;



// Fonction principale

Fonction Register_GetCDF: integer;

var s: ShortString;

commencer

Res.xltype: = xltypeerr;

Res.val.err: = xlerrvalue;

s: = GetName;

pxModuleText.SetStr (s);

pxProcedure.SetStr ('GetCDF');

pxTypeText.SetStr ('BB!'); // Double, Double

pxFunctionText.setStr ('GetCDF');

pxArgumentText.SetStr ('value');

pxMacrotype.SetNum (1);

pxCategory.SetStr (AddInCategory);



EResult: = Excel4V (xlfregister, @ res, 8,

[PxModuletext.thelpxloper,

pxProcedure.thelpxloper,

pxTypeText.thelpxloper,

pxFunctionText.thelpxloper,

pxArgumentText.thelpxloper,

pxMacroType.thelpxloper,

pxCategory.thelpxloper,

zlpxloper]);

évier pop asm; fin; // Jamais Retirer

Résultat: = tronc (res.val.num);

fin;



// Valeur Excel pile affiche

Fonction LastError: lpxloper; stdcall;

commencer

LastErrorxl.xltype: = xltypestr;

LastErrorxl.val.Str: = @ LastErrorStr;

Résultat: = LastErrorxl;

fin;



Fonction Register_LastError: integer;

var s: ShortString;

commencer

Res.xltype: = xltypeerr;

Res.val.err: = xlerrvalue;

s: = GetName;

pxModuleText.SetStr (s);

pxProcedure.SetStr ('LastError');

pxTypeText.SetStr ('R!'); // Lpxloper

pxFunctionText.setStr ('LastError');

pxArgumentText.SetStr ('');

pxMacrotype.SetNum (1);

pxCategory.SetStr (AddInCategory);



EResult: = Excel4V (xlfregister, @ res, 8,

[PxModuletext.thelpxloper,

pxProcedure.thelpxloper,

pxTypeText.thelpxloper,

pxFunctionText.thelpxloper,

pxArgumentText.thelpxloper,

pxMacroType.thelpxloper,

pxCategory.thelpxloper,

zlpxloper]);

évier pop asm; fin; // Jamais Retirer

Résultat: = tronc (res.val.num);

fin;



// Fonction exportée affiche la valeur de invisible Excel Stack

Fonction GetXlStack: lpxloper; stdcall;

commencer

EResult: = Excel4V (XlStack, @ res, 1, [zéro]);

évier pop asm; fin; // Jamais Retirer

Résultat: = res;

fin;



Fonction Register_GetXLStack: integer;

var s: ShortString;

commencer

Res.xltype: = xltypeerr;

Res.val.err: = xlerrvalue;

s: = GetName;

pxModuleText.SetStr (s);

pxProcedure.SetStr ('GetXlStack');

pxTypeText.SetStr ('R!');

pxFunctionText.setStr ('GetXlStack');

pxArgumentText.SetStr ('');

pxMacrotype.SetNum (0); // 0 = invisible, 1 = visible

pxCategory.SetStr (AddInCategory);



EResult: = Excel4V (xlfregister, @ res, 8,

[PxModuletext.thelpxloper,

pxProcedure.thelpxloper,

pxTypeText.thelpxloper,

pxFunctionText.thelpxloper,

pxArgumentText.thelpxloper,

pxMacroType.thelpxloper,

pxCategory.thelpxloper,

zlpxloper]);

évier pop asm; fin; // Jamais Retirer

Résultat: = tronc (res.val.num);

fin;



// Fonction exporté

Fonction Version: lpxloper; stdcall;

commencer

xvalue.xltype: = xltypeStr;

xvalue.val.str: = DLLVersion;

Résultat: = xValue;

fin;



fonction de Register_Version: integer;

var s: ShortString;

commencer

Res.xltype: = xltypeerr;

Res.val.err: = xlerrvalue;

s: = GetName;

pxModuleText.SetStr (s);

pxProcedure.SetStr («Version»);

pxTypeText.SetStr ('R!');

pxFunctionText.setStr («Version»);

pxArgumentText.SetStr ('');

pxMacrotype.SetNum (1);

pxCategory.SetStr (AddInCategory);



EResult: = Excel4V (xlfregister, @ res, 8,

[PxModuletext.thelpxloper,

pxProcedure.thelpxloper,

pxTypeText.thelpxloper,

pxFunctionText.thelpxloper,

pxArgumentText.thelpxloper,

pxMacroType.thelpxloper,

pxCategory.thelpxloper,

zlpxloper]);

évier pop asm; fin; // Jamais Retirer

Résultat: = tronc (res.val.num);

fin;



// Fonction exporté

Fonction FreeRAM: integer; stdcall;

commencer

Résultat: = GetHeapStatus.TotalFree;

fin;



Fonction Register_FreeRam: integer;

var s: ShortString;

commencer

Res.xltype: = xltypeerr;

Res.val.err: = xlerrvalue;

s: = GetName;

pxModuleText.SetStr (s);

pxProcedure.SetStr ('FreeRAM');

pxTypeText.SetStr ('J!');

pxFunctionText.setStr ('FreeRAM');



























fin;



fin;





commencer



Sortie;

















































fin;













commencer





fin;

fin;



commencer















fin;





stdcall;

commencer



Résultat: = 1;

fin;



stdcall;

commencer







Résultat: = 1;

fin;



stdcall;





commencer







fin;



commencer





fin

autre

commencer





fin;



fin;



stdcall;

commencer



fin;



stdcall;

commencer





Résultat: = 1;

fin;



stdcall;

commencer





Résultat: = 1;

fin;



stdcall;

commencer



fin;





commencer

Créer hérité;





fin;





commencer

Destroy héritée;

fin;





commencer

Créer hérité;







fin;





commencer









fin;





commencer





fin;





commencer





fin;





commencer





fin;





commencer



fin;



exportations



































commencer



fin.





Commentaires (0)
Sans commentaires

Ajouter un commentaire

smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile
Caractères restants: 3000
captcha