IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Aide sur un p'tit algorythme


Sujet :

Langage Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut Aide sur un p'tit algorythme
    Bonjour,

    J'aurais besoin d'un coup de main sur un algorythme.

    soit 3 requetes écrite différement :
    1) Select CodeFacture, CodeArticle, Sum (Quantite) As SommeDeQte From [Ligne CI] Group by CodeFacture, CodeArticle

    2) Select CodeFacture, Sum (Quantite) As SommeDeQte, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticle

    3) Select Sum (Quantite) As SommeDeQte, CodeFacture, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticle

    comment arriver à ressortir le text en GRAS sachant que je connais au départ que SommedeQte dans un variable


    Voilà où j'en suis dans le code qui ne fonctionne pas dans le cas n°3, mais dans tous les autres cas :

    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
    function RetourneLeChamp(Requete, Champ :String): String;
    Var
      i: Integer;
      ParentheseFermer: Boolean;
      Car: Char;
      PosInitial: Integer;
      PositionDebut, PositionFin: Integer;
    Begin
    // Initilisation
      ParentheseFermer := False;
    // Position dans le Richedit du premier caractére du nom de la colonne
      PosInitial := Pos(Champ,Requete);
      while PosInitial > 0 do // On va en marche arrière
      Begin
        if Requete[PosInitial] = ')' then  // Si on tombe sur un parenthèse fermer
        Begin
          Parenthesefermer := True;
          PositionFin := PosInitial + 1; // On retiens la position de cette parenthèse
        end
        else
        Begin
        // Si on tombe sur une virgule cela signifie que le text du champ est fini
          if (Requete[PosInitial] = ',') And (ParentheseFermer) then
          Begin
            PositionDebut := PosInitial + 1; //  On récupere la position de départ
            PosInitial := 1; // On sort de la boucle While
          end;
        end;
        PosInitial := PosInitial - 1;
      end;
      if ParentheseFermer then
        Result := Copy(Requete,Positiondebut, PositionFin-PositionDebut)   // On récupère l'info
      else
        Result := '';
    end;
    Comment gérer le cas trois ?

    Merci de votre aide.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Tu pourrais éliminer le Select pour commencer, puis boucler jusqu'à ce que tu trouves la virgule où jusqu'à ce que tu arrives en début de chaîne ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var
      DataBuf: String;
      iStart, iStop: Integer;
    begin
      DataBuf := Requete;
      // Enlève le superflu avant et après la zone intéressante
      iStart := Pos('Select ', DataBuf);
      iStop := Pos(Champ, DataBuf);
      DataBuf := Copy(DataBuf, iStart, iStop - iStart);
     
      // ... ton code...

  3. #3
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    voila

    au passage cela fonctionne aussi si ce n'est pas une somme

    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    procedure TForm1.Extract(Alias, SQL: string);
    var
      i : Integer;
     
      procedure Spaces;
      begin
        while (i>0) and (SQL[i]=' ') do
          Dec(i);
      end;
     
      function GoBack(const Match: string): Boolean;
      var
        x : Integer;
      begin
        Result := False;
        Spaces;
        for x := Length(Match) downto 1 do
          if Upcase(SQL[i]) <> UpCase(Match[x]) then
            Exit
          else
            Dec(i);
        Result := True;
      end;
     
    var
      e : Integer;
    begin
      Memo1.Lines.Add(Alias);
      Memo1.Lines.Add(SQL);
      i := Pos(Alias, SQL) - 1;
      if not GoBack(' AS') then Exit;
      Spaces;
      if i<0 then
        Exit;
      if SQL[i]=')' then
      begin
        e := i;
        while (i>0) and (SQL[i]<>'(') do
          Dec(i);
        Dec(i);
        Spaces;
      end
      else
      begin
        Spaces;
        e := i;
      end;
      while (i>0) and (SQL[i]<>' ') do
        Dec(i);
      if i<0 then
        Exit;
      Memo1.Lines.Add(Copy(SQL, i+1, e-i));
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
     Extract(
      'SommeDeQte',
      'Select CodeFacture, CodeArticle, Sum (Quantite) As SommeDeQte From [Ligne CI] Group by CodeFacture, CodeArticle'
     );
     Extract(
      'SommeDeQte',
      'Select CodeFacture, Sum (Quantite) As SommeDeQte, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticle'
     );
     Extract(
      'SommeDeQte',
      'Select Sum (Quantite) As SommeDeQte, CodeFacture, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticleend;'
     );
     Extract(
      'SommeDeQte',
      'Select Quantite As SommeDeQte, CodeFacture, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticleend;'
     );
    end;

  4. #4
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    [EDIT]
    annule est remplace mon ancien code j'ai trouvé un bug il existe aussi dans celui de paul
    il suffit qu'un non de champs soit semblable
    imagine que tu est un alias qui se nomme SOLDE et un deuxième qui se nomme SOLDECUM si tu fait une recherche sur SOLDE il s'arrête au premier qui trouve

    je fait donc un test supplémentaire pour vérifier que se soit bien le bon nom que l'on cherche par contre si un nom du champs correspond a un alias
    risque de confusion

    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
     
    {$ifdef delphi6}
    function PosEx(const SubString: string; const s: string; const StartIndex:integer) : integer;
    begin
      Result := Pos(SubString, Copy(s, StartIndex, Length(s) - StartIndex));
      if Result > 0 then
        Result := Result + StartIndex
    end;
    {$endif delphi6}
     
    Function FoundField(SqlTxt,FieldTxt : String) : String;
    var
     Found         : Boolean;
     iStart, iStop : Integer;
    begin
      Result := SqlTxt;
      // Enlève le superflu avant et après la zone intéressante
      iStart := Pos('Select ', Result)+Length('Select ');
      iStop := Pos(FieldTxt, Result)+length(FieldTxt);
      Found := False;
      while not(Found) do
      begin
       if iStop = Length(Result) Then
         Found := true
       else
        if (result[iStop]= ' ') or (result[iStop]= ',')  Then
           Found := true
        else
          iStop := Posex(FieldTxt, Result,iStop)+length(FieldTxt)-1;
      end;
      Result := Copy(Result, iStart, iStop - iStart);
      Found := False;
      iStart := Length(Result);
      While ((iStart >0) and Not(Found)) do
      begin
        Dec(iStart);
        if Result[iStart] = ',' Then
          Found := true;
      end;
      result :=trim(Copy(Result, iStart+1, Length(Result) - (iStart)));
      result :=copy(Result,1,Pos('AS ',uppercase(Result))-1); 
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    const
      TabTest : array[0..3] of Record
                          SqlText   : String;
                          FieldText : String;
                         end = (
                         (SqlText:'Select CodeFacture as SommeDeQte2, CodeArticle, Sum (Quantite) As SommeDeQte From [Ligne CI] Group by CodeFacture, CodeArticle';FieldText:'SommeDeQte'),
                         (SqlText:'Select CodeFacture, Sum (Quantite) As SommeDeQte, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticle';FieldText:'SommeDeQte'),
                         (SqlText:'Select Sum (Quantite) As SommeDeQte, CodeFacture, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticle';FieldText:'SommeDeQte'),
                         (SqlText:'Select Quantite As SommeDeQte, CodeFacture, CodeArticle From [Ligne CI] Group by CodeFacture, CodeArticleend'   ;FieldText:'SommeDeQte')
                         );
     
    var
     i : integer;
     
    begin
     RichEdit1.Lines.Clear;
     for i:=low(TabTest) to high(TabTest) do
        RichEdit1.Lines.Add(FoundField(TabTest[i].SqlText,TabTest[i].FieldText));
    end;
    @+ Phil

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonjour et merci de votre aide.

    La dernière proposition se rapproche de la difficulté.

    Evidement je n'avais pas précisé un point, les exemples, les 3 cas que j'ai sité plus haut correspondent à la saisie de l'utilisateur, il pourrait trés bien saisir se genre de requete :

    SELECT DISTINCT Code, Nom, MAx(ResteDU) As MaxResteDu FROM Client Group By Code, Nom

    en fait il pourrais taper n'importe quelle requete !!

    Moi, je connais juste ce qui se trouve a droite de AS ici MaxResteDu et je doit récupérer exemple ici Max(Restedu)

    PS : il pourrais aussi saisire une requete totalement classique
    Select * FROM Client
    Dans ce cas je ne fait rien.

    PS : de toute façon on gere uniquement si on à un 'Group By '


    Pour Anapurna, à la question
    "*.............. par contre si un nom du champs correspond a un alias risque de confusion"
    C'est impossible, il y aurait un erreur ACCESS tout à fait normal, lors de l'ouverture de la requete que je gere.


    Merci.

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    bon bin ma derniere fonction fonctionne parfaitement dans ce cas

    mais tu peut tres bien ecrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT Code, Nom, MAx(ResteDU) As ResteDU FROM Client Group By Code, Nom
    et la ca ne marche plus

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par anapurna Voir le message
    il suffit qu'un non de champs soit semblable
    imagine que tu est un alias qui se nomme SOLDE et un deuxième qui se nomme SOLDECUM si tu fait une recherche sur SOLDE il s'arrête au premier qui trouve .
    pas faux...mais dans ce cas il suffit d'ajouter des espaces autour du nom

  8. #8
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bonjour à tous,

    Aux vues du nombres de possiblité de tombé sur des cas tordu
    SELECT ALL
    SELECT *
    SELECT DISTINCT

    et j'en passe.

    Je préfère abandonner l'idée, et de conserver la dernière proposition de anapurna.


    Merci encore à tous ceux qui s'implique pour l'aide des programmeurs.


  9. #9
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    tiens une methode encore plus efficace "SearchField"

    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
     
    Procedure Split(Source, Deli: string; StringList: TStrings);
    var
      EndOfCurrentString: byte;
    begin
      repeat
        EndOfCurrentString := Pos(Deli, Source);
        if EndOfCurrentString = 0 then
          StringList.add(Source)
        else
          StringList.add(Copy(Source, 1, EndOfCurrentString - 1));
        Source := Copy(Source, EndOfCurrentString + length(Deli), length(Source) - EndOfCurrentString);
      until EndOfCurrentString = 0;
    end;
     
    Function SearchField(SqlTxt,FieldTxt : String) : String;
    var
     iStart, iStop   : Integer;
     ipos,ipos2  : Integer;
     Found : Boolean;
     StrLst,StrLst2 :  TStringList;
    begin
      iStart := Pos('SELECT ', Uppercase(SqlTxt))+Length('Select ');
      if  Pos('DISTINCT ', Uppercase(SqlTxt)) > 0 Then
        iStart := Pos('DISTINCT ', Uppercase(SqlTxt))+Length('DISTINCT ');
      iStop := Pos('FROM '   , Uppercase(SqlTxt));
      Result := Copy(SqlTxt, iStart, iStop - iStart);
      StrLst :=  TStringList.Create;
      Split(Result,',',StrLst);
      Result   := 'Field non trouvé';
      for ipos:=0 To StrLst.Count-1 do
      begin
        StrLst2 := TStringList.Create;
        Split(trim(StrLst[ipos]),' ',StrLst2);
        if FieldTxt = Trim(StrLst2[StrLst2.Count-1]) then
        begin
          ipos2 :=0;
          Result   := '';
          Found := False;
          While ((ipos2<= StrLst2.Count-1) And (Not (Found))) Do
          begin
           if Uppercase(StrLst2[ipos2]) = 'AS' Then
             Found := True
           else
             Result :=Result+' '+StrLst2[ipos2];
            Inc(ipos2);
          end;
        end;
        StrLst2.Free;
      end;
      Result := trim(Result);
      StrLst.Free;
    end;
    @+ Phil

Discussions similaires

  1. [CR] besoin d'aide sur les formules
    Par GuillaumeDSA dans le forum Formules
    Réponses: 4
    Dernier message: 10/07/2003, 12h19
  2. Réponses: 2
    Dernier message: 27/02/2003, 01h33
  3. [Kylix] Aide sur BitBlt
    Par mic006 dans le forum EDI
    Réponses: 1
    Dernier message: 10/12/2002, 22h54
  4. Aide sur une fenetre
    Par Ray-j dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 29/11/2002, 08h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo