Beruflich Dokumente
Kultur Dokumente
Une application peut placer les différents ensembles de données qu'elle manipule dans
des modes différents en appelant une méthode appropriée.
Mode Description
Inactive L'ensemble de donnée est fermé
Browse État par défaut à l'ouverture. Il permet de visualiser les données et de se
déplacer au sein de l'ensemble de données mais n'autorise pas les
modifications ni les ajouts.
Edit Permet la modification de l'enregistrement actif .
Insert Permet l'insertion d'une nouvelle ligne à l'emplacement courant qui devient
l'enregistrement courant. Permet l'édition dans cet enregistrement.
( L'ex-enregistrement courant est donc déplacé d'un rang après le nouvel
enregistrement )
Setkey Permet à certaines méthodes ( FindKey, GoToKey, etc. ) de rechercher
des valeurs dans l'ensemble de données.
CalcFields Mode utilisé uniquement avec des champs calculés.
Page XIII.1
Programmation d'applications orientées données
Les différents ensembles de données peuvent être parcourus à l'aide des méthodes du
composant TTable suivantes :
Méthode Action
First Déplace le curseur sur le premier enregistrement
Last Déplace le curseur sur le dernier enregistrement
Next Déplace le curseur à l'enregistrement suivant
Prior Déplace le curseur à l'enregistrement précédent
BOF Renvoie true lorsque le curseur est au début de l'ensemble de données
EOF Renvoie true lorsque le curseur est à la fin de l'ensemble de données
MoveBy (n) Déplace le curseur de n enregistrements ( n peut être positif ou négatif )
par rapport à l'enregistrement courant.
Méthode Action
Open Ouvre l'ensemble de données (*). Le met en mode Browse.
Close Ferme l'ensemble de données. Le met en mode Inactive
Cancel Annule l'opération en cours et place l'ensemble de données en mode
Browse
Edit Place l'ensemble de données en mode Edit. (**)
Insert Place l'ensemble de données en mode Insert.
Append Positionne le curseur à la fin de l'ensemble de données et le place en
mode Insert
Post Expédie l'enregistrement nouveau à la base de données ( valide donc les
nouvelles données ) et place l'ensemble de données en mode Browse
Delete Supprime l'enregistrement en cours et place l'ensemble de données en
mode Browse
(*) Dans le cas ou l'ensemble de données n'a pas sa propriété Active = true lors de la phase de
conception.
(**) Se met en mode Insert si l'ensemble de données est vide.
C'est donc la méthode Post ( ), qui en fait actualise les tables physiques. Elle joue donc
un rôle primordial et il faut bien comprendre son mécanisme :
- En mode Edit ( ), Post ( ) modifie l'enregistrement en cours;
- En mode Insert ( ), Post ( ) insère un nouvel élément.
Les méthodes First( ), Next( ), Prior( ), Last( ) génèrent un appel implicite à Post( ) si
l'ensemble est en mode Edit ( ) ou Insert ( ).
Page XIII.2
Programmation d'applications orientées données
Les méthodes Insert( ) et Append( ) effectuent elles aussi des appels implicites à
Post() (validation des données contenues dans l'enregistrement courant avant que celui-ci soit
remplacé par un nouvel enregistrement ).
Dans les autres cas il faut appeler Post( ) explicitement.
Post n'est pas appelée implicitement par Close ( ). Il faut utiliser l'événement
BeforeClose ( ) pour expédier explicitement les données en attente.
Lorsque l'on réalise une action itérative sur tous les enregistrements
d'une table, l'application est ralentie par toutes les actions de
rafraîchissement de l'écran qu'elle doit réaliser.
Il faut donc penser à inhiber le composant TDataSource lié à la table
pendant toute la durée du traitement et de ne le réactiver qu'à l'issue :
Page XIII.3
Programmation d'applications orientées données
Événement Action
BeforeOpen, AfterOpen Appelés avant ou après l'ouverture d'un ensemble de
données
BeforeClose , AfterClose Appelés avant ou après la fermeture d'un ensemble de
données
BeforeInsert, AfterInsert Appelés avant ou après le passage en mode Insert
BeforeEdit, AfterEdit Appelés avant ou après le passage en mode Edit
BeforeCancel, AfterCancel Appelés avant ou après l'annulation du mode
précédent
BeforeDelete, AfterDelete Appelés avant ou après la suppression d'un
enregistrement
OnNewRecord Appelé lors de la création d'un nouvel enregistrement .
Utile pour donner des valeurs par défaut.
Exemple :
Page XIII.4
Programmation d'applications orientées données
Pour que cela soit possible, C++ Builder offre la possibilité de créer, à la demande, des
objets spécifiques - appelés objets TField - qui encapsulent chaque champ d'un enregistrement.
Une fois un objet TField créé, il peut être configuré finement, dès la phase de conception, à
l'aide de l'inspecteur d'objet puis manipulé par programmation.
Le fait de pouvoir définir des objets TField fait que l'on peut accéder aux différents
champs d'une table sans utiliser de composants constituant une interface utilisateur.
Page XIII.5
Programmation d'applications orientées données
Il est possible de "supprimer" des objets TField voire de tous les effacer
(cette suppression n'a, bien entendu, aucun effet sur la table).
Le fait de ne pas sélectionner un champ ( en créant un objet TField ) fait qu'il ne pourra
pas être accessible ultérieurement par programmation.
Par contre on peut créer un objet TField, associé à un champ donné, puis - on le verra
plus loin - le rendre 'invisible'. Dans ce cas :
- Il n'est pas affiché dans le composant TGrid associé à la table ;
- On peut néanmoins y accéder par programmation. Cette possibilité est surtout
intéressante lorsque l'on doit manipuler des clés numériques dont l'utilisateur n'a
pas à avoir connaissance.
Il ne faut créer les objets TField que si l'on en a réellement besoin, car ils gonflent
l'exécutable résultant. Si on ne souhaite que réaliser de l'affichage simple, il ne sont pas
nécessaires.
Le nom de chaque objet champ est généré automatiquement : il est constitué par le nom
logique de la table auquel C++ Builder a rajouté, sans espace, le nom du champ dans la
table.
C'est ce nom qui apparaît dans l'inspecteur d'objet lorsque le champ est sélectionné dans
l'éditeur de champs.
Exemple :
Le champ Nom dans la table TMembres sera encapsulé dans un objet TField
nommé TMembresNom.
Page XIII.6
Programmation d'applications orientées données
ou :
EMarques->Text = TMarquesMarque->Value ;
Toute la puissance ultérieure développée par C++ Builder dans la gestion des données
vient de sa capacité à gérer, par programmation les champs individuellement.
Il est aussi possible de forcer une conversion de manière à ce que C++ Builder
convertisse la valeur entrée dans le type souhaitée.
Par exemple, pour un champ de type "chaîne", C++ Builder générera une erreur
si l'on entre des valeurs numériques. Si l'on réalise la conversion de la valeur
entrée en chaîne de caractères, il n'y aura pas d'erreur.
Page XIII.7
Programmation d'applications orientées données
On convertit la valeur d'un composant TField en utilisant une de ses propriétés As ..... .
Les possibilités de conversions sont résumées dans le tableau ci-dessous :
Type de conversion
Type de TField AsString AsInteger AsFloat AsDateTime
TStringField Type chaîne par Convertir en entier Convertir en Convertir en date
définition si possible flottant si possible si possible
TIntegerField Convertir en Type entier par Convertir en Interdit
TSmallintField chaîne définition flottant
TWordField
TFloatField Convertir en Arrondir à la valeur Type flottant par Interdit
TCurrencyField chaîne entière la plus définition
TBCDField proche
TDateTimeField Convertir en Interdit Convertir date en Type date ou
TDateField chaîne. Le nombre de jours heure par
TTimeField contenu dépend depuis définition. Aucune
du format 01/01/0001. date ou heure en
d'affichage du Convertir l'heure l'absence de
champ en fractions de 24 spécification
heures
TBooleanField Convertir en Interdit Interdit Interdit
chaîne "true" ou
"false"
TBytesField Convertir en Interdit Interdit Interdit
TVarBytesField chaîne (n'a
TBlobField généralement lieu
TMemoField d'être que pour
TGraphicField TMemoField)
Exemples :
Page XIII.8
Programmation d'applications orientées données
Une fois les différents objets champ créés, on peut accéder aux différentes valeurs
des champs par la propriété Value.
Cette propriété n'est accessible qu'à l'exécution et en mode lecture ( sauf en mode
SetKey ). Elle nécessite la connaissance complète de la structure de la table.
Exemple :
AnsiString chaine;
....
chaine = TIdentiteNom -> Value ;
chaine = TIdentite -> FieldByName ("Nom") -> AsString ;
chaine = TIdentite -> Fields [ 1 ] ->AsString ;
Page XIII.9
Programmation d'applications orientées données
Modifie les valeurs des champs de l'enregistrement actif. Ne fait pas appel à
Post ( ).
Exemples :
Pour pouvoir utiliser ces méthodes il faut connaître parfaitement la structure de la table
(ordre et nature des différents champs).
Dans le deuxième exemple, le fait d'initialiser certains paramètres à 'NULL' fait que les
valeurs courantes correspondantes ne sont pas modifiées .
Pour utiliser la méthode SetFields ( ), il faut au préalable mettre la table dans le mode
Edit puis, à l'issue, réaliser un Post ( ).
Par exemple on peut avoir une table CLIENTS contenant un champ Nom ( de 30
caractères ) et un champ Prenom ( de 30 caractères ).
On peut utiliser ces champs tels quels. Mais, à l'affichage, il peut être peut intéressant
de devoir afficher les deux colonnes correspondant à ces deux champs, cela prend
trop de place.
On peut souhaiter disposer d'un champ NomPrenom concaténant les deux
informations et considéré comme un seul champ. Ce champ, qui n'existe pas
physiquement dans le base, est un champ calculé.
Page XIII.10
Programmation d'applications orientées données
- Dans la zone de saisie 'Nom' il faut donner un nom au champ calculé. Un type est
proposé qu'il est possible de modifié. S'il s'agit d'une chaîne de caractères on peut
indiquer une taille ( qui peut être différente de celle de la somme des champs
originaux ).
- S'assurer que le radio bouton 'Calculé' est validé.
- Valider l'ensemble en cliquant sur 'OK'. Un nouveau composant TField est créé, il a
les même caractéristiques que les autres champs.
- Le calcul ne peut être réalisé qu'à l'exécution du programme en fonction des valeurs
réellement contenues dans les différents champs. Ces calculs sont réalisés à l'aide
de l'événement OnCalcField de la table concernée.
}
/* chaque champs Nomprenom de chaque enregistrement de la
"vue" prend la valeur des deux champs Nom et Prenom, plus
un espace entre les deux */
Page XIII.11
Programmation d'applications orientées données
Si l'on souhaite gérer et afficher une table selon un ordre il faut demander à BDE de
réaliser une "vue" de la table en fonction de l'index spécifié.
Il est ainsi possible de modifier les "vues" d'une même table en fonction des besoins
du programme ( d'où la nécessité de prévoir dès la phase de conception les différents
index secondaires qui seront utilisés ensuite ).
Si le programmeur gère lui même une clé et que la table est affichée selon
un index secondaire ( par exemple par ordre alphabétique sur le champ 'Nom ' ), le
programmeur ne peut atteindre la fin "réelle" de la table. En effet les instructions du type
TTable -> Next ( ), TTable ->Last ( ) ou autres déplacent le curseur interne au sein de la
"vue" de la table constituée avec l'index et non en fonction de sa constitution physique.
Si l'on souhaite revenir à une vue de la table s'appuyant sur l'index primaire
il faut écrire une instruction de type :
Exemple :
On souhaite insérer une nouvelle marque à la table TMarques. Cette table est
actuellement gérée par un index secondaire l'affichant par ordre alphabétique et
utilise un identifiant créé par programmation ( utilisé pour pouvoir accéder aux
différentes tables secondaires de la base de données).
Pour insérer un nouvel enregistrement il va falloir réaliser les opérations suivantes :
{
int Index;
Page XIII.12
Programmation d'applications orientées données
Sous Paradox, donc BDE, les champs clés doivent être placés en tête de la
table.
Pour pouvoir effectuer une recherche avec ces méthodes il faut, au préalable, placer la
table en 'mode de recherche' par la méthode SetKey ( ) (ce qui a pour effet d'empêcher les
modifications sur les champs ).
On donne la valeur à rechercher dans le champ clé et on réalise la recherche en appelant
la méthode GoToKey ( ) - recherche stricte - ou GoToNearest ( ) - recherche les
correspondances proches -.
TTable ->
Close ( );
TTable ->
Open ( ) ; // vidage des buffers
TTable ->
SetKey ( ) ;
TTable ->
Fields -> Fields [ 0 ] -> AsString = Edit1 -> Text ;
/* ou
TTable -> FieldByName ( "Nom" ) ->AsString
= Edit1 -> Text */
if ( ! TTable -> GotoKey ( ) )
ShowMessage ( "Enregistrement non trouvé ");
...
GotoKey ( ) est une fonction booléenne qui renvoie true quand la recherche s'est
bien passée ( d'où la possibilité de tester cette valeur de retour ).
Page XIII.13
Programmation d'applications orientées données
Le type TVarRec est une structure prédéfinie utilisée à l'intérieur d'une fonction avec
un type de paramètre de tableau de const.
Une variable de ce type peut être créée avec la macro ARRAYOFCONST. Cette macro
est définie dans le fichier sysdefs.h.
Exemple :
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
Table1 -> FindNearest ( ARRAYOFCONST ( ( Edit1->Text ) ) );
}
/* Dans ce cas le tableau de constante est réduit à une seule
chaîne de caractères */
Il faut que l'index secondaire ait été créé au préalable dans DBD ( son nom
apparaît alors dans l'inspecteur d'objet dans le champ IndexName ).
Page XIII.14
Programmation d'applications orientées données
Affichage d'une table contenant un champ clé ( Id ) et deux champs liés à des tables de
référence ( IdMarque et Id Type ). Elle n'est que très peu utilisable telle quelle.
Page XIII.15
Programmation d'applications orientées données
- Dans ce cas, et dans ce cas seul, il faut alors renseigner les différents champs de
saisie contenus dans le groupe 'Définition de la référence' ( seuls deux champs sont actifs au
début ).
. 'Champs clé' doit contenir l'indication du champ qui lie les deux tables ( ici :
IdMarque ).
. 'Dataset' doit contenir le nom de la table dans laquelle on va chercher
l'indication en clair ( ici : TMarques ). Les deux autres zones de saisies
s'activent à ce moment là.
. 'Clés de référence' doit contenir le champ clé de la table de référence ( ici :
IdMarque ).
. 'Champ résultat' doit contenir le nom du champ contenant les données que l'on
souhaite afficher en "clair" ( ici : Marque ).
Un nouveau composant TField aux caractéristiques souhaitées apparaît alors et peut être
visualiser dans un composant TDBGrid à l'exécution.
Ses caractéristiques apparaissent dans l'inspecteur d'objet comme suit :
Page XIII.16
Programmation d'applications orientées données
Page XIII.17
Programmation d'applications orientées données
Ils sont à utiliser prioritairement dans les formulaires de saisie où l'on souhaite proposer
à l'utilisateur le "clair" des données dont seules les valeurs des clés seront stockées dans la
table en cours de modification.
Page XIII.18
Programmation d'applications orientées données
Il suffit de créer un modèle du "formulaire" type souhaité pour que, à l'exécution une
succession de formulaires apparaissent sous forme d'une liste accessible par un ascenseur.
Page XIII.19
Programmation d'applications orientées données
Il est parfois nécessaire de pouvoir marquer un enregistrement courant dans une table,
puis de se déplacer dans celle-ci tout en conservant la possibilité de revenir à l'enregistrement
de départ rapidement.
Pour ce faire on utilise les possibilités de marquages offertes par C++ Builder en
appelant les méthodes GetBookmark ( ), GoToBookmark () et FreeBookMark () du
composant TTable.
Il est possible de poser plusieurs marques dans une même table. Mais il
faudra penser ultérieurement à les libérer une à une.
Exemple :
TBookmark Bookmark ;
// Déclaration d'une marque (variable globale)
if ( ! BookMark )
// vérification que la marque n'est pas utilisée
Bookmark = Table1 -> GetbookMark ( ) ;
// Pose d'une marque
Un filtre peut être constitué de deux valeurs (une maximale et une minimale) indiquant
les limites des valeurs affichées pour un champ donné.
Exemple :
Page XIII.20
Programmation d'applications orientées données
TTable1->SetRange(ARRAYOFCONST(("100")),ARRAYOFCONST(("1000")));
Page XIII.21