Publicité
+ Répondre à la discussion
Page 3 sur 3 PremièrePremière 123
Affichage des résultats 41 à 58 sur 58
  1. #41
    Membre Expert Avatar de Dr.Who
    Inscrit en
    septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 35

    Informations forums :
    Inscription : septembre 2009
    Messages : 980
    Points : 1 162
    Points
    1 162

    Par défaut

    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!

  2. #42
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  3. #43
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  4. #44
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    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

  5. #45
    Expert Confirmé
    Avatar de Ph. B.
    Homme Profil pro Philippe
    Inscrit en
    avril 2002
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Nom : Homme Philippe
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 1 327
    Points : 3 631
    Points
    3 631

    Par défaut

    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.

  6. #46
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  7. #47
    Expert Confirmé
    Avatar de Ph. B.
    Homme Profil pro Philippe
    Inscrit en
    avril 2002
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Nom : Homme Philippe
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 1 327
    Points : 3 631
    Points
    3 631

    Par défaut

    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.

  8. #48
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  9. #49
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 337
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 337
    Points : 9 748
    Points
    9 748

    Par défaut

    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

  10. #50
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  11. #51
    Expert Confirmé
    Avatar de Ph. B.
    Homme Profil pro Philippe
    Inscrit en
    avril 2002
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Nom : Homme Philippe
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 1 327
    Points : 3 631
    Points
    3 631

    Par défaut

    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.

  12. #52
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  13. #53
    Expert Confirmé
    Avatar de Ph. B.
    Homme Profil pro Philippe
    Inscrit en
    avril 2002
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Nom : Homme Philippe
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 1 327
    Points : 3 631
    Points
    3 631

    Par défaut

    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
    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.

  14. #54
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  15. #55
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 337
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 337
    Points : 9 748
    Points
    9 748

    Par défaut

    , 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
    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

  16. #56
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

  17. #57
    Rédacteur/Modérateur
    Avatar de SergioMaster
    Homme Profil pro Serge Girard
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    5 337
    Détails du profil
    Informations personnelles :
    Nom : Homme Serge Girard
    Âge : 58
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 5 337
    Points : 9 748
    Points
    9 748

    Par défaut

    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

  18. #58
    Membre éprouvé
    Homme Profil pro NABIL
    Enseignant
    Inscrit en
    août 2008
    Messages
    505
    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 : 505
    Points : 409
    Points
    409

    Par défaut

    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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •