cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 2014
-
28 avril 2008 à 18:44
cs_cage
Messages postés9Date d'inscriptionmardi 13 septembre 2005StatutMembreDernière intervention29 décembre 2012
-
3 nov. 2012 à 12:12
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
cs_cage
Messages postés9Date d'inscriptionmardi 13 septembre 2005StatutMembreDernière intervention29 décembre 2012 3 nov. 2012 à 12:12
merci pour votre source lafarge mais je trouve pas la table des contacts est ce qu'il ya un moyen de ziper la base de donné sinon si vous pouvez me dire comment déclarer une photo dans une base de donnés paradox parce je travail sur un projet semblable au tien merci.
jackalunion
Messages postés128Date d'inscriptionmercredi 8 janvier 2003StatutMembreDernière intervention14 juillet 2008 25 juin 2008 à 14:32
il ya des trucs que j'apprecie
nraloux
Messages postés30Date d'inscriptionjeudi 20 avril 2006StatutMembreDernière intervention26 février 2010 12 mai 2008 à 10:11
Merci pour les conseils, je vais me mettre au boulot pour essayer d'ameliorer le code source et l'application.
cs_Delphiprog
Messages postés4297Date d'inscriptionsamedi 19 janvier 2002StatutMembreDernière intervention 9 janvier 201332 10 mai 2008 à 15:54
Effectivement, pour une première, c'est pas mal.
Voici néanmoins quelques remarques (constructives) :
1- Eviter de désactiver les messages d'erreur du compilateur qui ne sont pas là pour meubler le décor. Ainsi, les avertissements suivants sont à prendre au sérieux :
[Avertissement] AjoutContact.pas(256): La variable 'senderEdt' n'est peut-être pas initialisée
[Avertissement] AjoutContact.pas(267): La variable 'SenderEdt' n'est peut-être pas initialisée
[Avertissement] AjoutContact.pas(299): Le symbole 'fmShareDenyRead' est propre à une plate-forme
[Avertissement] ModifContact.pas(260): La variable 'senderEdt' n'est peut-être pas initialisée
[Avertissement] ModifContact.pas(271): La variable 'SenderEdt' n'est peut-être pas initialisée
[Avertissement] ModifContact.pas(312): Le symbole 'fmShareDenyRead' est propre à une plate-forme
Hormis l'avertissement concernant l'utilisation du symbole fmShareDenyRead, le reste peut poser de gros problèmes à l'exécution.
2- Il manque des contrôles à la suppression d'un contact : si on ne rentre aucune donnée et que l'on clique sur le bouton [ok], voici le beau message qui s'affiche :
---------------------------
Gestion Des Contacts
---------------------------
Base de données inconnue.
Alias: Contact.
---------------------------
OK
---------------------------
A affiner, donc.
3- idem que ci-dessus lorsque l'on tente de visualiser un contact ou tous les contacts avec une base de données vide.
4- "Visualiser un contact", puis cliquer sur "visualiser", on obtient ceci :
---------------------------
Gestion Des Contacts
---------------------------
Violation d'accès à l'adresse 005263D0 dans le module 'GDCManager.exe'. Lecture de l'adresse 0000033C.
---------------------------
OK
---------------------------
5- Au niveau du code, on trouve des redondances comme dans Timer1Timer et dans FormCreate (Accueil.pas) pour une simple mise à l'heure des différents composants. Place cette potion de code dans une procédure que tu appelles ensuite.
De même pour :
procedure TFenPrincipale.AjoutContact1Click(Sender: TObject);
begin
TFajoutContact.Create(Self);
ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
end;
procedure TFenPrincipale.Label11Click(Sender: TObject);
begin
TFajoutContact.Create(Self);
ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
end;
De plus, je dirai que c'est un peu maladroit qu'une fiche soit chargée de modifier le titre d'une autre fiche lorsque ce titre est statique.
6- Attention à la façon de nommer tes composants car cela peut prêter à confusion comme ici :
procedure TFenPrincipale.AjoutContact2Click(Sender: TObject);
begin
TFsuppContact.create(self);
ActiveMDIChild.Caption := 'Suppression d''un Contact';
end;
Le bouton AjoutContact a pour action d'afficher la fiche de suppression d'un contact !
7- Ce type de code fait un peu ringard de nos jours et me rappelle les applications des années 80 :
procedure TFenPrincipale.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if
MessageDlg('Cette operation fermera l''application. Voulez-vous effectuer cette operation ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
Application.Terminate
else
begin
Action := caNone;
end;
end;
On alerte l'utilisateur uniquement si des données ont été modifiées et non sauvegardées. D'autre part, éviter l'utilisation de l'appel à Application.Terminate qui arrête brutalement l'application sans laisser le temps aux composants orientés données de vider leurs buffers.
8- Attention à vérifier l'existence d'un fichier avant de l'ouvrir comme dans :
procedure Tsplash.FormShow(Sender: TObject);
begin
sprite := tbitmap.create;
sprite.loadfromfile('1.bmp');
9- Privilégier l'utilisation de TDataModule pour centraliser la logique métier en matière de gestion des données. Cela aurait évité de multiplier les composants TQuery sur chaque fiche et de retrouver des requêtes identiques d'une fiche à l'autre. Lors de la maintenance d'une application, cela peut devenir critique et coûteux en temps avec des tests inutiles quand il faut revisiter chaque fiche de l'application (qui peut en contenir plusieurs centaines). La preuve :
E:\delphifr\GDC\GDC Manager\Acceuil.pas
163 ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
171 ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
187 ActiveMDIChild.Caption := 'Recherche et Modification d''un Contact';
195 ActiveMDIChild.Caption := 'Suppression d''un Contact';
E:\delphifr\GDC\GDC Manager\AjoutContact.pas
173 query1.SQL.Add('insert into contact (civilite,Societe,Nom,Prenom,Adresse,CodePostal,Ville,Pays,Site,Email,telephone,Fax,Mobile,DateNaiss,Observation,photo) values (:ci,:s,:n,:p,:a,:c,:v,:pa,:si,:e,:t,:f,:m,:d,:o,:pho)');
E:\delphifr\GDC\GDC Manager\ModifContact.pas
105 Query1.SQL.Add('select * from contact where nom = :p');
198 Query1.SQL.Add('UPDATE contact SET civilite=:ci ,societe=:s,Nom=:n,Prenom=:p,Adresse=:a,CodePostal=:c,ville=:v,pays=:pa,Email=:e,site=:si,telephone=:t,fax=:f,mobile=:m,datenaiss=:d,observation=:o,photo=:pho WHERE nom=:pr');
335 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
E:\delphifr\GDC\GDC Manager\SelectContact.pas
64 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
81 Query1.SQL.Add('select * from contact where nom = :p');
E:\delphifr\GDC\GDC Manager\SupprimerContact.pas
54 Query1.SQL.Add('select prenom from contact where nom = :p ');
86 Conf := MessageDlg(('Voulez-vous Vraiment supprimer le contact ' + combo.Text
92 Query1.SQL.Add('Delete from Contact WHERE nom=:pr');
116 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
Dans le code, on remarque aussi que tu ne vérifies aucune des données entrées par l'utilisateur et que tu ne prends même pas la précaution de "quoter" tes chaines. Rien de tel pour faire planter une requête si un contact s'appelle "Monsieur Archibald de l'archipel". Ta base de données est gravement exposée aux injections SQL.
Bon, je vais m'arrêter là et passer le relais aux autres. Tu as déjà de quoi occuper les quelques jours du long week-end qu'il te reste.
Mais, je le dis comme d'autres ici, pour une première c'est pas mal du tout.
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 6 mai 2008 à 18:08
Et bien bravo si tu l' as fait seul ^^
Le TFrame est une sorte de panel que l' on peut disposer sur n' importe quel contenant (parent) comme une Form, un panel, un PageControl etc ...
Il se présente en Design-time comme une form et est travaillée comme cette dernière.
Sur ce TFrame, on y met les compos que l' on veut ainsi que le code associé. Ça fait penser à un ActiveX en fait. Les points forts comme le dit si bien Cari, sont la réutilisabilité, la simplicité et pas la peine d' installer puisque en fait, ce n' est pas un compo.
Par contre, il n' est pas visualisé dans son emplacement car on doit le faire par code:
Exemple:
FramAg := TFrameAgend.Create(FrmPrin);
FramAg.Parent := NoteBook_Page(NBookRight, 'AGENDA');
FramAg.Align := alClient;
Particulièrement, je l' utilise mais assez peu car j' ai commencé à utiliser des Dlls avant que le TFrame n' existe. Les Dlls sont compilées indépendemment des applis qui l' appelle alors que si l' on modifie un Frame, toutes les applis qui l' utilisent doivent être recompilées comme toute unité que l' on modifie.
A+
nraloux
Messages postés30Date d'inscriptionjeudi 20 avril 2006StatutMembreDernière intervention26 février 2010 6 mai 2008 à 14:45
Merci a tous pour vos encouragements et contrairement a ce que peut penser MAURICIO je l'ai fais tout seul l'application.
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 4 mai 2008 à 17:34
Bonjour,
LAFARGE me fait penser à un truc...
Je n'y connais rien en BDD et j'espère ne pas dire de bêtises, mais il me semble que TFrame est aussi sous-exploité.
TFrame permet de céer une sorte de composant ré-utilisable sans qu'il soit néccessaire de l'installer.
De plus il permet qu'on le charge au moment voulu, seulement si c'est utile, et de placer le code le gérant dans son unité.
Je ne sais pas pourquoi on le voit si rarement...
HAFTARIFOUAD
Messages postés256Date d'inscriptionmercredi 5 septembre 2007StatutMembreDernière intervention 6 janvier 2011 29 avril 2008 à 12:58
Bonjour
Vu que c'est votre premier code je dit personnellement trés bien. vous avez fait du bon travail. trés bon courage, et bonne continuation.
nethacker
Messages postés288Date d'inscriptionmardi 2 mai 2006StatutMembreDernière intervention12 octobre 2011 28 avril 2008 à 19:57
Salut,
C'est très bien mais ca serait bien si tu avais utilisé une base SQL distante ! les exemples avec access sont plusieurs !
Mais bon, ^^
cs_MAURICIO
Messages postés2106Date d'inscriptionmardi 10 décembre 2002StatutModérateurDernière intervention15 décembre 20145 28 avril 2008 à 18:44
Salut,
si c' est ton premier code, c' est pas mal du tout:
- tu as fait le ménage dans les fichiers.
- les unités sont presques toutes nommées.
- les compos appelés dans le code sont plus ou moins nommés.
- Le code est assez bien présenté et semble plutôt correct.
Malheureusement je n' ai pas compilé parce que tu utilises des compos externes que je ne peux tester pour l' instant.
L' interface graphique et la disposition des compos sont à améliorer.
Si tu l' as fait tout seul (je t' avoue que j' en doute un peu), bravo!
A+
3 nov. 2012 à 12:12
25 juin 2008 à 14:32
12 mai 2008 à 10:11
10 mai 2008 à 15:54
Voici néanmoins quelques remarques (constructives) :
1- Eviter de désactiver les messages d'erreur du compilateur qui ne sont pas là pour meubler le décor. Ainsi, les avertissements suivants sont à prendre au sérieux :
[Avertissement] AjoutContact.pas(256): La variable 'senderEdt' n'est peut-être pas initialisée
[Avertissement] AjoutContact.pas(267): La variable 'SenderEdt' n'est peut-être pas initialisée
[Avertissement] AjoutContact.pas(299): Le symbole 'fmShareDenyRead' est propre à une plate-forme
[Avertissement] ModifContact.pas(260): La variable 'senderEdt' n'est peut-être pas initialisée
[Avertissement] ModifContact.pas(271): La variable 'SenderEdt' n'est peut-être pas initialisée
[Avertissement] ModifContact.pas(312): Le symbole 'fmShareDenyRead' est propre à une plate-forme
Hormis l'avertissement concernant l'utilisation du symbole fmShareDenyRead, le reste peut poser de gros problèmes à l'exécution.
2- Il manque des contrôles à la suppression d'un contact : si on ne rentre aucune donnée et que l'on clique sur le bouton [ok], voici le beau message qui s'affiche :
---------------------------
Gestion Des Contacts
---------------------------
Base de données inconnue.
Alias: Contact.
---------------------------
OK
---------------------------
A affiner, donc.
3- idem que ci-dessus lorsque l'on tente de visualiser un contact ou tous les contacts avec une base de données vide.
4- "Visualiser un contact", puis cliquer sur "visualiser", on obtient ceci :
---------------------------
Gestion Des Contacts
---------------------------
Violation d'accès à l'adresse 005263D0 dans le module 'GDCManager.exe'. Lecture de l'adresse 0000033C.
---------------------------
OK
---------------------------
5- Au niveau du code, on trouve des redondances comme dans Timer1Timer et dans FormCreate (Accueil.pas) pour une simple mise à l'heure des différents composants. Place cette potion de code dans une procédure que tu appelles ensuite.
De même pour :
procedure TFenPrincipale.AjoutContact1Click(Sender: TObject);
begin
TFajoutContact.Create(Self);
ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
end;
{—————————————————————————————————————————————————————————————————————————}
procedure TFenPrincipale.Label11Click(Sender: TObject);
begin
TFajoutContact.Create(Self);
ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
end;
De plus, je dirai que c'est un peu maladroit qu'une fiche soit chargée de modifier le titre d'une autre fiche lorsque ce titre est statique.
6- Attention à la façon de nommer tes composants car cela peut prêter à confusion comme ici :
procedure TFenPrincipale.AjoutContact2Click(Sender: TObject);
begin
TFsuppContact.create(self);
ActiveMDIChild.Caption := 'Suppression d''un Contact';
end;
Le bouton AjoutContact a pour action d'afficher la fiche de suppression d'un contact !
7- Ce type de code fait un peu ringard de nos jours et me rappelle les applications des années 80 :
procedure TFenPrincipale.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if
MessageDlg('Cette operation fermera l''application. Voulez-vous effectuer cette operation ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
Application.Terminate
else
begin
Action := caNone;
end;
end;
On alerte l'utilisateur uniquement si des données ont été modifiées et non sauvegardées. D'autre part, éviter l'utilisation de l'appel à Application.Terminate qui arrête brutalement l'application sans laisser le temps aux composants orientés données de vider leurs buffers.
8- Attention à vérifier l'existence d'un fichier avant de l'ouvrir comme dans :
procedure Tsplash.FormShow(Sender: TObject);
begin
sprite := tbitmap.create;
sprite.loadfromfile('1.bmp');
9- Privilégier l'utilisation de TDataModule pour centraliser la logique métier en matière de gestion des données. Cela aurait évité de multiplier les composants TQuery sur chaque fiche et de retrouver des requêtes identiques d'une fiche à l'autre. Lors de la maintenance d'une application, cela peut devenir critique et coûteux en temps avec des tests inutiles quand il faut revisiter chaque fiche de l'application (qui peut en contenir plusieurs centaines). La preuve :
E:\delphifr\GDC\GDC Manager\Acceuil.pas
163 ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
171 ActiveMDIChild.Caption := 'Ajout d''un nouveau Contact';
187 ActiveMDIChild.Caption := 'Recherche et Modification d''un Contact';
195 ActiveMDIChild.Caption := 'Suppression d''un Contact';
E:\delphifr\GDC\GDC Manager\AjoutContact.pas
173 query1.SQL.Add('insert into contact (civilite,Societe,Nom,Prenom,Adresse,CodePostal,Ville,Pays,Site,Email,telephone,Fax,Mobile,DateNaiss,Observation,photo) values (:ci,:s,:n,:p,:a,:c,:v,:pa,:si,:e,:t,:f,:m,:d,:o,:pho)');
E:\delphifr\GDC\GDC Manager\ModifContact.pas
105 Query1.SQL.Add('select * from contact where nom = :p');
198 Query1.SQL.Add('UPDATE contact SET civilite=:ci ,societe=:s,Nom=:n,Prenom=:p,Adresse=:a,CodePostal=:c,ville=:v,pays=:pa,Email=:e,site=:si,telephone=:t,fax=:f,mobile=:m,datenaiss=:d,observation=:o,photo=:pho WHERE nom=:pr');
335 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
E:\delphifr\GDC\GDC Manager\SelectContact.pas
64 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
81 Query1.SQL.Add('select * from contact where nom = :p');
E:\delphifr\GDC\GDC Manager\SupprimerContact.pas
54 Query1.SQL.Add('select prenom from contact where nom = :p ');
86 Conf := MessageDlg(('Voulez-vous Vraiment supprimer le contact ' + combo.Text
92 Query1.SQL.Add('Delete from Contact WHERE nom=:pr');
116 Query1.SQL.Add('SELECT Nom from contact where Nom LIKE :p Order by Nom Asc');
Dans le code, on remarque aussi que tu ne vérifies aucune des données entrées par l'utilisateur et que tu ne prends même pas la précaution de "quoter" tes chaines. Rien de tel pour faire planter une requête si un contact s'appelle "Monsieur Archibald de l'archipel". Ta base de données est gravement exposée aux injections SQL.
Bon, je vais m'arrêter là et passer le relais aux autres. Tu as déjà de quoi occuper les quelques jours du long week-end qu'il te reste.
Mais, je le dis comme d'autres ici, pour une première c'est pas mal du tout.
6 mai 2008 à 18:08
Le TFrame est une sorte de panel que l' on peut disposer sur n' importe quel contenant (parent) comme une Form, un panel, un PageControl etc ...
Il se présente en Design-time comme une form et est travaillée comme cette dernière.
Sur ce TFrame, on y met les compos que l' on veut ainsi que le code associé. Ça fait penser à un ActiveX en fait. Les points forts comme le dit si bien Cari, sont la réutilisabilité, la simplicité et pas la peine d' installer puisque en fait, ce n' est pas un compo.
Par contre, il n' est pas visualisé dans son emplacement car on doit le faire par code:
Exemple:
FramAg := TFrameAgend.Create(FrmPrin);
FramAg.Parent := NoteBook_Page(NBookRight, 'AGENDA');
FramAg.Align := alClient;
Particulièrement, je l' utilise mais assez peu car j' ai commencé à utiliser des Dlls avant que le TFrame n' existe. Les Dlls sont compilées indépendemment des applis qui l' appelle alors que si l' on modifie un Frame, toutes les applis qui l' utilisent doivent être recompilées comme toute unité que l' on modifie.
A+
6 mai 2008 à 14:45
4 mai 2008 à 17:34
LAFARGE me fait penser à un truc...
Je n'y connais rien en BDD et j'espère ne pas dire de bêtises, mais il me semble que TFrame est aussi sous-exploité.
TFrame permet de céer une sorte de composant ré-utilisable sans qu'il soit néccessaire de l'installer.
De plus il permet qu'on le charge au moment voulu, seulement si c'est utile, et de placer le code le gérant dans son unité.
Je ne sais pas pourquoi on le voit si rarement...
29 avril 2008 à 12:58
Vu que c'est votre premier code je dit personnellement trés bien. vous avez fait du bon travail. trés bon courage, et bonne continuation.
28 avril 2008 à 19:57
C'est très bien mais ca serait bien si tu avais utilisé une base SQL distante ! les exemples avec access sont plusieurs !
Mais bon, ^^
28 avril 2008 à 18:44
si c' est ton premier code, c' est pas mal du tout:
- tu as fait le ménage dans les fichiers.
- les unités sont presques toutes nommées.
- les compos appelés dans le code sont plus ou moins nommés.
- Le code est assez bien présenté et semble plutôt correct.
Malheureusement je n' ai pas compilé parce que tu utilises des compos externes que je ne peux tester pour l' instant.
L' interface graphique et la disposition des compos sont à améliorer.
Si tu l' as fait tout seul (je t' avoue que j' en doute un peu), bravo!
A+