Précédent   Forum du club des développeurs et IT Pro > Environnements de développement > Delphi > Débutant
Débutant Pour bien débuter avec Delphi
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 12/02/2013, 19h27   #41
Dr.Who
Membre Expert
 
Avatar de Dr.Who
 
Inscription : septembre 2009
Messages : 980
Détails du profil
Informations personnelles :
Âge : 34

Informations forums :
Inscription : septembre 2009
Messages : 980
Points : 1 175
Points : 1 175
pour l'impression ou l'affichage :
Code :
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
 
function gluIDs(aIDs: array of integer): string;
var L,F,T : integer;
begin
  result := '';
 
  L := Length(aIDs);
  F := 0;
  T := 0;
  while T < L do
  begin
    F := T;
 
    while (aIDs[T+1] = aIDs[T]+1) and (T < L) do
      inc(T);
 
    if (T < L+1) and (F < T) then
    begin
      result := result + format('%d-%d',[aIds[F], aIDs[T]])
    end
    else
      result := result + intToStr(aIds[T]);
 
    inc(T);
    if T < L then
      result := result + ',';
  end;
end;
Mais voila, tu dois juste fournir un tableau d'integer disctinct correspondant aux id.
Et pourquoi je dis qu'il faut un champs Id_localite disctinct dans le client pour eviter de faire une fonction lourde "ungluIds->array of integer".
Après rien n'empèche, mais j'ai peur qu'avec 100000 entrées ou plus, on mette plus de 10 secondes à générer et corriger les ids.

gluIds mets 5 seconde (4437ms) environ pour traiter 4 200 000 Id.
(test basé sur 100 000 * 10 call gludIDs[ 42 ids ])
__________________
[ 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!
Dr.Who est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2013, 07h44   #42
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par Dr.Who Voir le message
Mais voila, tu dois juste fournir un tableau d'integer disctinct correspondant aux id.
Et pourquoi je dis qu'il faut un champs Id_localite disctinct dans le client pour eviter de faire une fonction lourde "ungluIds->array of integer".
Après rien n'empèche, mais j'ai peur qu'avec 100000 entrées ou plus, on mette plus de 10 secondes à générer et corriger les ids.

gluIds mets 5 seconde (4437ms) environ pour traiter 4 200 000 Id.
(test basé sur 100 000 * 10 call gludIDs[ 42 ids ])

Bonjour à tous,

@ Dr.Who: merci pour ton aide . Oui c'est très rapide.

Tu sais, j'ai restructuré toutes les tables de la base de donnée et j'ai réécrit tout depuis le début.Cette application peut-être finalisée que si je trouve une solution à ce souci qui est de grouper les id à l'affichage et à l'impression .

Il me reste qu'à corriger l'erreur dans la procédure de notre ami SergioMaster (d'ailleurs merci aussi à lui de me prêter de l'aide).

@ Serge : à propos de cette erreur , dis-moi où il faut corriger stp? Car comme je t'ai dis, la procédure loupe le dernier chiffre de la suite de série si on cherche à filtrer la query une une seul localité, par contre elle fonctionne sans souci s'il n'y a pas de filtre.

Merci.

NABIL74
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 21h44   #43
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Bonsoir à tous,

@ Serge:

Tu sais quand je fais le tri sur une localité,elle fonctionne très bien.
J'ai rien changé dans ta procédure.En fait, j'ai vidé la table Clients et j'ai insérer à nouveau les Id_Clients et là boom ça marche!

Pendant presque une semaine que ça me tape sur les nerfs seulement pour un vidage de la table Clients !!!!



Un énorme merci à vous de m'avoir prêter de l'aide.
Je ne sais pas comment te remercier mon cher ami Serge.Mille fois MERCI et bravo.

Si tu fais un jour un tour en Algérie, on pourrait faire ensemble une belle partie de pêche.

Encore fois merci.

Pour moi ce topic est résolu et dieu merci

Nabil
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2013, 22h59   #44
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Par défaut Amélioration

bonsoir,

je me demandais si on pourrait améliorer ça en faisant un Count des Id_Client selon chaque localité parce qu'avec :

Code :
1
2
3
4
5
6
7
 
Query1.Active := False;
Query1.SQL.Clear;
Query1.SQL.Add('SELECT LOCALITE,NUMERO, Count(*)CountALL FROM CLIENTS  WHERE  Localite=:L');
Query1.SQL.Add(' ORDER BY LOCALITE,NUMERO');
Query1.ParambyName('L').asString:=DBEdit2.Text;
Query1.Active:=True;
ça ne marche pas le Count , il renvoit bien sûr '1' , par contre si on efface le NUMERO de la requête ça marche, on récupère le nombre des id de chaque localité mais dans notre cas, le Id_Client est la base de la requête.

une idée?

Merci
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 14/02/2013, 23h50   #45
Ph. B.
Expert Confirmé
 
Avatar de Ph. B.
 
Homme Philippe
Inscription : avril 2002
Messages : 1 058
Détails du profil
Informations personnelles :
Nom : Homme Philippe
Âge : 46
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : avril 2002
Messages : 1 058
Points : 2 808
Points : 2 808
Envoyer un message via ICQ à Ph. B. Envoyer un message via Skype™ à Ph. B.
Citation:
Envoyé par NABIL74 Voir le message
ça ne marche pas le Count , il renvoit bien sûr '1' , par contre si on efface le NUMERO de la requête ça marche, on récupère le nombre des id de chaque localité mais dans notre cas, le Id_Client est la base de la requête.
Count est une fonction d'agrégation comme min, max, avg et s'utilise généralement associé à une clause d’agrégation group by...
Avec Firebird ou Ms SqlServer, on utiliserait une Expression de Table Commune ou CTE (c. Message de @SergioMaster). Avec Paradox, comme je l'ai indiqué au début , je ferais cela en 2 étapes via une table temporaire ou un clientdataset.
__________________
Philippe.
Ph. B. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2013, 19h01   #46
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par Ph. B. Voir le message
Count est une fonction d'agrégation comme min, max, avg et s'utilise généralement associé à une clause d’agrégation group by...
Avec Firebird ou Ms SqlServer, on utiliserait une Expression de Table Commune ou CTE (c. Message de @SergioMaster). Avec Paradox, comme je l'ai indiqué au début , je ferais cela en 2 étapes via une table temporaire ou un clientdataset.
Oui Ph.B ,SergioMaster m'a déjà dit que sur Firebird, on pourrait faire ça en utilisant les requêtes récursives , mais avec Paradox, tu dis qu'il faut passer par deux étapes via une table temporaire ou un clientdataset.
La table temporaire je l'ai, mais j'ignore si elle aura avec les mêmes champs ou non.
La procédure de Serge me va bien , les enregistrements sont poster dans cette table temporaire et puis je les récupère pour imprimer mon état, par contre pour faire un Count des id là je ne sais pas comment m'y prendre, ça me dépasse un peu .

A+

Nabil
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2013, 20h19   #47
Ph. B.
Expert Confirmé
 
Avatar de Ph. B.
 
Homme Philippe
Inscription : avril 2002
Messages : 1 058
Détails du profil
Informations personnelles :
Nom : Homme Philippe
Âge : 46
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : avril 2002
Messages : 1 058
Points : 2 808
Points : 2 808
Envoyer un message via ICQ à Ph. B. Envoyer un message via Skype™ à Ph. B.
Citation:
Envoyé par NABIL74 Voir le message
La procédure de Serge me va bien , les enregistrements sont poster dans cette table temporaire et puis je les récupère pour imprimer mon état, par contre pour faire un Count des id là je ne sais pas comment m'y prendre, ça me dépasse un peu .
Pour compter, une solution est de le faire lors de la recherche des ID !
Je reprends le code que j'avais écrit pour la recherche des intervalles et je vais modifier 4 lignes :
Code :
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
64
// Recherche des intervalles et comptage des éléments de chaque intervalle
procedure TForm1.BtnIntervallesClick(Sender: TObject);
var
  Deb,
  Fin,
  Courant: Integer;
begin
  ListeSequence.Clear;
 
  QEntete.Active := False;
  QEntete.SQL.Clear;
  QEntete.SQL.Add('SELECT DISTINCT(NUMERO) FROM FACTURES WHERE ANNEE = ' + QuotedStr(CodeSaison.Text));
  QEntete.SQL.Add('ORDER BY NUMERO');
  QEntete.Active := True;
 
  with QEntete do
  begin
    DisableControls;
    try
      First;
      Deb := MaxInt;
      Courant := MaxInt;
      while not EOF do
      begin
        Fin := FieldByName('NUMERO').AsInteger;
        if Deb > Fin then
        begin
          Deb := Fin
        end
        else
        begin
          if Courant + 1 < Fin then
          begin
            if Deb = Courant then
              //ListeSequence.Items.Add(IntToStr(Deb))
              ListeSequence.Items.Add(IntToStr(Deb)
                + ' [1]') // <=> Count = 1
            else
              //ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant));
              ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant)
                + ' [' +  IntToStr(Courant - Deb + 1) + ']');  // <=> Count = Courant - Deb + 1
            Deb := Fin;
          end;
        end;
        Courant := Fin;
        Next;
      end;
    finally
      if Deb = Courant then
        //ListeSequence.Items.Add(IntToStr(Deb))
        ListeSequence.Items.Add(IntToStr(Deb)
          + ' [1]')  // <=> Count = 1
      else
        //ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant));
        ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant)
          + ' [' +  IntToStr(Courant - Deb + 1) + ']');  // <=> Count = Courant - Deb + 1
 
      EnableControls;
    end;
  end;
  QEntete.Active := False;
  if ListeSequence.Items.Count > 0 then
    ListeSequence.Visible := True;
end;
Reste à l'adapter à ce que vous avez repris du code de @SergioMaster .
__________________
Philippe.
Ph. B. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2013, 22h57   #48
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Bonsoir,

@ Ph.B : merci pour ton aide

Voilà ce que j'ai fait avec la procédure de Serge:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)  +  ' [' +  IntToStr(wNum - sNum + 1) + ']'
     else begin
           if snum=wnum then Lignememo:=Lignememo+', '
           else Lignememo:=Lignememo+'...'+inttostr(wnum)  +  ' [' +  IntToStr(wNum - sNum + 1) + ']' +', ');
            wNum:=Query1NUMERO.asInteger;
            sNum:=Query1NUMERO.asInteger;
            Lignememo:=Lignememo+Inttostr(WNum);
          end;
     end;
    end;
Elle n'est pas ok à 100%,je t'explique: s'il s'agit d'une suite de série, c'est ok, ex affichage:
100-120 [21]

mais s'il s'agit d'un seul chiffre, là pas de count ,ex affichage:
150 => rien.

Ecoute, y a t-il pas une solution pour poster ce count dans un champ de la Table temporaire ?

Merci

A+

NAbil
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 08h11   #49
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 272
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 4 272
Points : 7 533
Points : 7 533
Franchement l'effort n'était pas bien gros pour rajouter le nombre . Il me semble en plus que Ta modification apportée a amener une erreur grossière !
le Else après le -1 est un else de Case , pas du if snum<>wnum

Je ne crois pas que tu ais bien saisi comment fonctionne cette fonction
Code :
1
2
3
4
5
6
7
8
   // EOF  
   -1 : if snum<>wnum then lignememo:=Lignememo+'...'+Inttostr(wnum)  +  ' [' +  IntToStr(wNum - sNum + 1) + ']'
         else LigneMemo:=LigneMemo+' [1]';
    // Autres valeurs de T 
     else begin
           if snum=wnum then Lignememo:=Lignememo+' [1], '
           else Lignememo:=Lignememo+'...'+inttostr(wnum)  +  ' [' +  IntToStr(wNum - sNum + 1) + ']' +', ');
P.S. Correction faite le matin , avant mon café => cerveau encore embrumé et non testée

remarque pour la dernière ligne IntToStr(wnum-snum+1) aurait pu être remplacé par T+1 ce que tu n'as même pas remarqué , cependant pour la lisibilité entre le cas T>1 et EOF il vaut mieux laisser tel quel


et non , on ne peut pas utiliser la fonction d'agrégat COUNT et la stocker dans la table temporaire tout simplement parce que tu ne connais pas le nombre de "suite" donc le nombre de champs "nombre" qu'il te faudrait à moins de faire un enregistrement par "suite"
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 13h03   #50
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par SergioMaster Voir le message
Franchement l'effort n'était pas bien gros pour rajouter le nombre . Il me semble en plus que Ta modification apportée a amener une erreur grossière !
Bonjour,

@ Serge:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
case t of
     0 : begin
         if Length(Lignememo)=0
             then LigneMemo:=Inttostr(WNum)
             else LigneMemo:=Lignememo+','+Inttostr(WNum) ;
         snum:=wnum;
         end;
 
      1 : Wnum:=Query1Num_Objet.asInteger ;
 
     -1 : if snum<>wnum then lignememo:= Lignememo+'-'+Inttostr(wnum)+  ' [' +  IntToStr(wNum - sNum + 1) + ']'
 
          else LigneMemo:=LigneMemo+' [1]';
     else begin
          if snum=wnum then Lignememo:=Lignememo+' [1], '
           else Lignememo:=(Lignememo+'-'+inttostr(wnum) +  ' [' +  IntToStr(wNum - sNum + 1) + ']' +', '); 
            wNum:=Query1Num_Objet.asInteger;
            sNum:=Query1Num_Objet.asInteger;
            Lignememo:=(Lignememo + Inttostr(WNum));
          end;
     end;
    end;
Voilà ce que ça donne:

Nantes,2704 // pas de [1] ??
Bordeaux,2071 // pas de [1] ??
Montpellier,2653 // pas de [1]
Paris,1 [1], 61-65 [5], 100-120 [21], 200-210 [11], 240-250 [11], 3060 //ici pour 3060, pas de [1] ??
Cannes,2603 [1] // par contre ici c'est ok [1]


Citation:
Envoyé par SergioMaster Voir le message
remarque pour la dernière ligne IntToStr(wnum-snum+1) aurait pu être remplacé par T+1 ce que tu n'as même pas remarqué , cependant pour la lisibilité entre le cas T>1 et EOF il vaut mieux laisser tel quel
Non, j'ai bien remarqué mais il renvoit un compte qui n'est pas bon.Voilà ce que j'ai obtenu avec le T+1
Code :
1
2
 if snum=wnum then Lignememo:=Lignememo+' [1], '
           else Lignememo:=(Lignememo+'-'+inttostr(wnum) +  ' [' +  IntToStr(T + 1) + ']' +', '); //**
résultat:

Nantes,2704
Bordeaux,2071
Montpellier,2653
Paris,1 [1], 61-65 [36], 100-120 [81], 200-210 [31], 240-250 [2811], 3060
Cannes,2603 [1]

Serge, ne crois-tu pas que si on groupait les id de toute la localité , c'est mieux non?
ex:
Paris,1 [1], 61-65 [5], 100-120 [21], 200-210 [11], 240-250 [11], 3060
=> Paris= 1 + 5 +21 + 11 + 11 + 1 = 50

Paris= 50 c'est ça qui est mieux.

Pour poster le 50 dans la table temporaire, une idée?

Merci

A+

Nabil
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 14h12   #51
Ph. B.
Expert Confirmé
 
Avatar de Ph. B.
 
Homme Philippe
Inscription : avril 2002
Messages : 1 058
Détails du profil
Informations personnelles :
Nom : Homme Philippe
Âge : 46
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : avril 2002
Messages : 1 058
Points : 2 808
Points : 2 808
Envoyer un message via ICQ à Ph. B. Envoyer un message via Skype™ à Ph. B.
Citation:
Envoyé par NABIL74 Voir le message
Voilà ce que ça donne:

Nantes,2704 // pas de [1] ??
Bordeaux,2071 // pas de [1] ??
Montpellier,2653 // pas de [1]
Paris,1 [1], 61-65 [5], 100-120 [21], 200-210 [11], 240-250 [11], 3060 //ici pour 3060, pas de [1] ??
Cannes,2603 [1] // par contre ici c'est ok [1]
AMHA, il manque un test en sortie d'une boucle intermédiaire de votre code, d'où l'absence de compteur en fin de chaque regroupement de localité, sauf la dernière qui doit être traitée par la boucle principale.
Citation:
Envoyé par NABIL74 Voir le message
Serge, ne crois-tu pas que si on groupait les id de toute la localité , c'est mieux non?
ex:
Paris,1 [1], 61-65 [5], 100-120 [21], 200-210 [11], 240-250 [11], 3060
=> Paris= 1 + 5 +21 + 11 + 11 + 1 = 50

Paris= 50 c'est ça qui est mieux.

Pour poster le 50 dans la table temporaire, une idée?
Il suffit en partant de la boucle de comptage de séquence de rajouter une variable de cumul initialisée à 0 pour chaque nouvelle localité et qui est incrémentée de 1 ou de wNum - sNum + 1. cette info viendra remplacer les cumuls par séquence...
__________________
Philippe.
Ph. B. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 15h51   #52
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par Ph. B. Voir le message
AMHA, il manque un test en sortie d'une boucle intermédiaire de votre code, d'où l'absence de compteur en fin de chaque regroupement de localité, sauf la dernière qui doit être traitée par la boucle principale.
C'est fort possible qu'il manque un test en sortie d'une boucle intermédiaire du code.


Citation:
Envoyé par Ph. B. Voir le message
Il suffit en partant de la boucle de comptage de séquence de rajouter une variable de cumul initialisée à 0 pour chaque nouvelle localité et qui est incrémentée de 1 ou de wNum - sNum + 1. cette info viendra remplacer les cumuls par séquence...
Franchement, dès le début ça était compliqué pour moi de grouper la suite de série de chiffres des id, et maintenant, pour compter le nombre des id de chaque localité c'est encore plus compliqué !

C'est vrai que dans cette application, j'ai un peu mélangé les pinceaux





Nabil
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 17h05   #53
Ph. B.
Expert Confirmé
 
Avatar de Ph. B.
 
Homme Philippe
Inscription : avril 2002
Messages : 1 058
Détails du profil
Informations personnelles :
Nom : Homme Philippe
Âge : 46
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : avril 2002
Messages : 1 058
Points : 2 808
Points : 2 808
Envoyer un message via ICQ à Ph. B. Envoyer un message via Skype™ à Ph. B.
Citation:
Envoyé par NABIL74 Voir le message
Franchement, dès le début ça était compliqué pour moi de grouper la suite de série de chiffres des id, et maintenant, pour compter le nombre des id de chaque localité c'est encore plus compliqué !
Je pense surtout que vous vous faites une montagne d'un petit faux plat !
Donc, à partir de mon précédent postulat
Citation:
Il suffit en partant de la boucle de comptage de séquence de rajouter une variable de cumul initialisée à 0 pour chaque nouvelle localité et qui est incrémentée de 1 ou de wNum - sNum + 1. cette info viendra remplacer les cumuls par séquence...
et en adaptant mon code, j'obtiens :
Code :
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Recherche des intervalles et comptage des éléments de chaque intervalle et cumul général
procedure TForm1.BtnIntervallesClick(Sender: TObject);
var
  Deb,
  Fin,
  Courant,
  Cumul: Integer;
begin
  ListeSequence.Clear;
 
  QEntete.Active := False;
  QEntete.SQL.Clear;
  QEntete.SQL.Add('SELECT DISTINCT(NUMERO) FROM FACTURES WHERE ANNEE = ' + QuotedStr(CodeSaison.Text));
  QEntete.SQL.Add('ORDER BY NUMERO');
  QEntete.Active := True;
  Cumul := 0;
 
  with QEntete do
  begin
    DisableControls;
    try
      First;
      Deb := MaxInt;
      Courant := MaxInt;
      while not EOF do
      begin
        Fin := FieldByName('NUMERO').AsInteger;
        if Deb > Fin then
        begin
          Deb := Fin
        end
        else
        begin
          if Courant + 1 < Fin then
          begin
            if Deb = Courant then
            begin
              //ListeSequence.Items.Add(IntToStr(Deb))
              ListeSequence.Items.Add(IntToStr(Deb)
                + ' [1]'); // <=> Count = 1
              Cumul := Cumul + 1;
            end
            else
            begin
              //ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant));
              ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant)
                + ' [' +  IntToStr(Courant - Deb + 1) + ']');  // <=> Count = Courant - Deb + 1
              Cumul := Cumul + Courant - Deb + 1;
            end;
            Deb := Fin;
          end;
        end;
        Courant := Fin;
        Next;
      end;
    finally
      if Deb = Courant then
      begin
        //ListeSequence.Items.Add(IntToStr(Deb))
        ListeSequence.Items.Add(IntToStr(Deb)
          + ' [1]');  // <=> Count = 1
        Cumul := Cumul + 1;
      end
      else
      begin
        //ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant));
        ListeSequence.Items.Add(IntToStr(Deb) + '..' + IntToStr(Courant)
          + ' [' +  IntToStr(Courant - Deb + 1) + ']');  // <=> Count = Courant - Deb + 1
        Cumul := Cumul + Courant - Deb + 1;
      end;
      // Rajout du cumul en fin de liste
      ListeSequence.Items.Add('Cumul = ' + InToStr(Cumul);
 
      EnableControls;
    end;
  end;
  QEntete.Active := False;
  //if ListeSequence.Items.Count > 0 then
  ListeSequence.Visible := True;
end;
Et le tour est joué !
__________________
Philippe.
Ph. B. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 20h30   #54
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Merci beacoup Phillipe pour ton aide.

impécable !

Pour info, c'est une application que je développe pour un ami à moi (gratuitement) qui possède une société de vente.
Alors, il m'a demandé de lui codé une.

Je n'ai pas eu trop de difficulter à le faire, sauf pour le groupage des ID, là je me suis arraché les cheveux

Il a des clients dans pas mal de villes d'Algérie. Alors, il arrive des fois que dans une ville comme Alger, il y a plusieurs clients dans chaque arrondissements.

Il m'a dis de faire aussi le groupage des ID suivant la Localité et Arrondissement(ou par Cité)


Pardon pour ce changement de situation de dernière minute, après beaucoup d'efforts !

là, comment on peut adapter le code?

Rappellons que l'objectif maintenant est :

- Grouper les ID selon : la Localité et Arrondissement(ou Cité).

- Et de le faire comme ça :

Nantes, 2704, Arrondissement13 =1
Bordeaux,2071 , Arrondissement1 =1
Montpellier,2653 , Arrondissement19 =15
Paris,1-15, Arrondissement18 = 16 , 61-65 Arrondissement17 = 5
Cannes,2603 ,Arrondissement12 =1


Encore une fois Pardon les copains
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 17/02/2013, 08h42   #55
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 272
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 4 272
Points : 7 533
Points : 7 533
, ben moi j'abandonne , un cahier des charges qui change sans arrêt, une utilisation de techno obsolète , c'en est trop !

pour conclure , voici une requête FIREBIRD qui fournirai les informations (j'y ai même inclus les districts)
sans passer par procedures , uniquement des Common Table Expression et encore , je suis sur que c'est largement perfectible en utilisant la récursivité

Code SQL :
1
2
3
4
5
6
7
8
CREATE TABLE TCLI
(
  NUM Integer NOT NULL,
  LOCALITE Varchar(20) NOT NULL,
  DISTRICT Varchar(20) NOT NULL,
 
  CONSTRAINT PK_TCLI PRIMARY KEY (NUM)
);

Code SQL JEU d'essai :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('1', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('2', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('3', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('4', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('5', 'NANTES', 'A');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('6', 'NANTES', 'A');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('7', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('8', 'NANTES', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('10', 'PARIS', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('20', 'NANTES', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('21', 'NANTES', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('22', 'NANTES', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('30', 'NANTES', 'B');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('31', 'NANTES', 'A');
INSERT INTO TCLI (NUM, LOCALITE, DISTRICT) VALUES ('32', 'NANTES', 'A');
Code SQL :
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
 
WITH 
--DEBUT DE SERIE
DT AS (
SELECT  LOCALITE,DISTRICT,NUM
FROM    TCLI t
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    TCLI r 
        WHERE   LOCALITE=T.LOCALITE AND DISTRICT=T.DISTRICT AND r.NUM = t.NUM -1
 
        )
),
--FIN DE SERIE
NT AS (
SELECT  LOCALITE,DISTRICT,NUM
FROM    TCLI t
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    TCLI r 
        WHERE   LOCALITE=T.LOCALITE AND DISTRICT=T.DISTRICT AND r.NUM = t.NUM +1
 
        )
)
 
 
SELECT LOCALITE,DISTRICT,NUM AS DEBUT,(SELECT FIRST 1 NUM FROM NT WHERE NUM>=DT.NUM) AS FIN,
       (SELECT FIRST 1 NUM FROM NT WHERE NUM>=DT.NUM)-NUM+1 AS NB 
FROM DT
ORDER BY 1,2,3

Citation:
Envoyé par Resultat
NANTES A 5 6 2
NANTES A 31 32 2
NANTES B 8 8 1
NANTES B 20 22 3
NANTES B 30 30 1
PARIS B 1 4 4
PARIS B 7 7 1
PARIS B 10 10 1
[edit]
en 'affinant' on arrive même a obtenir ceci
Citation:
NANTES A 5 ..6,31 ..32 4
NANTES B 30 ,8 ,20 ..22 5
PARIS B 7 ,10 ,1 ..4 6
Dommage que la fonction d'aggrégat LIST , n'ordonne pas (du moins en FB 2.1) ;-)
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/02/2013, 17h58   #56
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par SergioMaster Voir le message
, ben moi j'abandonne , un cahier des charges qui change sans arrêt, une utilisation de techno obsolète , c'en est trop !

pour conclure , voici une requête FIREBIRD qui fournirai les informations (j'y ai même inclus les districts)
sans passer par procedures , uniquement des Common Table Expression et encore , je suis sur que c'est largement perfectible en utilisant la récursivité
@ Serge : vraiment désolé pour le changement du cahier de charge .

et un grand Merci pour ta procédure de regroupement

Merci pour la requête récursive sur Firebird.

@ Phillipe : un grand Merci à toi aussi pour ta procédure de regroupement
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2013, 07h57   #57
SergioMaster
Modérateur
 
Avatar de SergioMaster
 
Homme Serge Girard
Développeur informatique
Inscription : janvier 2007
Messages : 4 272
Détails du profil
Informations personnelles :
Nom : Homme Serge Girard
Âge : 56
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : Industrie

Informations forums :
Inscription : janvier 2007
Messages : 4 272
Points : 7 533
Points : 7 533
Code :
SELECT LOCALITE||' '||DISTRICT AS LOCALITE,NUMERO FROM CLIENTS ORDER BY LOCALITE,DISTRICT,NUMERO
sans changer une ligne de code cela pourrait fonctionner
__________________
La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein
J'entends et j'oublie. Je vois et je me souviens. Je fais et je comprends . Confucius
Si votre seul outil est un marteau, vous aurez tendance a ne voir que des clous
SergioMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2013, 11h21   #58
NABIL74
Membre éprouvé
 
Homme NABIL
Enseignant
Inscription : août 2008
Messages : 482
Détails du profil
Informations personnelles :
Nom : Homme NABIL
Localisation : Algérie

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : août 2008
Messages : 482
Points : 431
Points : 431
Citation:
Envoyé par SergioMaster Voir le message
Code :
SELECT LOCALITE||' '||DISTRICT AS LOCALITE,NUMERO FROM CLIENTS ORDER BY LOCALITE,DISTRICT,NUMERO
sans changer une ligne de code cela pourrait fonctionner
Bonjour,
Merci pour ta réponse Serge, je l'ai testé hier comme tu me l'as dit, ça ajoute seulement LOCALITE et DISTRICT une après l'autre: Paris, District18.

Sur Paradox le ||' '|| => ||', '||

Et pour la suite de série, même résultat qu'avant, pas de changement.

si c'est possible d'obtenir ça , ça série la fin de notre galère :

Nantes, 2704, Arrondissement13 =1
Bordeaux,2071 , Arrondissement1 =1
Montpellier,2653 , Arrondissement19 =15
Paris,1-15, Arrondissement18 = 16 , 61-65 Arrondissement17 = 5
Cannes,2603 ,Arrondissement12 =1.

Merci
NABIL74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 15h14.


 
 
 
 
Partenaires

Hébergement Web