L'accès rapide aux données foxpro à partir de delphi


l'Accès de données FoxPro à l'aide de la vitesse de Rushmore dans Delphi.

Développeur Delphijanvier 1999
droit d'Auteur Pinnacle Publishing, Inc. Tous droits réservés.un Accès Rapide aux Données FoxPro à partir de Delphi
Steve Zimmelman

Quand Borland a annoncé que Delphi 3 allait avoir FoxPro DBF/CDX pilotes, il y avait une certaine excitation à partir de FoxPro développeurs qui tentaient de migrer leurs applications Delphi. L'enthousiasme a été de courte durée, cependant, quand ils ont réalisé que les pilotes n'ont pas le même punch que leurs natif cousin. La petite DLL OLE présenté dans cet article pourrait être le pont qui apporte enfin les deux ensemble.

j'ai récemment développé une application pour notre entreprise en Delphi 3 qui lit les tables dans notre FoxPro DOS système d'héritage. Tout s'est bien passé en version bêta, donc nous avons commencé à distribuer de la demande de nos clients. Il y avait, cependant, une surveillance. Nous n'avons jamais testé le système sur des tables qui ont été fortement peuplées. Quand nous avons installé l'application à l'un de nos plus grand client des sites, l'application est tombé à ses genoux et il est mort. Le problème: Le BDE a été de tenter certaines requêtes complexes à l'aide de SQL Local contre une table qui avait environ 2 millions de disques. Notre client nous a informés que les requêtes ont été jusqu'à 72 heures. Bien sûr, cela n'est pas acceptable, alors j'ai commencé à explorer d'autres façons de l'exécution de requêtes. Le résultat a été un Visual FoxPro (VFP) objet OLE dans la forme d'une DLL qui exécute les requêtes (ou presque toute commande FoxPro) à partir de Delphi, de manière transparente, et avec la vitesse de Rushmore. Grâce à cette technologie, la durée de la requête a chuté de quelques heures à quelques secondes.
Pour ceux qui ne sont pas familiers avec Visual FoxPro, il a une fonction appelée Substitution Macro, qui est à la base de la DLL OLE. La Substitution Macro traite le contenu d'une variable de mémoire comme un littéral de chaîne de caractères. Quand une esperluette ( & ) précède un type de chaîne variable de mémoire, le contenu de la variable est traitée comme une main-commande tapée, et est exécuté.
le code de La VFP DLL OLE est en fait très simple, et peut contenir aussi peu que un seul de procédure ou de fonction. J'ai choisi d'écrire quelques procédures spécifiques à l'application, mais aussi inclus quelques génériques qui peuvent être utilisés par n'importe quelle application. Par souci de simplicité, j'ai inclus seulement le générique de procédures et de fonctions dans le code ci-dessous.

**************************************
* Programme: VFP_OLE.PRG
* Visual FoxPro 5 DLL OLE
**************************************
permet de DÉFINIR la CLASSE VFP_OLE_Server COMME CONTENEUR OLEPUBLIC
& nbsp & nbsp & nbsp Procédure Init
& ! & ! & ! & ! & ! & nbsp * La Procédure INIT est automatiquement
& ! & ! & ! & ! & ! & nbsp * exécutée lorsque la DLL est chargée.
& ! & ! & ! & ! & ! & nbsp Set Parler Off
& ! & ! & ! & ! & ! & nbsp Sécurité Off
& ! & ! & ! & ! & ! & nbsp Erreur Ne Ole_Err Avec l'Erreur(),Lineno(),le Message(),Programme()
& ! & ! & ! & ! & ! & nbsp Set Exclusif
& ! & ! & ! & ! & ! & nbsp Set Null
& ! & ! & ! & ! & ! & nbsp *****************************************
& ! & ! & ! & ! & ! & nbsp * & Si CPDIALOG est SUR et un DBF qui a été
& ! & ! & ! & ! & ! & nbsp * & créé sans une page de Codes est ouvert,
& ! & ! & ! & ! & ! & nbsp * & la page de Codes de la Boîte de Dialogue se confronter
& ! & ! & ! & ! & ! & nbsp * & l'utilisateur.
& ! & ! & ! & ! & ! & nbsp *****************************************
& ! & ! & ! & ! & ! & nbsp ENSEMBLE CPDIALOG OFF
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Jeu de Retraiter À 1
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * Déplacer Foxpro écran principal moyen de sortir de la bit-seau
& ! & ! & ! & ! & ! & nbsp * afin de ne pas être vu si elle est visible.
& ! & ! & ! & ! & ! & nbsp Déplacer la Fenêtre de l'Écran À -1000,-1000
& ! & ! & ! & ! & ! & nbsp Modifier l'Écran de la Fenêtre de Titre 'VFP OLE'
& ! & ! & ! & ! & ! & nbsp Masquer l'Écran de la Fenêtre
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procédure SetDir
& nbsp & nbsp & nbsp Paramètre du redc
& ! & ! & ! & ! & ! & nbsp Définir par Défaut (m.redc)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Fonction ExeSql
& ! & ! & ! & ! & ! & nbsp Paramètre cSql
& ! & ! & ! & ! & ! & nbsp Privé nRecs,j',cFile,cFileSrc,cFullPath,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cDestpath,cAlias,IsVFPFile,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cDbfFileName,nHandle
& ! & ! & ! & ! & ! & nbsp lIsVFPFile = .F.
& ! & ! & ! & ! & ! & nbsp cFullPath = Set('FullPath')
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * Afficher le Principal VFP Fenêtre pour le Fichier
& ! & ! & ! & ! & ! & nbsp * boîte de dialogue sera visible
& ! & ! & ! & ! & ! & nbsp * si VFP ne peut pas trouver un fichier
& ! & ! & ! & ! & nbsp & nbsp * est nécessaire pour la commande SQL.
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Afficher l'Écran de la Fenêtre
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * & Exécution de l'Instruction SQL & *
& ! & ! & ! & ! & ! & nbsp *
& nbsp & nbsp & ! & ! & ! & nbsp cSql = AllTrim(m.cSql)
& ! & ! & ! & ! & ! & ! & cSql
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Masquer l'Écran de la Fenêtre
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp nRecs = _Tally
& ! & ! & nbsp & nbsp & nbsp & nbsp *
& ! & ! & ! & ! & ! & nbsp Ensemble FullPath Sur
& ! & ! & ! & ! & ! & nbsp cFileSrc = DBF()
& ! & ! & ! & ! & ! & nbsp Utiliser
& ! & ! & ! & ! & ! & nbsp **************************************
& ! & ! & ! & ! & ! & nbsp * & Check tableau tapez.
& ! & ! & ! & ! & ! & nbsp * & Si le Type Est Visual FoxPro Convertir
& ! & ! & ! & ! & ! & nbsp * & à Fox2x.
& ! & ! & ! & ! & ! & nbsp * & Le BDE ne prend pas en charge VFP tables
& ! & ! & ! & ! & ! & nbsp **************************************
& ! & ! & ! & ! & ! & nbsp nHandle = FOpen(m.cFileSrc)
& ! & ! & ! & ! & ! & nbsp Si nHandle <> -1
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp lIsVFPFile = (FGets(m.nHandle,1)=Chr(48))
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp =FClose(m.nHandle)
& ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & nbsp Utiliser (m.cFileSrc) Exclusive
& ! & ! & ! & ! & ! & nbsp cDestPath = gauche(dbf(),rat('\',dbf()))
& ! & ! & ! & ! & ! & nbsp Si m.lIsVFPFile
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp * & Convertir Résultat À Fox2x Format & *
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp cFile = 'T' droite(sys(3),7)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie À m.cDestPath m.cFile) Type Fox2x
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Utiliser
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Effacer (m.cFileSrc)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Si le Fichier(à Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Effacer (à Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Renommer (m.cDestPath m.cFile '.DBF')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp À m.cFileSrc)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Si le Fichier(m.cDestPath m.cFile '.FPT')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Renommer (m.cDestPath m.cFile '.FPT')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp (à Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Utiliser (m.cFileSrc) Exclusive
& ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & nbs * & Restaurer FullPath Paramètre & *
& ! & ! & ! & ! & ! & nbsp Ensemble FullPath & cFullPath
& ! & ! & ! & ! & ! & nbsp ** & Résultat de Retour le nombre d'Enregistrement & **
& ! & ! & ! & ! & ! & nbsp Retour (m.nRecs)
& nbsp & nbsp & nbsp EndFunc
& nbsp & nbsp & nbsp Procédure SetPath
& ! & ! & ! & ! & ! & nbsp Paramètre cPath
& ! & ! & ! & ! & ! & nbsp Définir le Chemin d'accès À m.cPath)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procédure FoxCommand
& ! & ! & ! & ! & ! & nbsp Paramètre ccg
& ! & ! & ! & ! & ! & ! & ccg
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Fonction FoxFunction
& ! & ! & ! & ! & ! & nbsp Paramètre cFunc
& ! & ! & ! & ! & ! & nbsp Privé Rtn
& ! & ! & ! & ! & ! & nbsp Rtn = & cFunc
& ! & ! & ! & ! & ! & nbsp Retour (m.Rtn)
& nbsp & nbsp & nbsp EndFunc
ENDDEFINE
Procédure Ole_Err
& nbsp & nbsp & nbsp ** & Poignée DLL Erreurs internes & **
& nbsp & nbsp & nbsp Paramètre nErr,nLine,cMessage,cPRG
& nbsp & nbsp & nbsp SI (m.nErr=1707)
& ! & ! & ! & ! & ! & nbsp * & CDX présente pas, OK pour Réessayer & *
& ! & ! & ! & ! & ! & nbsp Réessayer
& nbsp & nbsp & nbsp Else
& ! & ! & ! & ! & ! & nbsp MessageBox( m.cMessage Chr(13) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Erreur '# ' str(m.nErr,5) Chr(13)
&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!', À la Ligne de#' Str(m.nLine,5) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! 'Dans' m.cPrg chr(13) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ' Voir File:OLE_ERR.TXT pour plus de détails.'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ,16, 'ERREUR dans le VFP_OLE.DLL Module')
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * & Dump de la Mémoire et de l'État des Fichiers dans un Fichier Texte.
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Créer Curseur OleError (ErrText M(10))
& ! & ! & ! & ! & ! & nbsp État de la Liste des NoConsole De Fichier OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Liste de la Mémoire Comme * NoConsole De Fichier OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp Append Blank
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Répliquer('*',80) Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp DTOC(Date()) '' Time()
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc(' STATUS ',80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10)
& ! & ! & ! & ! & ! & nbsp Ajouter Memo ErrText De OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc (la 'MÉMOIRE', 80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10) Addi
& ! & ! & ! & ! & ! & nbsp Ajouter Memo ErrText De OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc ('la Fin de l'Erreur & ',80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10) Addi
& ! & ! & ! & ! & ! & nbsp Si le Fichier('OLE_ERR.TXT')

& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie du Mémo ErrText À OLE_ERR.TXT Addi
& ! & ! & ! & ! & ! & nbsp Else
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie du Mémo ErrText À OLE_ERR.TXT
& ! & ! & ! & ! & ! & nbsp Endif
& nbsp & nbsp & ! & ! & ! & nbsp Effacer OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Effacer OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Proche de Données
& ! & ! & ! & ! & ! & nbsp Masquer l'Écran de la Fenêtre
& ! & ! & ! & ! & ! & nbsp * & La commande ANNULER causes Delphi
& ! & ! & ! & ! & ! & nbsp * & pour être en mesure d'intercepter l'erreur.
& ! & ! & ! & ! & ! & nbsp Annuler
& ! & ! & ! & ! & ! & nbsp *
& nbsp & nbsp & nbsp Endif
EndProc
*:EOF(VFP_OLE.PRG)

une fois la DLL compilée, il doit être enregistré auprès de REGSVR32.EXE qui est distribué avec windows 95 et NT et devrait être dans le répertoire \Windows\System pour windows 95 et \Windows\System32 pour NT. Toutefois, ce processus peut être automatisé par l'Delphi application lors de l'exécution. (voir la fonction RegisterDLL)
Dans une application Delphi, j'ai créé une méthode qui tente d'instancier la DLL lors de l'exécution, et un autre pour enregistrer la DLL si l'instanciation de la méthode échoue. En outre, j'ai 2 variables globales: vFoxOle et bIsFoxOle. vFoxOle est une Variante qui pointe vers l'objet OLE et bIsFoxOle est un Booléen qui indique à l'application si l'objet OLE a été correctement instancié. De cette façon, je peux écrire l'application pour gérer les Données FoxPro avec le VFP OLE ou le BDE. Vous devez également disposer d'une référence à ComObj dans les 'Usages' de la clause de la forme qui instancie la DLL.
Dans le Formulaire de création de la méthode, j'ai appeler la Fonction IsFoxOle pour instancier la DLL OLE. Le Delphi fonction CreateOleObject() est utilisé pour créer une connexion à l'objet OLE et retourne un pointeur vers l'objet qui est stockée dans la variable vFoxOle. CreateOleObject() est utilisée avec un paramètre de chaîne de points de la Classe qui est instanciée. Dans ce cas, le nom de la DLL est VFP_OLE et la Classe est VFP_OLE_Server. Donc, pour faire un lien que j'ai utilisé CreateOleObject('VFP_OLE.VFP_OLE_Server').

procédure TfrmFox.FormCreate(Sender: TObject)
Begin
& nbsp & nbsp & nbsp Si Pas IsFoxOle Puis Commencer
& ! & ! & ! & ! & ! & nbsp RegisterDLL
& ! & ! & ! & ! & ! & nbsp // initialisation de bIsFoxOle avec le résultat
& ! & ! & ! & ! & ! & nbsp // de la tentative d'instanciation. Si le fournisseur OLE
& ! & ! & ! & ! & ! & nbsp // objet a été enregistré, le résultat
& ! & ! & ! & ! & ! & nbsp // sera vrai.
& ! & ! & ! & ! & ! & nbsp bIsFoxOle := IsFoxOle
& nbsp & nbsp & nbsp Fin Else
& ! & ! & ! & ! & ! & nbsp bIsFoxOle := True
Fin
Fonction de TFrmFox.IsFoxOle : Boolean
Begin
& nbsp & nbsp & nbsp Essayer
& ! & ! & ! & ! & ! & nbsp // Instancier l'objet OLE
& ! & ! & ! & ! & ! & nbsp vFoxOle :=
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp CreateOleObject('VFP_OLE.VFP_OLE_Server')
& ! & ! & ! & ! & ! & nbsp Result := True
& nbsp & nbsp & nbsp à l'Exception de
& ! & ! & ! & ! & ! & nbsp Result := False
& nbsp & nbsp & nbsp Fin
Fin
Procédure TFrmFox.RegisterDLL
// Si REGSVR32.EXE existe RegisterDLL()
// va chercher VFP_OLE.DLL
// à 2 endroits:
// 1) \Windows\System
// 2) le répertoire courant
var A : Array[0..100] of Char
& ! & ! & ! & nbsp sSysDir : String
& ! & ! & ! & nbsp sCurDir : String
Begin
& nbsp & nbsp & nbsp GetSystemDirectory(@A, 100)
& nbsp & nbsp & nbsp sSysDir := A
& nbsp & nbsp & nbsp sSysDir := AddBS(sSysDir)
& nbsp & nbsp & nbsp sCurDir := AddBS(GetCurrentDir)
& nbsp & nbsp & nbsp if FileExists(sSysDir 'REGSVR32.EXE'), Puis Commencer
& ! & ! & ! & ! & ! & nbsp if FileExists(sSysDir 'VFP_OLE.DLL') Ensuite, Commencez
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! ''' sSysDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& ! & ! & ! & ! & ! & nbsp Fin Else if FileExists(sCurDir 'VFP_OLE.DLL') Ensuite, Commencez
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! ''' sCurDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& ! & ! & ! & ! & ! & nbsp Fin
& nbsp & nbsp & nbsp End Else Begin
& ! & ! & ! & ! & ! & nbsp Raise Exception.Create('Ne peut pas s'Inscrire VFP_OLE.DLL !')
& nbsp & nbsp & nbsp Fin
Fin

Pratique à Utiliser
Supposons que vous avez une Facture de l'application et vous devez savoir combien d'argent est due, l'âge, et qui les doit. Votre formulaire de requête pourrait ressembler à ceci:
(Insérer un Fichier: QForm1.BMP ici)
Lorsque l'utilisateur clique sur le bouton OK, l'instruction SQL est créé dynamiquement et envoyé à la DLL en tant que paramètre de traitement. Il est important de noter que la chaîne SQL a un 'Dans la Table' dans le cadre de l'instruction. Sans cela, le Delphi application n'a aucun moyen de ramasser les données de résultat. Il y a 3 manières de gérer la création de la Table: 1) Créer la table sur les utilisateurs locaux répertoire temporaire avec un nom de fichier statique. 2) Écrire une fonction qui crée un nom de fichier unique ou utiliser la fonction Windows API GetTempFileName(). 3) Combiner les deux 1 & 2 et de créer un nom unique dans le répertoire Temp de Windows. Pour les environnements réseau, je trouve que l'option 3 est la plus sûre. Il est également important d'utiliser la méthode SetDir() avant et après l'exécution de la Requête. C'est donc FoxPro sait où trouver les tables c'est interrogée contre, et Delphi application peut trouver son chemin de retour à la maison. Si vous n'avez pas SetDir() après la requête, alors il ya une assez bonne chance que le Delphi application ne sera pas en mesure de trouver les composants externes tels que AVI, BMP, WAV ou fichiers dont il a besoin. C'est parce que FoxPro change physiquement le répertoire pointeur.
Cet exemple suppose que l'DBF tables sont dans le même répertoire que le Delphi exécutable. La fonction GetTempDir() est une simple fonction wrapper qui utilise l'API Windows pour obtenir le répertoire temp de windows. L'instruction SQL Select dynamique est créé sur la base des Jours de retard, et le résultat de la table est créée dans le répertoire Temp de Windows dans un fichier appelé MyQuery.dbf. Après MyQuery.dbf est créé, la Table1 objet est affecté à son contenu et affichées dans la grille.

procédure TfrmFox.btnExeQueryClick(Sender: TObject)
Var
& nbsp & nbsp & nbsp sSQLText : String
& nbsp & nbsp & nbsp rieds : Integer
& nbsp & nbsp & nbsp sAppDir : String
begin
& nbsp & nbsp & nbsp Si bIsFoxOle Puis Commencer
& ! & ! & ! & ! & ! & nbsp // Obtenir le chemin d'accès au répertoire de l'application
& ! & ! & ! & ! & ! & nbsp sAppDir :=
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp ExtractFilePath(Application.ExeName)
& ! & ! & ! & ! & ! & nbsp Si (e_PastDue.Text= ')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp e_PastDue.Text := '0'
& ! & ! & ! & ! & ! & nbsp sSQLText :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Select Client.Nom,'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' de la Facture.AcctNo, Facture.Balance,'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (Date()-Facture.La Date) Que l'Âge'
&!&!&!&!&!&!&!&!&!', Du Client,la Facture d'
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Où'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (le Client.AcctNo = Facture.AcctNo) Et'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (Date()-Facture.Date) >= ' e_PastDue.Texte
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' la Commande Par le Client.Le nom,l'Âge'
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Dans la Table' GetTempDir() 'MyQuery'
& ! & ! & ! & ! & ! & nbsp // assurez-vous que l'objet de la table qui lit
& ! & ! & ! & ! & ! & nbsp // le résultat est fermé avant de la requête
& ! & ! & ! & ! & ! & nbsp // est exécuté.
& ! & ! & ! & ! & ! & nbsp Si Table1.Actif, Puis Commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.Fermer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // assurez-vous que la table est supprimée après la clôture
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.DeleteTable
& ! & ! & ! & ! & ! & nbsp Fin
& ! & ! & ! & ! & ! & nbsp // affectation temporaire le nom du fichier à Table1
& ! & ! & ! & ! & ! & nbsp Table1.TableName := 'MyQuery.DBF'
& ! & ! & ! & ! & ! & nbsp // affecter le Répertoire temporaire sur Table1
& ! & ! & ! & ! & ! & nbsp Table1.DatabaseName := GetTempDir()
& ! & ! & ! & ! & ! & nbsp // VFP Répertoire par Défaut où l'
& ! & ! & ! & ! & ! & nbsp // Fox DBFs sont stockées.
& ! & ! & ! & ! & ! & nbsp vFoxOle.SetDir(sAppDir)
& ! & ! & ! & ! & ! & nbsp // Exécution de la Requête
& ! & ! & ! & ! & ! & nbsp rieds := vFoxOle.ExeSql(sSQLText)
& ! & ! & ! & ! & ! & nbsp Label7.Caption := IntToStr(rieds)
& ! & ! & ! & ! & ! & nbsp Si (rieds = 0) Then
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp MessageDlg('Aucun enregistrement Trouvé Dans la Requête!'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ,mtInformation,[bakang],0)
& ! & ! & ! & ! & ! & nbsp Else Begin
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // ExeSql() les feuilles le résultat de la table ouvrir
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // de sorte que vous pouvez les pré-traiter la table
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // VFP avant de Delphes qu'il Ouvre.
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Ces Indices sont utilisés pour modifier
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // l'ordre de tri en cliquant sur le
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Grille de Titre.
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Index Sur Nom Nom de la Balise')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand (Indice Sur l'Âge de la Balise de l'Âge')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Index Sur AcctNo Tag AcctNo')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand (Indice Sur l'Équilibre de la Balise Équilibre')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Fermer la Base de données')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.Ouvert
& ! & ! & ! & ! & ! & nbsp Fin
& nbsp & nbsp & nbsp End Else Begin
& ! & ! & ! & ! & ! & nbsp MessageDlg('VFP_OLE.DLL Non Instancié!',
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mtError,[bakang])
& nbsp & nbsp & nbsp Fin // Si bIsFoxOle
fin

Avec cette DLL vous avez la possibilité de réaliser à partir de Delphi, presque rien que vous pouvez faire à partir de FoxPro. Ce n'est pas seulement limitée à la simple Substitution de Macro, mais peut être utilisé pour développer Delphi frontaux qui utilisent l'ensemble de la base de données Visual FoxPro structure. Maintenant, je ne dis pas que nous commençons tous à l'aide de Visual FoxPro pour notre back-ends, mais elle permet de faire un joli pont pour ceux d'entre nous qui sont de la migration de notre DOS et les applications Windows à partir de FoxPro pour Delphi et besoin de la vitesse de Rushmore.
Il y a quelques mises en garde de cette technologie à l'aide de Visual FoxPro, vous devez être conscient de:

  • la gestion d'Erreur est limité. Si une instruction SQL fait référence à une table FoxPro ne pouvez pas le trouver, il ouvre une boîte de dialogue demandant à l'utilisateur le chemin de la mystérieuse table. Seulement après que la touche échap il va générer une erreur récupérable. Donc, il pourrait être prudent de vérifier l'existence des tables avec le Delphi fonction FileExists(), avant d'exécuter la requête.
  • les résultats de La requête sont parfois retournés dans Visual FoxPro format de fichier, quelque chose de Delphi n'est pas actuellement pris en charge. Le résultat doit être converti par la DLL, ce qui peut prendre plus de temps pour le processus.
  • Il y a 2 runtime de Visual FoxPro Dll qui doivent être distribués avec le Delphi application ajouter environ 3,9 mo pour la taille globale de l'application.
  • afin de pouvoir distribuer le runtime de Visual FoxPro Dll ou créer la DLL OLE, vous devez posséder une copie de Visual FoxPro version Professionnelle de 5 ou plus.
    Depuis les Modifications de Cet Article a Été WrittenVisual FoxPro version 6 et plus ne fonctionnent pas avec la DLL. Vous devez compiler l'objet COM dans un fichier EXE. L'EXE peuvent être enregistrés par l'exécution d'une fois sur l'ordinateur qui sera accès. RegSvr32.exe n'est plus nécessaire.









L'acces rapide aux donnees foxpro a partir de delphi


L'acces rapide aux donnees foxpro a partir de delphi : Plusieurs milliers de conseils pour vous faciliter la vie.


l'Acces de donnees FoxPro a l'aide de la vitesse de Rushmore dans Delphi.

Developpeur Delphijanvier 1999
droit d'Auteur Pinnacle Publishing, Inc. Tous droits reserves.un Acces Rapide aux Donnees FoxPro a partir de Delphi
Steve Zimmelman

Quand Borland a annonce que Delphi 3 allait avoir FoxPro DBF/CDX pilotes, il y avait une certaine excitation a partir de FoxPro developpeurs qui tentaient de migrer leurs applications Delphi. L'enthousiasme a ete de courte duree, cependant, quand ils ont realise que les pilotes n'ont pas le meme punch que leurs natif cousin. La petite DLL OLE presente dans cet article pourrait etre le pont qui apporte enfin les deux ensemble.

j'ai recemment developpe une application pour notre entreprise en Delphi 3 qui lit les tables dans notre FoxPro DOS systeme d'heritage. Tout s'est bien passe en version beta, donc nous avons commence a distribuer de la demande de nos clients. Il y avait, cependant, une surveillance. Nous n'avons jamais teste le systeme sur des tables qui ont ete fortement peuplees. Quand nous avons installe l'application a l'un de nos plus grand client des sites, l'application est tombe a ses genoux et il est mort. Le probleme: Le BDE a ete de tenter certaines requetes complexes a l'aide de SQL Local contre une table qui avait environ 2 millions de disques. Notre client nous a informes que les requetes ont ete jusqu'a 72 heures. Bien sûr, cela n'est pas acceptable, alors j'ai commence a explorer d'autres façons de l'execution de requetes. Le resultat a ete un Visual FoxPro (VFP) objet OLE dans la forme d'une DLL qui execute les requetes (ou presque toute commande FoxPro) a partir de Delphi, de maniere transparente, et avec la vitesse de Rushmore. Grace a cette technologie, la duree de la requete a chute de quelques heures a quelques secondes.
Pour ceux qui ne sont pas familiers avec Visual FoxPro, il a une fonction appelee Substitution Macro, qui est a la base de la DLL OLE. La Substitution Macro traite le contenu d'une variable de memoire comme un litteral de chaîne de caracteres. Quand une esperluette ( & ) precede un type de chaîne variable de memoire, le contenu de la variable est traitee comme une main-commande tapee, et est execute.
le code de La VFP DLL OLE est en fait tres simple, et peut contenir aussi peu que un seul de procedure ou de fonction. J'ai choisi d'ecrire quelques procedures specifiques a l'application, mais aussi inclus quelques generiques qui peuvent etre utilises par n'importe quelle application. Par souci de simplicite, j'ai inclus seulement le generique de procedures et de fonctions dans le code ci-dessous.

**************************************
* Programme: VFP_OLE.PRG
* Visual FoxPro 5 DLL OLE
**************************************
permet de DEFINIR la CLASSE VFP_OLE_Server COMME CONTENEUR OLEPUBLIC
& nbsp & nbsp & nbsp Procedure Init
& ! & ! & ! & ! & ! & nbsp * La Procedure INIT est automatiquement
& ! & ! & ! & ! & ! & nbsp * executee lorsque la DLL est chargee.
& ! & ! & ! & ! & ! & nbsp Set Parler Off
& ! & ! & ! & ! & ! & nbsp Securite Off
& ! & ! & ! & ! & ! & nbsp Erreur Ne Ole_Err Avec l'Erreur(),Lineno(),le Message(),Programme()
& ! & ! & ! & ! & ! & nbsp Set Exclusif
& ! & ! & ! & ! & ! & nbsp Set Null
& ! & ! & ! & ! & ! & nbsp *****************************************
& ! & ! & ! & ! & ! & nbsp * & Si CPDIALOG est SUR et un DBF qui a ete
& ! & ! & ! & ! & ! & nbsp * & cree sans une page de Codes est ouvert,
& ! & ! & ! & ! & ! & nbsp * & la page de Codes de la Boîte de Dialogue se confronter
& ! & ! & ! & ! & ! & nbsp * & l'utilisateur.
& ! & ! & ! & ! & ! & nbsp *****************************************
& ! & ! & ! & ! & ! & nbsp ENSEMBLE CPDIALOG OFF
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Jeu de Retraiter A 1
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * Deplacer Foxpro ecran principal moyen de sortir de la bit-seau
& ! & ! & ! & ! & ! & nbsp * afin de ne pas etre vu si elle est visible.
& ! & ! & ! & ! & ! & nbsp Deplacer la Fenetre de l'Ecran A -1000,-1000
& ! & ! & ! & ! & ! & nbsp Modifier l'Ecran de la Fenetre de Titre 'VFP OLE'
& ! & ! & ! & ! & ! & nbsp Masquer l'Ecran de la Fenetre
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedure SetDir
& nbsp & nbsp & nbsp Parametre du redc
& ! & ! & ! & ! & ! & nbsp Definir par Defaut (m.redc)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Fonction ExeSql
& ! & ! & ! & ! & ! & nbsp Parametre cSql
& ! & ! & ! & ! & ! & nbsp Prive nRecs,j',cFile,cFileSrc,cFullPath,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cDestpath,cAlias,IsVFPFile,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp cDbfFileName,nHandle
& ! & ! & ! & ! & ! & nbsp lIsVFPFile = .F.
& ! & ! & ! & ! & ! & nbsp cFullPath = Set('FullPath')
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * Afficher le Principal VFP Fenetre pour le Fichier
& ! & ! & ! & ! & ! & nbsp * boîte de dialogue sera visible
& ! & ! & ! & ! & ! & nbsp * si VFP ne peut pas trouver un fichier
& ! & ! & ! & ! & nbsp & nbsp * est necessaire pour la commande SQL.
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Afficher l'Ecran de la Fenetre
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * & Execution de l'Instruction SQL & *
& ! & ! & ! & ! & ! & nbsp *
& nbsp & nbsp & ! & ! & ! & nbsp cSql = AllTrim(m.cSql)
& ! & ! & ! & ! & ! & ! & cSql
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Masquer l'Ecran de la Fenetre
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp nRecs = _Tally
& ! & ! & nbsp & nbsp & nbsp & nbsp *
& ! & ! & ! & ! & ! & nbsp Ensemble FullPath Sur
& ! & ! & ! & ! & ! & nbsp cFileSrc = DBF()
& ! & ! & ! & ! & ! & nbsp Utiliser
& ! & ! & ! & ! & ! & nbsp **************************************
& ! & ! & ! & ! & ! & nbsp * & Check tableau tapez.
& ! & ! & ! & ! & ! & nbsp * & Si le Type Est Visual FoxPro Convertir
& ! & ! & ! & ! & ! & nbsp * & a Fox2x.
& ! & ! & ! & ! & ! & nbsp * & Le BDE ne prend pas en charge VFP tables
& ! & ! & ! & ! & ! & nbsp **************************************
& ! & ! & ! & ! & ! & nbsp nHandle = FOpen(m.cFileSrc)
& ! & ! & ! & ! & ! & nbsp Si nHandle <> -1
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp lIsVFPFile = (FGets(m.nHandle,1)=Chr(48))
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp =FClose(m.nHandle)
& ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & nbsp Utiliser (m.cFileSrc) Exclusive
& ! & ! & ! & ! & ! & nbsp cDestPath = gauche(dbf(),rat('\',dbf()))
& ! & ! & ! & ! & ! & nbsp Si m.lIsVFPFile
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp * & Convertir Resultat A Fox2x Format & *
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp cFile = 'T' droite(sys(3),7)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie A m.cDestPath m.cFile) Type Fox2x
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Utiliser
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Effacer (m.cFileSrc)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Si le Fichier(a Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Effacer (a Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Renommer (m.cDestPath m.cFile '.DBF')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp A m.cFileSrc)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Si le Fichier(m.cDestPath m.cFile '.FPT')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Renommer (m.cDestPath m.cFile '.FPT')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp (a Gauche(m.cFileSrc,
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Len(m.cFileSrc)-4) '.FTP')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Utiliser (m.cFileSrc) Exclusive
& ! & ! & ! & ! & ! & nbsp Endif
& ! & ! & ! & ! & ! & nbs * & Restaurer FullPath Parametre & *
& ! & ! & ! & ! & ! & nbsp Ensemble FullPath & cFullPath
& ! & ! & ! & ! & ! & nbsp ** & Resultat de Retour le nombre d'Enregistrement & **
& ! & ! & ! & ! & ! & nbsp Retour (m.nRecs)
& nbsp & nbsp & nbsp EndFunc
& nbsp & nbsp & nbsp Procedure SetPath
& ! & ! & ! & ! & ! & nbsp Parametre cPath
& ! & ! & ! & ! & ! & nbsp Definir le Chemin d'acces A m.cPath)
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Procedure FoxCommand
& ! & ! & ! & ! & ! & nbsp Parametre ccg
& ! & ! & ! & ! & ! & ! & ccg
& nbsp & nbsp & nbsp EndProc
& nbsp & nbsp & nbsp Fonction FoxFunction
& ! & ! & ! & ! & ! & nbsp Parametre cFunc
& ! & ! & ! & ! & ! & nbsp Prive Rtn
& ! & ! & ! & ! & ! & nbsp Rtn = & cFunc
& ! & ! & ! & ! & ! & nbsp Retour (m.Rtn)
& nbsp & nbsp & nbsp EndFunc
ENDDEFINE
Procedure Ole_Err
& nbsp & nbsp & nbsp ** & Poignee DLL Erreurs internes & **
& nbsp & nbsp & nbsp Parametre nErr,nLine,cMessage,cPRG
& nbsp & nbsp & nbsp SI (m.nErr=1707)
& ! & ! & ! & ! & ! & nbsp * & CDX presente pas, OK pour Reessayer & *
& ! & ! & ! & ! & ! & nbsp Reessayer
& nbsp & nbsp & nbsp Else
& ! & ! & ! & ! & ! & nbsp MessageBox( m.cMessage Chr(13) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Erreur '# ' str(m.nErr,5) Chr(13)
&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!&!', A la Ligne de#' Str(m.nLine,5) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! 'Dans' m.cPrg chr(13) Chr(13)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ' Voir File:OLE_ERR.TXT pour plus de details.'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ,16, 'ERREUR dans le VFP_OLE.DLL Module')
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp * & Dump de la Memoire et de l'Etat des Fichiers dans un Fichier Texte.
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Creer Curseur OleError (ErrText M(10))
& ! & ! & ! & ! & ! & nbsp Etat de la Liste des NoConsole De Fichier OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Liste de la Memoire Comme * NoConsole De Fichier OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp Append Blank
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Repliquer('*',80) Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp DTOC(Date()) '' Time()
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc(' STATUS ',80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10)
& ! & ! & ! & ! & ! & nbsp Ajouter Memo ErrText De OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc (la 'MEMOIRE', 80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10) Addi
& ! & ! & ! & ! & ! & nbsp Ajouter Memo ErrText De OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp Remplacer ErrText Avec Chr(13) Chr(10)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp nom de padc ('la Fin de l'Erreur & ',80,'*')
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Chr(13) Chr(10) Addi
& ! & ! & ! & ! & ! & nbsp Si le Fichier('OLE_ERR.TXT')

& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie du Memo ErrText A OLE_ERR.TXT Addi
& ! & ! & ! & ! & ! & nbsp Else
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Copie du Memo ErrText A OLE_ERR.TXT
& ! & ! & ! & ! & ! & nbsp Endif
& nbsp & nbsp & ! & ! & ! & nbsp Effacer OLE_STAT.TMP
& ! & ! & ! & ! & ! & nbsp Effacer OLE_MEM.TMP
& ! & ! & ! & ! & ! & nbsp *
& ! & ! & ! & ! & ! & nbsp Proche de Donnees
& ! & ! & ! & ! & ! & nbsp Masquer l'Ecran de la Fenetre
& ! & ! & ! & ! & ! & nbsp * & La commande ANNULER causes Delphi
& ! & ! & ! & ! & ! & nbsp * & pour etre en mesure d'intercepter l'erreur.
& ! & ! & ! & ! & ! & nbsp Annuler
& ! & ! & ! & ! & ! & nbsp *
& nbsp & nbsp & nbsp Endif
EndProc
*:EOF(VFP_OLE.PRG)

une fois la DLL compilee, il doit etre enregistre aupres de REGSVR32.EXE qui est distribue avec windows 95 et NT et devrait etre dans le repertoire \Windows\System pour windows 95 et \Windows\System32 pour NT. Toutefois, ce processus peut etre automatise par l'Delphi application lors de l'execution. (voir la fonction RegisterDLL)
Dans une application Delphi, j'ai cree une methode qui tente d'instancier la DLL lors de l'execution, et un autre pour enregistrer la DLL si l'instanciation de la methode echoue. En outre, j'ai 2 variables globales: vFoxOle et bIsFoxOle. vFoxOle est une Variante qui pointe vers l'objet OLE et bIsFoxOle est un Booleen qui indique a l'application si l'objet OLE a ete correctement instancie. De cette façon, je peux ecrire l'application pour gerer les Donnees FoxPro avec le VFP OLE ou le BDE. Vous devez egalement disposer d'une reference a ComObj dans les 'Usages' de la clause de la forme qui instancie la DLL.
Dans le Formulaire de creation de la methode, j'ai appeler la Fonction IsFoxOle pour instancier la DLL OLE. Le Delphi fonction CreateOleObject() est utilise pour creer une connexion a l'objet OLE et retourne un pointeur vers l'objet qui est stockee dans la variable vFoxOle. CreateOleObject() est utilisee avec un parametre de chaîne de points de la Classe qui est instanciee. Dans ce cas, le nom de la DLL est VFP_OLE et la Classe est VFP_OLE_Server. Donc, pour faire un lien que j'ai utilise CreateOleObject('VFP_OLE.VFP_OLE_Server').

procedure TfrmFox.FormCreate(Sender: TObject)
Begin
& nbsp & nbsp & nbsp Si Pas IsFoxOle Puis Commencer
& ! & ! & ! & ! & ! & nbsp RegisterDLL
& ! & ! & ! & ! & ! & nbsp // initialisation de bIsFoxOle avec le resultat
& ! & ! & ! & ! & ! & nbsp // de la tentative d'instanciation. Si le fournisseur OLE
& ! & ! & ! & ! & ! & nbsp // objet a ete enregistre, le resultat
& ! & ! & ! & ! & ! & nbsp // sera vrai.
& ! & ! & ! & ! & ! & nbsp bIsFoxOle := IsFoxOle
& nbsp & nbsp & nbsp Fin Else
& ! & ! & ! & ! & ! & nbsp bIsFoxOle := True
Fin
Fonction de TFrmFox.IsFoxOle : Boolean
Begin
& nbsp & nbsp & nbsp Essayer
& ! & ! & ! & ! & ! & nbsp // Instancier l'objet OLE
& ! & ! & ! & ! & ! & nbsp vFoxOle :=
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp CreateOleObject('VFP_OLE.VFP_OLE_Server')
& ! & ! & ! & ! & ! & nbsp Result := True
& nbsp & nbsp & nbsp a l'Exception de
& ! & ! & ! & ! & ! & nbsp Result := False
& nbsp & nbsp & nbsp Fin
Fin
Procedure TFrmFox.RegisterDLL
// Si REGSVR32.EXE existe RegisterDLL()
// va chercher VFP_OLE.DLL
// a 2 endroits:
// 1) \Windows\System
// 2) le repertoire courant
var A : Array[0..100] of Char
& ! & ! & ! & nbsp sSysDir : String
& ! & ! & ! & nbsp sCurDir : String
Begin
& nbsp & nbsp & nbsp GetSystemDirectory(@A, 100)
& nbsp & nbsp & nbsp sSysDir := A
& nbsp & nbsp & nbsp sSysDir := AddBS(sSysDir)
& nbsp & nbsp & nbsp sCurDir := AddBS(GetCurrentDir)
& nbsp & nbsp & nbsp if FileExists(sSysDir 'REGSVR32.EXE'), Puis Commencer
& ! & ! & ! & ! & ! & nbsp if FileExists(sSysDir 'VFP_OLE.DLL') Ensuite, Commencez
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! ''' sSysDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& ! & ! & ! & ! & ! & nbsp Fin Else if FileExists(sCurDir 'VFP_OLE.DLL') Ensuite, Commencez
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp WinExec(pChar(''' sSysDir 'REGSVR32.EXE' '
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! ''' sCurDir 'VFP_OLE.DLL' /s'), SW_SHOWNORMAL)
& ! & ! & ! & ! & ! & nbsp Fin
& nbsp & nbsp & nbsp End Else Begin
& ! & ! & ! & ! & ! & nbsp Raise Exception.Create('Ne peut pas s'Inscrire VFP_OLE.DLL !')
& nbsp & nbsp & nbsp Fin
Fin

Pratique a Utiliser
Supposons que vous avez une Facture de l'application et vous devez savoir combien d'argent est due, l'age, et qui les doit. Votre formulaire de requete pourrait ressembler a ceci:
(Inserer un Fichier: QForm1.BMP ici)
Lorsque l'utilisateur clique sur le bouton OK, l'instruction SQL est cree dynamiquement et envoye a la DLL en tant que parametre de traitement. Il est important de noter que la chaîne SQL a un 'Dans la Table' dans le cadre de l'instruction. Sans cela, le Delphi application n'a aucun moyen de ramasser les donnees de resultat. Il y a 3 manieres de gerer la creation de la Table: 1) Creer la table sur les utilisateurs locaux repertoire temporaire avec un nom de fichier statique. 2) Ecrire une fonction qui cree un nom de fichier unique ou utiliser la fonction Windows API GetTempFileName(). 3) Combiner les deux 1 & 2 et de creer un nom unique dans le repertoire Temp de Windows. Pour les environnements reseau, je trouve que l'option 3 est la plus sûre. Il est egalement important d'utiliser la methode SetDir() avant et apres l'execution de la Requete. C'est donc FoxPro sait ou trouver les tables c'est interrogee contre, et Delphi application peut trouver son chemin de retour a la maison. Si vous n'avez pas SetDir() apres la requete, alors il ya une assez bonne chance que le Delphi application ne sera pas en mesure de trouver les composants externes tels que AVI, BMP, WAV ou fichiers dont il a besoin. C'est parce que FoxPro change physiquement le repertoire pointeur.
Cet exemple suppose que l'DBF tables sont dans le meme repertoire que le Delphi executable. La fonction GetTempDir() est une simple fonction wrapper qui utilise l'API Windows pour obtenir le repertoire temp de windows. L'instruction SQL Select dynamique est cree sur la base des Jours de retard, et le resultat de la table est creee dans le repertoire Temp de Windows dans un fichier appele MyQuery.dbf. Apres MyQuery.dbf est cree, la Table1 objet est affecte a son contenu et affichees dans la grille.

procedure TfrmFox.btnExeQueryClick(Sender: TObject)
Var
& nbsp & nbsp & nbsp sSQLText : String
& nbsp & nbsp & nbsp rieds : Integer
& nbsp & nbsp & nbsp sAppDir : String
begin
& nbsp & nbsp & nbsp Si bIsFoxOle Puis Commencer
& ! & ! & ! & ! & ! & nbsp // Obtenir le chemin d'acces au repertoire de l'application
& ! & ! & ! & ! & ! & nbsp sAppDir :=
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp ExtractFilePath(Application.ExeName)
& ! & ! & ! & ! & ! & nbsp Si (e_PastDue.Text= ')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp e_PastDue.Text := '0'
& ! & ! & ! & ! & ! & nbsp sSQLText :=
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Select Client.Nom,'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' de la Facture.AcctNo, Facture.Balance,'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (Date()-Facture.La Date) Que l'Age'
&!&!&!&!&!&!&!&!&!', Du Client,la Facture d'
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Ou'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (le Client.AcctNo = Facture.AcctNo) Et'
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' (Date()-Facture.Date) >= ' e_PastDue.Texte
& ! & ! & ! & ! & ! & ! & ! & ! & ! ' la Commande Par le Client.Le nom,l'Age'
& ! & ! & ! & ! & ! & ! & ! & ! & ! 'Dans la Table' GetTempDir() 'MyQuery'
& ! & ! & ! & ! & ! & nbsp // assurez-vous que l'objet de la table qui lit
& ! & ! & ! & ! & ! & nbsp // le resultat est ferme avant de la requete
& ! & ! & ! & ! & ! & nbsp // est execute.
& ! & ! & ! & ! & ! & nbsp Si Table1.Actif, Puis Commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.Fermer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // assurez-vous que la table est supprimee apres la cloture
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.DeleteTable
& ! & ! & ! & ! & ! & nbsp Fin
& ! & ! & ! & ! & ! & nbsp // affectation temporaire le nom du fichier a Table1
& ! & ! & ! & ! & ! & nbsp Table1.TableName := 'MyQuery.DBF'
& ! & ! & ! & ! & ! & nbsp // affecter le Repertoire temporaire sur Table1
& ! & ! & ! & ! & ! & nbsp Table1.DatabaseName := GetTempDir()
& ! & ! & ! & ! & ! & nbsp // VFP Repertoire par Defaut ou l'
& ! & ! & ! & ! & ! & nbsp // Fox DBFs sont stockees.
& ! & ! & ! & ! & ! & nbsp vFoxOle.SetDir(sAppDir)
& ! & ! & ! & ! & ! & nbsp // Execution de la Requete
& ! & ! & ! & ! & ! & nbsp rieds := vFoxOle.ExeSql(sSQLText)
& ! & ! & ! & ! & ! & nbsp Label7.Caption := IntToStr(rieds)
& ! & ! & ! & ! & ! & nbsp Si (rieds = 0) Then
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp MessageDlg('Aucun enregistrement Trouve Dans la Requete!'
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp ,mtInformation,[bakang],0)
& ! & ! & ! & ! & ! & nbsp Else Begin
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // ExeSql() les feuilles le resultat de la table ouvrir
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // de sorte que vous pouvez les pre-traiter la table
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // VFP avant de Delphes qu'il Ouvre.
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Ces Indices sont utilises pour modifier
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // l'ordre de tri en cliquant sur le
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp // Grille de Titre.
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Index Sur Nom Nom de la Balise')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand (Indice Sur l'Age de la Balise de l'Age')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Index Sur AcctNo Tag AcctNo')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand (Indice Sur l'Equilibre de la Balise Equilibre')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp vFoxOle.FoxCommand ('Fermer la Base de donnees')
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Table1.Ouvert
& ! & ! & ! & ! & ! & nbsp Fin
& nbsp & nbsp & nbsp End Else Begin
& ! & ! & ! & ! & ! & nbsp MessageDlg('VFP_OLE.DLL Non Instancie!',
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp mtError,[bakang])
& nbsp & nbsp & nbsp Fin // Si bIsFoxOle
fin

Avec cette DLL vous avez la possibilite de realiser a partir de Delphi, presque rien que vous pouvez faire a partir de FoxPro. Ce n'est pas seulement limitee a la simple Substitution de Macro, mais peut etre utilise pour developper Delphi frontaux qui utilisent l'ensemble de la base de donnees Visual FoxPro structure. Maintenant, je ne dis pas que nous commençons tous a l'aide de Visual FoxPro pour notre back-ends, mais elle permet de faire un joli pont pour ceux d'entre nous qui sont de la migration de notre DOS et les applications Windows a partir de FoxPro pour Delphi et besoin de la vitesse de Rushmore.
Il y a quelques mises en garde de cette technologie a l'aide de Visual FoxPro, vous devez etre conscient de:

  • la gestion d'Erreur est limite. Si une instruction SQL fait reference a une table FoxPro ne pouvez pas le trouver, il ouvre une boîte de dialogue demandant a l'utilisateur le chemin de la mysterieuse table. Seulement apres que la touche echap il va generer une erreur recuperable. Donc, il pourrait etre prudent de verifier l'existence des tables avec le Delphi fonction FileExists(), avant d'executer la requete.
  • les resultats de La requete sont parfois retournes dans Visual FoxPro format de fichier, quelque chose de Delphi n'est pas actuellement pris en charge. Le resultat doit etre converti par la DLL, ce qui peut prendre plus de temps pour le processus.
  • Il y a 2 runtime de Visual FoxPro Dll qui doivent etre distribues avec le Delphi application ajouter environ 3,9 mo pour la taille globale de l'application.
  • afin de pouvoir distribuer le runtime de Visual FoxPro Dll ou creer la DLL OLE, vous devez posseder une copie de Visual FoxPro version Professionnelle de 5 ou plus.
    Depuis les Modifications de Cet Article a Ete WrittenVisual FoxPro version 6 et plus ne fonctionnent pas avec la DLL. Vous devez compiler l'objet COM dans un fichier EXE. L'EXE peuvent etre enregistres par l'execution d'une fois sur l'ordinateur qui sera acces. RegSvr32.exe n'est plus necessaire.


L'accès rapide aux données foxpro à partir de delphi

L'accès rapide aux données foxpro à partir de delphi : Plusieurs milliers de conseils pour vous faciliter la vie.
Recommander aux amis
  • gplus
  • pinterest

Messages récents

Commentaire

Laisser un commentaire

évaluation