salut,
Pour afficher le résultat de la procédure de Serge et de Ph. B. dans la requête sans passer par une ListBox, faut-il ajouter un champ à la Query (à la conception) ou dans la table et ensuite faire un Select de ce champ qui servira à regrouper ces intervalles des Id_clients ?
Rapellons-nous que l'objectif est :
Localité: les "Id" qui vont avec
@+
NAbil
bon , j'avais du temps libre
essayes quand même de comprendre le code , avant de faire un copier coller bête
@philippe : si tu veux chercher la petite bête , je suis sur que tout n'est pas encore optimum
ici , le résultat sera mis dans un mémo (resultmemo) , une ligne par localité
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SELECT LOCALITE,NUMERO FROM CLIENTS ORDER BY LOCALITE,NUMERO
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 procedure TForm1.TestBtnClick(Sender: TObject); var wloc : String; // localité en cours wNum: Integer; // numero en cours sNum : Integer; // debut de la suite LigneMemo : String; // resultat pour une localité // mise en forme de la ligne procedure ModifierLigne; var t : integer; // utilisée pour le cas du EOF begin t:=Query1NUMERO.asInteger-Wnum; if Query1.EOF then t:=-1; // force t a -1 case t of 0 : begin if Length(Lignememo)= Length(Wloc) then LigneMemo:=Lignememo+' '+Inttostr(WNum) else LigneMemo:=Lignememo+','+Inttostr(WNum) ; snum:=wnum; end; 1 : Wnum:=Query1NUMERO.asInteger; -1 : if snum<>wnum then lignememo:=Lignememo+'...'+Inttostr(wnum); else begin if snum=wnum then Lignememo:=Lignememo+', ' else Lignememo:=Lignememo+'...'+inttostr(wnum)+', '; wNum:=Query1NUMERO.asInteger; sNum:=Query1NUMERO.asInteger; Lignememo:=Lignememo+Inttostr(WNum); end; end; end; begin Resultmemo.Clear; Query1.Active:=True; wNum:=0; wLoc:=''; while not Query1.Eof do begin if Wloc<>Query1LOCALITE.AsString then begin if WNum>0 then ResultMemo.Lines.Add(LigneMemo); wloc:=Query1LOCALITE.AsString; sNum:=Query1NUMERO.asInteger; wNum:=Query1NUMERO.asInteger; LigneMemo:=wloc; end; ModifierLigne; Query1.Next; end; ModifierLigne; ResultMemo.Lines.Add(LigneMemo); Query1.Active:=false; end;
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Bonjour à tous,
Merci pour le temps que tu as consacré à ce souci !
Oui, j'ai toujours pris note de tes conseils.
Mais là Serge t'es une bête
Le code fonctionne correctement,c'est ça ce que je voulais.
Une question, est-il possible avec cette procédure d'afficher le résultat de la procédure dans la Query sans passer par un TMemo? Car je dois faire un état qui englobe tout et bien sûr par la suite l'imprimé.
Merci encore.
@+
Nabil
c'est clairement non , sauf a passer par une table temporaire du genre
j'aurais certainement dit autrement s'il s'était agit d'une base Firebird (d'ailleurs je l'ai déjà dit ) Cela aurait été un bon exemple d'utilisation de procédure récursives et d'utilisation de lanction LIST je pense . Si j'ai encore du temps a perdre (et que ce n'est pas déjà fait), je pense que j'essaierai !Table TEMP
LOCALITE String
MEMO blob
mais il est toujours possible d'imprimer directement le memo , ou de passer par des evenements de calcul pour chaque Localité . Tout dépend du générateur utilisé
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Oui, c'est ça que je voulais éviter avant que je pose ma question. Passer par une Table temporaire et puis insérer les enregistrements et par la suite, faire le traitement voulu (ça serait fait par une requête Sélection + un Union, ou un Left Join je pense).
J'ai déjà crée il y a quelques temps une Table temporaire qui contient les champs: Localite (string [200]), IDS_Clients(Memo).
ça c'est une autre paire de manches Serge.
Mon générateur est ReportBuilder.
Dans mon état, il y a deux colonnes : une pour la localité et l'autre pour les Id_clients.
il faut donc copier à partir de chaque ligne:
les mots de chaque localité (ex:Nantes) dans la 1ère colonnes et les ID correspondant dans la 2ème colonne.
A+
Nabil
évidemment celui là je connais pas !
pour ce qui est de mettre le résultat en table temporaire par contre c'est très facile , il suffit de modifier légèrement le code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 procedure TForm1.TestBtnClick(Sender: TObject); var wloc : String; // localité en cours wNum: Integer; // numero en cours sNum : Integer; // debut de la suite LigneMemo : String; // resultat pour une localité // mise en forme de la ligne procedure ModifierLigne; var t : integer; // utilisée pour le cas du EOF begin t:=Query1NUMERO.asInteger-Wnum; if Query1.EOF then t:=-1; // force t a -1 case t of 0 : begin if Length(Lignememo)=0 then LigneMemo:=Inttostr(WNum) else LigneMemo:=Lignememo+','+Inttostr(WNum) ; snum:=wnum; end; 1 : Wnum:=Query1NUMERO.asInteger; -1 : if snum<>wnum then lignememo:=Lignememo+'...'+Inttostr(wnum); else begin if snum=wnum then Lignememo:=Lignememo+', ' else Lignememo:=Lignememo+'...'+inttostr(wnum)+', '; wNum:=Query1NUMERO.asInteger; sNum:=Query1NUMERO.asInteger; Lignememo:=Lignememo+Inttostr(WNum); end; end; end; procedure insertligne; begin // Query2 = INSERT INTO TABLETEMP(LOCALITE,LIGNE) VALUES (:LO,:LM) Query2.ParamByName('LO').asString:=wloc; Query2.ParamByName('LM').asString:=LigneMemo; Query2.ExecSQL; end; begin Resultmemo.Clear; Query1.Active:=True; wNum:=0; wLoc:=''; while not Query1.Eof do begin if Wloc<>Query1LOCALITE.AsString then begin if WNum>0 then insertligne; wloc:=Query1LOCALITE.AsString; sNum:=Query1NUMERO.asInteger; wNum:=Query1NUMERO.asInteger; LigneMemo:=''; end; ModifierLigne; Query1.Next; end; ModifierLigne; insertligne; Query1.Active:=false; end;
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Salut à tous,
@Serge : sans faire de pub, Report Builder est bon générateur d'état.
Oui, c'est facile de mettre le résultat dans table temporaire et de le récupérer ensuite .
Je n'ai pas Delphi là où je suis(au boulot. eh oui,dimanche c'est le début de semaine chez nous! ), donc je le testerai sûrement ce soir et je te dirai ce que ça donne mon ami.
Mais c'est vrai Serge, "Paradox" c'est de la merde ,pardon pour ce mot
c'est toujours limité en SQL, il y a plein de trucs qu'on peut pas faire sans parler des index qui sont pas à jour quand les tables sont endommagés. .Avant que je pose ma question sur le forum, j'ai déjà fait une recherche sur le net et j'ai bien sûr trouvé ton poste qui se rapport à la ma question mais sous Firdbird.
enfin bon, merci encore.
Nabil
Bonjour à tous,
@ Serge:
ça marche bien sauf un petit détail dans:
A+
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 begin // Query2 = INSERT INTO TABLETEMP(LOCALITE,LIGNE) VALUES (:LO,:LM) Query2.ParamByName('LO').asString:=wloc; // "wloc" donne bien les Localités mais "LigneMemo" donne "Localité + numéros" alors qu'on a seulement besoin des numéros. :mur: Query2.ParamByName('LM').asString:=LigneMemo; Query2.ExecSQL;
Modérateur Delphi
Le guide du bon forumeur :
- Les règles du forum tu liras
- La FAQ et les tutoriels tu consulteras
- La fonction Recherche tu utiliseras
- Google tu vénèreras
__________
Rayek World : Youtube Facebook
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
pour table temporaire je préfère Clientdataset, ou le composant proposé par Franck , mais aussi on peut imprimer directement dans report buider en utilisant les événements des champs
PAS DE DESTIN, C'EST CE QUE NOUS FAISONS
C'est ok même pour l'insertion .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 case t of 0 : begin if Length(Lignememo)= Length(Wloc) then LigneMemo:= Inttostr(WNum) ; // j'ai effacé : Lignememo+' ' // else LigneMemo:= Inttostr(WNum) ; snum:=wnum;
Tu sais Serge, si je n'applique pas un tri des données, la procédure 'collecte' tous les ID_clients avec les localités qui lui correspondent:
Mais quand ce tri est activer, elle loupe quelques ID
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Query1.Active := False; Query1.SQL.Clear; Query1.SQL.Add(SELECT LOCALITE,NUMERO FROM CLIENTS '); Query1.SQL.Add(' ORDER BY LOCALITE,NUMERO'); Query1.Active:=True;
Le DBEdit2 est la Localite.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Query1.Active := False; Query1.SQL.Clear; Query1.SQL.Add(SELECT LOCALITE,NUMERO FROM CLIENTS WHERE Localite='''+DBEdit2.Text+''' '); Query1.SQL.Add(' ORDER BY LOCALITE,NUMERO'); Query1.Active:=True;
Elle affiche seulement le début d'une série et pas sa fin
Ex: Paris : 1,29-50,120-129,990-1020
Le '1020' le loupe, elle m'affiche seulement '990'.
c'est vraiment incompréhensible non !
A+
Nabil
holalala ...
pourquoi n'y a t'il pas une table Client et une table Localité ?
Table Clients :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part id_client, id_city, ...
Table cities :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part id_city, name, ...
1 : on bouffe moins de ressources pour stocker les id_client dans un champs non prévus pour ... au risque de se retrouver avec un champs de 42Peta-octet... :/
2 : on simplifie les requêtes, le tris etc.
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 SELECT cl.id_client, cl.name, ci.id_city, ci.name FROM clients AS cl, cities AS ci WHERE cl.id_city=ci.id_city AND (autre condition) ORDER BY ci.id_city, cl.id_client ASC
et des group by et des count et des sum etc etc.
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
Ma messagerie n'est pas la succursale du forum... merci!
ça était comme ça au début.En réalité, J'ai la Table Clients avec les champs: id_client , Nom et prénom, Localité, téléphone,...
Tu n'as pas bien compris mon souci, je veux détecter les trous des ID dans une série entière suivant chaque localité:Nantes : ID: 1,2,3,7 ,8,9,10,11, 25
Je veux faire: 1-3, 7-11,25
A+
Si si j'avais compris, ce que je comprend pas c'est la finalité de trouver ces fameux trous ...
pour moi ça raisonne comme un "se prendre la tête pour un truc inutile parce que mal foutus à la base".
Tu t'embêterai moins a restructurer correctement que de chercher a faire "des trucs" qui te fond tourner en rond pour rien et au risque qu'a la fin d'une longue prise de tête infructueuse avec son lot de solutions improductives tu décide de refaire une structure correcte.
Avec une telle structure, admettons que tu cherche ou est localisé le client 5 (à paris par exemple), et dans paris tu as '2-9,12-32'
Tu fais quoi comme requête ?
à part un truc imbuvable à base fonctions à la noix et de like bancale ?
Et je parle même pas de la mise à jours de ce champs ... le mec qui en est à l'origine mériterais de bruler sur la stèle des sacrifices d'Oracle tiens...
Après, oui, le coté défis est intéressant, pour ma part je ferai un traitement externe à base de delphi.
Mais, ta base actuelle c'est le genre de truc que personne ne voudrais voir en Production.
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
Ma messagerie n'est pas la succursale du forum... merci!
Bonjour à tous,
@Dr.Who : je t'ai déjà dis que tu n'as pas bien pigé ce que je veux exactement, le but est dans un état de sortie (l'impression).
je ne perd pas la tête pour un truc inutile.Voilà, admettant que dans une localité, j'ai 200 clients et qu'on veut imprimer chaque localité avec les ID_Clients.Tu remarquerais que ces Id vont prendre beaucoup d'espace :de 1 jusqu'à 200!
Alors pourquoi pas les grouper comme :1-200 non?
Pour la recherche d'un client, on a pas besoin de cette procédure.Dans La Table Clients chaque enregistrement affiche un id_Client et sa localité, Un TEdit pour la recherche fera l'affaire.on tape '5' et on se pointe sur ce client.
+A
Nabil
non, cela veut simplement dire que le EOF est mal géré .Elle affiche seulement le début d'une série et pas sa fin
Ex: Paris : 1,29-50,120-129,990-1020
Le '1020' le loupe, elle m'affiche seulement '990'.
c'est vraiment incompréhensible non !
c'est encore plus vrai de dire que tes modifications sont responsables de l'erreur. Pour preuve , le dernier code mettant le tout dans un memo donnait le résultat correct.
1- je remarque que tu n'as pas fait la bonne correction
2-
le SQL avec un Where sur la Localité est une honte dans sa forme mais surtout dans le fond
Code ça c'est pour la forme : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Query1.Active := False; Query1.SQL.Clear; Query1.SQL.Add('SELECT LOCALITE,NUMERO FROM CLIENTS WHERE Localite=:L'); Query1.SQL.Add(' ORDER BY LOCALITE,NUMERO'); Query1.ParambyName('L').asString:=DBEdit2.Text; Query1.Active:=True;
pour le fond : s'il n'y a qu'une seule localité , alors il n'y a pas lieu d'utiliser le test sur le changement de localisation.
3- en général quand on fait une édition ce n'est pas pour n'avoir qu'une seule ligne (donc dans notre cas une seule localité)
je suis d'accord avec Dr Who sur la structure des tables bien que cela ne change rien à l'exercice. Ce genre d'exo était très en vogue en 1983 dans les écoles d'apprentissage a la programmation , a tel point que je voix encore le schéma de programmation (d'une méthode oubliée) dans ma tête . J'ai déjà également dit que Paradox n'etait certainement pas le meilleur choix bien que ce fut un très bon outil (au siècle dernier) quand les SGBD n'existaient pas encore.
MVP Embarcadero
Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
SGBD : Firebird 2.5, 3, SQLite
générateurs États : FastReport, Rave, QuickReport
OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd
Serge: merci pour tes bonnes remarques.
Oui c'est sûr que le EOF est mal géré car si on ajoute un ID_Client dont la Localité est la même pour la suite de série, il y est!
ex: Paris :1,29-50,120-129,990-1020=> 1,29-50,120-129,990
résultat ok après insertion:
1,29-50,120-129,990[COLOR="rgb(46, 139, 87)"]-1020[/COLOR] , 2025
je n'ai pas fait la bonne correction
J'ai essayé hier avec une requête paramétrée ,elle donne le même résultat que
pourOui, je suis tout à fait d'accord avec vous sur le choix de la BD Paradox, d'ailleurs je l'ai déjà dit.
Code : Sélectionner tout - Visualiser dans une fenêtre à part WHERE Localite='''+DBEdit2.Text+'''
Au début de ce topic, j'ai dit que je veux améliorer une vieille application faite avec Paradox comme BD.
Oui dans la mesure où on cherche à filtrer la query une une seul localité,
mais dans le cas contraire ,on fait le Select déjà cité:A+
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Query1.Active := False; Query1.SQL.Clear; Query1.SQL.Add('SELECT LOCALITE,NUMERO FROM CLIENTS WHERE Localite=:L'); Query1.SQL.Add(' ORDER BY LOCALITE,NUMERO'); Query1.ParambyName('L').asString:=DBEdit2.Text; Query1.Active:=True;
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager