image gauche logo Clairinfo image droite


Version du : 30/01/2007

TUTORIAL PARADOX POUR WINDOWS

Leçon 2 - Mise en route

Introduction :

La leçon 1 nous a permis de présenter l'objectif de ce tutorial : construire une application de gestion commerciale en Paradox pour windows. Nous sommes arrivés à un schéma des données à gérer, reste maintenant à construire l'application... Dernière précision avant de commencer nous n'utiliserons pas les "experts" ou autres "assistants" car le but du tutorial est d'expliquer justement le détail des manipulations et de justifier les choix faits à chaque étape. Il est clair que ces assistants pourront se révéler pratiques à l'usage.

Préparer les répertoires de l'application "MonAppli" :

Créer un répertoire C:\MonAppli puis dedans 2 sous-répertoires C:\MonAppli\Travail et C:\MonAppli\Prive

Le premier recevra tous les fichiers permanents de l'application alors que le deuxième ne stockera que les fichiers temporaires . Dans le cas d'un fonctionnement réseau le répertoire de travail sera simplement déplacé sur un disque partagé et chaque poste client conservera le répertoire privé sur son disque.

A quoi sert donc ce répertoire privé ?

Chaque fois qu'un utilisateur lance Paradox, une session distincte est lancée dans le BDE (moteur de base de données). Cette session suit l'utilisateur jusqu'à sa déconnexion. Elle permet de sauvegarder les contextes de travail de chaque utilisateur et par exemple de garantir que si 2 utilisateurs demandent une liste des clients avec des critères différents chacun reçoive bien la réponse à sa requête et non la requête du collègue !

Paradox a donc besoin par moment de stocker sur disque des résultats temporaires et il va le faire dans le "répertoire privé" de l'utilisateur. Chaque fois qu'on lance une requête par exemple, une table réponse va être créée dans le répertoire privé. Normalement ces fichiers temporaires sont automatiquement détruits lorsque la session prend fin c'est à dire lorsque l'utilisateur quitte Paradox. Sauvegarder notre application consistera donc simplement à sauvegarder le répertoire de travail.

Faut-il subdiviser le répertoire de travail ?

Certains développeurs aiment bien séparer les fiches , c'est à dire les écrans de l'application, les états , donc les éditions, les tables, donc les données. Ils créent alors une subdivision du répertoire de travail avec un dossier Fiche, un dossier Data, un dossier Etat etc...

Selon nous cela n'apporte en fait pas grand chose et complique plutôt le développement. Un des arguments cités est que cela permet de ne sauvegarder que les données ce qui est certes exacte mais pour nous dangereux ! Il est beaucoup plus sûr de sauvegarder l'ensemble (données et programmes) surtout lorsque le programme est constitué d'une myriade de fichiers comme c'est le cas en Paradox. L'autre argument avancé serait une perte de performance par rapport à la copie de cette partie programme sur chaque poste, les données seules restant sur le serveur. Là aussi danger avec le risque évident qu'un poste ne soit pas dans la même version que son voisin... Quant à la taille de la sauvegarde , il faut bien comprendre que le moteur de Paradox reste lui à l'écart et n'est donc pas sauvegardé. Seule la partie que vous construisez et les données seront sauvegardées.

Nous avons construit de grosses applications en Paradox (200 tables, 150 fiches, 200 éditions) sans constater le moindre problème de performance et en laissant le tout dans un seul répertoire sur le serveur. C'est la solution que nous préconisons, surtout pour débuter.

Lancer Paradox et définir le cadre de travail :

Pour le déroulement des opérations je vais utiliser P10 version US mais sauf indication contraire les manipulations seraient identiques dans une autre version. Je vais m'efforcer de traduire correctement les menus...

- Lancer Paradox et faites pointer le répertoire de travail sur celui que nous avons créé

Menu Fichier / Répertoire de travail (c:\MonAppli\Travail)

- Faites pointer le répertoire privé sur celui que nous avons choisi

Menu Outils / Paramètre / Préférences / Onglet Base de données (c:\MonAppli\Prive)

En passant vous remarquerez que l'alias :Priv: déjà défini permettra de désigner par la suite ce répertoire.

Un alias est un nom logique pour désigner dans le cas présent un répertoire. L'utilisation des alias est très importante car elle permet de rendre son code portable facilement. Plutôt que d'utiliser "c:\MonAppli\Prive" dans notre application nous utiliserons ":Priv:" ce qui nous permettra par la suite de changer de répertoire privé si nécessaire.

De la même façon nous allons maintenant à créer un nouvel alias pour désigner le répertoire de travail.

Créer un alias pour le répertoire de travail de notre application :

Menu Outils / Gestionnaire d'alias , cliquer sur Nouveau, choisissez :

Alias : App
Type : Standard
Path : C:\MonAppli\Travail

Validez par Ok et acceptez d'enregistrer ce nouvel alias dans le fichier de configuration du BDE : Idapi32.cfg

Remarques importantes :

1°) Pour une application réelle prenez 2 alias distincts pointant sur le même répertoire. En effet si vous décidez un jour de conserver votre application Paradox mais de transférer vos données Paradox dans une base de données de type Client /Serveur, ces 2 alias séparés vous faciliteront la tâche. Le premier doit désigner l'emplacement des données (ex :Data:) et le deuxième (ex :App:) doit désigner l'emplacement du reste des objets (fiches, états etc...).
L' opération s'effectue en changeant simplement le type de l'alias pointant sur les données. Au lieu de prendre STANDARD nous pourrions prendre SYBASE, ORACLE, DB2 , MYSQL etc... Pour ce tutorial nous n'utiliserons qu'un alias pour simplifier.

2°) Il faut éviter absolument d'utiliser des mot-clés en français même si votre version française de Paradox vous y incite. Il faut savoir que toutes les versions de Paradox comprennent les mot-clés en anglais et que le runtime étant maintenant en version US vous risqueriez inutilement des conflits. Ainsi nous n'utiliserons pas ":PRIVE:" mais ":PRIV:"

Créer les tables de notre application :

Il est logique de commencer par les tables (les fichiers) car sans elles point d'écrans de saisie ni d'éditions. Pour visualiser les différents objets de notre application il est pratique d'utiliser la fenêtre projet. Si vous ne la voyez pas demander Menu Outils / Fenêtre projet.

Dans la partie gauche de la fenêtre projet cliquez sur Table puis avec le bouton droit de le souris demander Nouveau

- Demander Vierge, acceptez un type de table Paradox 7 - 10, on tombe sur la grille de saisie des champs.

Client.db : La table des clients

Clé Nom du champ Type Taille Obligatoire Défaut
Oui CodeClient A 10 Oui  
  Nom A 35    
  Adresse1 A 35    
  Adresse2 A 35    
  CodePostal A 5    
  Ville A 35    
  Audit @     NOW

Avant de valider, vérifiez que vous êtes bien en langage de table "Pdox ANSI Intl" ce qui vous permettra de stocker des caractères tels que le symbole Euro dans votre table. Il s'agit en fait du type de codage informatique qui sera appliqué à vos données. Il est possible de fixer cette option par défaut dans le programme "Administrateur BDE" situé dans le panneau de configuration de Windows. En validant , choisissez Client.db comme nom de table.

Quelques explications :

Nous demandons que le champ CodeClient soit la "clé primaire" de notre table. Cela veut dire que Paradox va :

- Vérifier automatiquement l'unicité de cette clé lors de l'insertion d'un enregistrement
(On ne pourra pas avoir 2 CodeClient identiques)
- Classer automatiquement dans la table les enregistrements dans l'ordre de cette clé
Si un classement alphabétique sur le nom s'avérait indispensable, il suffirait de créer un "index secondaire" sur le champ nom (regardez l'onglet index secondaires sur l'écran). Retenez tout de même que même sans cet index il sera bien sûr possible de retrouver facilement un client par son nom ou une partie de son nom. En outre les requêtes nous permettrons d'obtenir très facilement des données triées sur n'importe quel critère. De notre point de vue, sauf cas exceptionnel (accélérer un traitement particulier) il faut éviter de créer de trop nombreux index.
- Permettre un accès rapide sur cette clé en gérant un petit fichier d'index séparé de la table.
(Pour les index secondaires le principe est identique avec la particularité de pouvoir choisir l'ordre ascendant ou descendant et de n'être pas forcément unique)

Nous demandons également un champ nommé Audit qui contiendra la Date et heure (Le type de champs "@" correspond à un "TimeStamp" , soit Heure + Date), de la création de l'enregistrement. Cela peut être utile pour tracer un éventuel problème. Paradox le gérera automatiquement pour nous. (Attention la mise à jour de cette valeur lors d'un changement sur l'enregistrement devra être gérée par code si nécessaire)

Ces choix pourront être modifiés ultérieurement (Sélectionnez la table dans la fenêtre projet, bouton droit de la souris et demandez restructurer) mais une fois des données saisies il faudra faire attention de ne pas corrompre celles-ci par un geste malheureux. Dire par exemple qu'un champ est obligatoire alors que certains enregistrements actuels ne vérifie pas ce critère entraînera leur exclusion de la table. Il faut être prudent et disposer de sauvegarde avant d'entamer ce type de modifications.

Continuons la création des tables :

Produit.db : La table des produits

Clé Nom du champ Type Taille Obligatoire Défaut
Oui CodeProduit A 10 Oui  
  Designation A 35    
  Prix N      
  Audit @     NOW

Les noms des champs :

Pour les noms des champs, ne mettez pas d'accent, pas de blanc, pas de caractère spéciaux. Faites simple afin d'éviter tout souci le jour ou vous voudrez récupérer vos données dans un autre système. C'est un point important. Sur les écrans et les éditions vous aurez tout loisir de modifier ces intitulés comme bon vous semble. Attention à certains mots réservés, comme "type" , "date" etc...

NoPiece.db : La table des derniers N°pièce (ex : N°Facture)

Clé Nom du champ Type Taille Obligatoire Défaut
Oui NoID S   Oui  
  NomPiece A 20    
  NoPiece I      
  TableControle A 10    
  Audit @     NOW

Quelques explications :

Vous aurez sans doute remarqué la possibilité de définir un champ de type "+ ,Auto-incrémenté". Nous vous déconseillons d'utiliser ce type de champ pour une application réseau sauf cas très particulier. Différents petits bugs fragilisent à l'extrême ce type de champ. Le plus sûr pour notre application est de gérer nous-même nos incréments grâce à cette petite table et une petite fonction que nous construirons plus loin. En outre le client peut exiger la possibilité de revenir sur son dernier N°Facture tant que celle-ci n'a pas été validée ou transmise en comptabilité. La partie 4 du tutorial vous expliquera en détail le fonctionnement de cette table.

Le type de champs "S" correspond à un "Short", un entier court
( un nombre entier compris entre -32 767 et 32 767)

Le type de champs "I" correspond à un "Integer", un entier long
( un nombre entier compris entre -2 147 483 648 et 2 147 483 647 )

Ne cherchez pas à optimiser à outrance, voyez grand. Notre application attend 10 000 factures par an ? Pas de problème , Paradox peut gérer des centaines de milliers de lignes sans difficulté (les limites théoriques sont de 2 milliards de lignes par table et/ou 1Go par table ! Bon c'est théorique hein ! Si vous en êtes là, Paradox n'est clairement pas le bon choix...). Prenez des types de champs adaptés pour une longue durée.

Fact.db : La table des en-têtes (et pieds) de facture

Clé Nom du champ Type Taille Obligatoire Défaut
Oui NoFact I   Oui  
  TypeFact A 10    
  DateFact D      
  CodeClient A 10    
  Nom A 35    
  Adresse1 A 35    
  Adresse2 A 35    
  CodePostal A 5    
  Ville A 35    
  TauxTVA N      
  TotalHT N      
  TotalTVA N      
  TotalTTC N      
  Audit @     NOW

Définir une table de référence pour contrôler et assister la saisie :

Avant de valider nous allons profiter d'une autre possibilité offerte, les tables de référence afin d'empêcher de saisir un CodeClient inexistant :

- Cliquez sur l'onglet Table de référence
- Dans la partie gauche cliquez 2 fois sur le CodeClient et dans la partie droite cliquez sur la table Client.db puis sur CodeClient pour mettre les 2 champs en correspondance.
- Comme nous souhaitons récupérer l'adresse du client sur la facture et que nous avons pris soin de prendre les même noms de champs, il suffit de choisir ici : "Tous les champs correspondants" comme type de référence pour que tout soit automatique. Paramétrer une table de référence permet également de disposer en saisie de la liste des valeurs possibles avec les libellés correspondants, ce qui est bien pratique.

Nous faisons de même pour le Taux de TVA en définissant Tva.db comme table de référence pour le champ TauxTVA.

Gérer l'intégrité référentielle au niveau table ?

Paradox offre une autre possibilité intéressante, l'intégrité référentielle. Cette option permet de s'assurer par exemple qu'il ne sera pas possible de supprimer un client de la table client si la table facture contient une ou plusieurs lignes le concernant. Il y a 2 écoles qui s'opposent sur ce sujet. Ceux qui préfèrent définir les contraintes d'intégrité au niveau de la base et ceux qui préfèrent laisser le soin des contrôles à l'application elle-même. Les premiers redoutent des entrées directes dans les tables donc hors contrôle de l'application ou un code défaillant, les seconds redoutent des problèmes liés à ces IR (problème de performance, problème avec les noms de fichiers longs, difficultés pour copier, renommer, déplacer une table etc...).

Les IR de Paradox ont des faiblesses à connaître :

- Pas de suppression en cascade
- Propagation de modification de clé sur un seul niveau

Du coup pour une application critique qui nécessiterait une intégrité parfaite des données nous préconisons d'employer une base de données Client-Serveur offrant en standard tous ces contrôles et surtout, contrairement à Paradox les effectuant côté serveur réduisant nettement le trafic réseau. Paradox peut parfaitement se connecter aux principales bases de données client-serveur et certaines d'entre-elles sont même gratuites comme Interbase 6.0 ou PostgreSql. Ce type de développement sort toutefois du cadre de ce didacticiel.

A titre d'exemple, mettons en place une règle d'IR entre la table d'en-tête de facture et la table client :

- Sur l'écran de restructuration de la table Fact.db , cliquez sur l'onglet Intégrité référentielle
- Dans la boite Nom de lien cliquez sur Ajouter, tapez le nom "IRClient"
- Dans la liste déroulante Table parent, choisissez Client.Db
- Dans la boite Table courante, double cliquez sur CodeClient
- Dans les règles de mise à jour, cliquez sur Interdit

En guise d'exercice , mettez en place une IR entre FactD.db et Produit.db, pour empêcher de supprimer ou de modifier un produit concerné par une ligne de facture.

Ces IR ne nous empêcheront pas d'effectuer également des contrôles par code.

FactD.db : La table détail des lignes de facture

Clé Nom du champ Type Taille Obligatoire Défaut
Oui NoFact I   Oui  
Oui NoLigne S   Oui  
  CodeProduit A 10    
  Designation A 35    
  Qte N      
  Prix N      
  MontantHT N      
  Audit @     NOW

Ici la clé primaire de la table est une clé composée N°Facture + N° Ligne.

Mettre la table Produit comme table de référence pour le CodeProduit et demander "Aide sur référence" et "Tous les champ correspondants" pour que le prix et la désignation se recopie automatiquement lors de l'appel d'un produit.

Tva.db : La table des Tva

Clé Nom du champ Type Taille Obligatoire Défaut
Oui TauxTVA N 1 Oui  
  LibelleTVA A 35    
  Audit @     NOW

Haut de page     Précédent     Suivant

© Copyright 2000-2007 , Clairinfo ® , http://www.clairinfo.fr