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

 Delphi Discussion :

Suppression d'une ligne d'un StringGrid


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut Suppression d'une ligne d'un StringGrid
    Bonjour,

    j'utilise ce code (issu de la FAQ) pour supprimer une ligne de Mon StringGrid nommé TN :

    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
    { ========================================================================= }
    procedure TF_Princ.Btn_SupprimeLigneClick(Sender: TObject);
    // Suppression d'une ligne dans le tableau
    Var
       Num  : Integer ;
    begin
       If TN.rowCount > 2 Then
          Begin
             Num := TN.row ;
             TN.Rows[Num].Clear;
             TPublicStringGrid(TN).DeleteRow(Num);
             NbPoint := NbPoint - 1 ;
             If Num > 1 Then TN.Row := Num - 1 Else TN.Row := Num ;
          End
       Else
          Begin
             ShowMessage('Une seule ligne dans le tableau'+ Chr(10)+ Chr(13)+ 'Suppression impossible');
          End ;
    end;
    { ========================================================================= }
    Cela fonctionne bien, mais quand il ne reste que 3 lignes, si je supprime la seconde ou la troisième le curseur se positionne sous la grille dans une cellule qui n'existe ?

    Comment faire pour se positionner sur la seconde ligne après suppression de la troisième par exemple ?

    PS : j'ai aussi un problème si je voulais supprimer la seconde et ne conserver que la première qui est en fixedRow

    Merci pour vos suggestions

    @+

    Charly

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 71
    Points : 102
    Points
    102
    Par défaut
    Salut,
    Essaye comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if TN.RowCount > TN.FixedRows +1 then
        TPublicStringGrid(TN).DeleteRow(TN.Row)
    else
        TN.Rows[TN.Row].Clear;
    @+

  3. #3
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    Merci Nuxtay,

    j'ai fait :

    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
    { ========================================================================= }
    procedure TF_Princ.Btn_SupprimeLigneClick(Sender: TObject);
    // Suppression d'une ligne dans le tableau
    Var
       Num  : Integer ;
    begin
       If TN.rowCount > 2 Then
          Begin
             Num := TN.row ;
    //         TN.Rows[Num].Clear;
    //         TPublicStringGrid(TN).DeleteRow(Num);
             if TN.RowCount > TN.FixedRows +1 then
                 TPublicStringGrid(TN).DeleteRow(TN.Row)
             else
                 TN.Rows[TN.Row].Clear;
             NbPoint := NbPoint - 1 ;
             If Num > 1 Then TN.Row := Num - 1 Else TN.Row := Num ;
          End
       Else
          Begin
             ShowMessage('Une seule ligne dans le tableau'+ Chr(10)+ Chr(13)+ 'Suppression impossible');
          End ;
     
    end;
    { ========================================================================= }
    Mais malheureusement cela ne change rien

    Charly

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut
    Bonjour à toutes et à tous,

    @ Charly910,

    Le composant StringGrid ne permet pas de supprimer une ligne directement avec son numéro. Il faut donc copier chaque ligne située après celle a supprimer sur la ligne qui la précède, puis supprimer la dernière ligne.

    Par exemple, si on veut supprimer la ligne 3, on copie la 4 sur la 3, la 5 sur la 4, ... et on supprime la dernière.

    On peut donc utiliser une procédure telle que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure RemoveLine(AStringGrid: TStringGrid; ALine: Integer);
    var
      i: Integer;
    begin
      for i := ALine to AStringGrid.RowCount - 2 do
        AStringGrid.Rows[i] := AStringGrid.Rows[i + 1];
      AStringGrid.RowCount := AStringGrid.RowCount - 1;
    end;
    On peut alors facilement supprimer la ligne 3 de la StringGrid "MaStringGrid" :

    RemoveLine(MaStringGrid,2);

    @+,

    Cincap

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    Bonjour Cincap,

    mais alors la procédure de la FAQ "Comment supprimer une ligne ou une colonne dans un TStringGrid ?" de Waskol ne fonctionne pas ?

    dommage, j'aurais bien voulu aussi l'utiliser pour détruire une colonne.

    Il doit y avoir quand même un bug dans le composant TStringGrid, car le curseur se positionne dans la zone cliente de la grille, mais sous la dernière ligne, dans une cellule qui n'existe pas mais on peut y taper du texte ?

    Je suis en D7 - cela a peut être été corrigé dans les versions ultérieures de Delphi ?

    Un truc bizarre c'est que si je met un ShowMessage après le DeleteRow, alors cela fonctionne bien, même pour détruire la 3iéme ligne

    A+

    Charly

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut
    Et avec ceci :

    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
     
    Type
    TSGridEfface = class(TStringGrid)
    protected
    procedure DeleteRow(ARow: LongInt); reintroduce;
    end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TSGridEfface.DeleteRow(ARow: LongInt);
    var
    GemRow: Integer;
    begin
    GemRow := Row;
    if RowCount > FixedRows + 1 then
    inherited DeleteRow(ARow)
    else
    Rows[ARow].Clear;
    if GemRow < RowCount then Row := GemRow;
    end;
     
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    TSGridEfface(StringGrid1).DeleteRow(2);
     
    end;
    @+,

    Cincap

  7. #7
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    Bonjour Cincap,

    avec ce code, en utilisant ton TSGridEfface , cela ne fonctionne toujours pas :

    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
    { ========================================================================= }
    procedure TF_Princ.SpeedButton1Click(Sender: TObject);
    // Suppression d'une ligne dans le tableau
    Var
       Num  : Integer ;
    begin
       If TN.rowCount > TN.FixedRows +1 Then
          Begin
             Num := TN.row ;
             TN.Rows[Num].Clear;
             TSGridEfface(TN).DeleteRow(Num);
             If Num > 1 Then TN.Row := Num - 1 Else TN.Row := Num ;
             if (TN.RowCount =  TN.FixedRows +1) Then  TN.Row :=  TN.FixedRows
          End
       Else
          Begin
             ShowMessage('Une seule ligne dans le tableau'+ Chr(10)+ Chr(13)+ 'Suppression impossible');
          End ;
    end;
    { ========================================================================= }
    Quand la grille comportet 3 lignes au total, et que je suis sur la ligne2, si je détruit, cela fonctionne, mais le curseur se retrouve sous la grille ..



    Charly

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 71
    Points : 102
    Points
    102
    Par défaut
    Je disais remplace tout...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TF_Princ.Btn_SupprimeLigneClick(Sender: TObject);
    begin
      if TN.RowCount > TN.FixedRows +1 then
        TPublicStringGrid(TN).DeleteRow(TN.Row)
      else
        TN.Rows[TN.Row].Clear;
    end;
    Quelle est le résultat ?
    @+

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut
    Pourquoi rajoutes tu TN. puisque la classe est déclarée et la procédure le spécifie (TSGridEfface.DeleteRow(ARow: LongInt);
    ) ?

    @+,

    Cincap

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 71
    Points : 102
    Points
    102
    Par défaut
    Jai pas regardé dans la faq,
    mais il ne doit pas y avoir de problème avec ceci...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    type
      TPublicStringGrid = class(TCustomGrid);
     
    procedure TF_Princ.Btn_SupprimeLigneClick(Sender: TObject);
    begin
      if TN.RowCount > TN.FixedRows +1 then
      begin
        TN.Rows[TN.Row].Clear;
        TPublicStringGrid(TN).DeleteRow(TN.Row);
      end
      else
        TN.Rows[TN.Row].Clear;
    end;
    @+

  11. #11
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    @ Cincap : c'était pour transtyper TN qui est déclarer en TSTringGrig comme dans l'exemple de la FAQ de Waskol

    @ Nuxtay : merci - j'essaye ta méthode

    A+

    Charly

  12. #12
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    @ Nuxtay :

    avec ton code, si on se place sur la dernière ligne de la grille et si on clique sur le bouton pour la détruire, la dernière lige est détruite, mais le curseur se retrouve sous la grille - donc même problème

    Je pense que je vais abandonner et recopier les lignes une par une comme le préconise Cincap dans son premier message.

    Charly

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 71
    Points : 102
    Points
    102
    Par défaut
    Je viens de tester le morceau de code que je te propose,
    un stringgrid et un bouton, résultat : je n'ai pas le problème...
    J'ai testé par la même occasion ton code de départ, résultat : pas de problème...
    Y a un truc ailleurs, par exemple dans OnDrawCell si tu l'utilise...
    @+

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 71
    Points : 102
    Points
    102
    Par défaut
    Le code avec ton premier post...
    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
    type 
      TPublicStringGrid = class(TCustomGrid);
     
    procedure TF_Princ.Btn_SupprimeLigneClick(Sender: TObject);
    var
       Num  : Integer ;
    begin
        if TN.RowCount > TN.FixedRows +1 then
        begin
            Num := TN.Row;
            TN.Rows[TN.Row].Clear;
            TPublicStringGrid(TN).DeleteRow(TN.Row);
            if Num > TN.FixedRows +1 then
                TN.Row := Num - 1
            else
                TN.Row := Num ;
        end
        else
            TN.Rows[TN.Row].Clear;
    end;
    @+

  15. #15
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    J'ai fait petit projet juste avec une grille pour voir:

    les 2 méthodes fonctionnent !!

    j'ai repris mon projet, j'ai supprimé la grille TN et je l'ai recréée avec l'éditeur.

    J'ai redonné toutes les propriétés, j'ai réaffecté DrawCell que j'utilise pour cadrer les valeurs, j'ai remis en goediting, ...

    Cela fonctionne .... pourquoi mystère

    voici le code que j'utilise finalement :

    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
    { ========================================================================= }
    procedure TF_Princ.SpeedButton4Click(Sender: TObject);
    // Suppression d'une ligne dans le tableau  TN
    Var
       Num  : Integer ;
    begin
       Num := TN.Row ;
       If (TN.RowCount > TN.fixedRows +1) Then
          Begin
             RemoveLine(TN, Num) ;
          End
       Else
          Begin
             TN.Rows[TN.RowCount-1].Clear ;
          End ;
    end;
    { ========================================================================= }
    procedure TF_Princ.RemoveLine(AStringGrid: TStringGrid; ALine: Integer);
    var
      i: Integer;
    begin
      For i := ALine to AStringGrid.RowCount - 2 do
         AStringGrid.Rows[i] := AStringGrid.Rows[i + 1];
      AStringGrid.RowCount := AStringGrid.RowCount - 1;
    end;
    { ========================================================================= }
    Merci à tous les deux et désolé de vous avoir fait cherché ...

    (je ne saurai jamais ce que j'avais mal fait !)

    @+

    Charly

  16. #16
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 346
    Points : 3 124
    Points
    3 124
    Par défaut
    Bonjour à tous,

    je rouvre mon post l'espace d'un instant, car j'ai trouvé la solution :

    le bug se produit si on met la propriété goAlwaysShowEditor de la grille à True

    Voilà, si cela peut servir à quelqu'un d'autre ...

    @+

    Charly

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/09/2005, 13h20
  2. [Debutant][JTable] Suppression d'une ligne
    Par seiryujay dans le forum Composants
    Réponses: 7
    Dernier message: 03/08/2005, 17h15
  3. [JTable] problème après suppression d'une ligne
    Par fredo3500 dans le forum Composants
    Réponses: 7
    Dernier message: 17/03/2005, 10h01
  4. Réponses: 6
    Dernier message: 04/03/2004, 09h35
  5. Déplacer la sélection d'une ligne dans un stringgrid
    Par jer64 dans le forum Composants VCL
    Réponses: 5
    Dernier message: 14/03/2003, 00h57

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