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 :

mauvaise suppression dans un select multiple


Sujet :

Delphi

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut mauvaise suppression dans un select multiple
    Bonjour a tous .Je n'arrive pas a supprimer les sélections dans un DBGrid.
    J'ai ce code pour enregistrer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       // Ouvrir la table au début du traitement
      Datamodule1.Table10.Active := True;
      for  i := 0 to SMDBGrid1.SelectedRows.Count - 1  do
      begin
        SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
        // Nouvelle ligne
        Datamodule1.Table10.Append;
        // On alimente
        Datamodule1.Table10.FieldByName('Idadherent').Value := SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString;
        Datamodule1.Table10.FieldByName('Id_cotis').Value := SMDBGrid1.DataSource.DataSet.FieldByName('Id_cotis').AsString;
        // On valide
        Datamodule1.Table10.Post;
    ok maintenant pour faire le suppression j'ai le code la

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      Datamodule1.Table9.Active := True;
      for  i := 0 to SMDBGrid1.SelectedRows.Count - 1  do
      begin
        SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
     
        Datamodule1.Table9.Delete;
     
      end;
      // Fermer la table à la fin du traitement
      Datamodule1.Table9.Active := False;
    la suppression fonctionne, mais ce code me supprime que le premier enregistrement de la liste ?

    pouvez vous m'aider svp

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    C'est logique. Les signets (bookmark) ne restent valides que tant que l'on insère pas une ligne ou en supprime une dans la table. En modification de données cela fonctionne comme vous avez pu le constater...

    Pour la suppression, il faut parcourir tous les signets, identifier les enregistrements à supprimer et stocker leur identifiants.
    Ensuite on procède à la suppression par un query
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    delete from MaTable where MonId in (1, 4, 42, ...);
    ou un parcours de la table avec un locate...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i:= 1 to NbASupprimer do
    begin
      MaTable.Locate(ArrayId[i]);
      MaTable.Delete;
    end;
    Philippe.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Bonjour,
    C'est logique. Les signets (bookmark) ne restent valides que tant que l'on insère pas une ligne ou en supprime une dans la table. En modification de données cela fonctionne comme vous avez pu le constater...

    Pour la suppression, il faut parcourir tous les signets, identifier les enregistrements à supprimer et stocker leur identifiants.
    Ensuite on procède à la suppression par un query
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    delete from MaTable where MonId in (1, 4, 42, ...);
    ou un parcours de la table avec un locate...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for i:= 1 to NbASupprimer do
    begin
      MaTable.Locate(ArrayId[i]);
      MaTable.Delete;
    end;
    Merci Ph.B mais justement comment je récupére tous les id des membres sélectionnés ?

    comme j'ai fais plus haut exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Memo1.tex := SMDBGrid1.DataSource.DataSet.FieldByName('Id_cotis').AsString;
    je place id de mes sélections dans un memo ??

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par tarmo57 Voir le message
    Merci Ph.B mais justement comment je récupére tous les id des membres sélectionnés ?
    De plusieurs manières posibles. On connait le nombre de signets via SMDBGrid1.SelectedRows.Count.
    Entre autres, on peut créer un tableau d'identifiants array of TypeIdentifiant ou une TStringList. On parcourt la liste des signets pour obtenir la liste des identifiants et ensuite on procède à la suppression de la manière que je l'ai indiqué précedemment...
    Exemple à adapter avec un tableau array of String
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var
      ArrId: array of String;
      i: Integer;
    begin
      SetLength(ArrId, SMDBGrid1.SelectedRows.Count);
      for i := 0 to SMDBGrid1.SelectedRows.Count - 1 do
      begin
        SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
        ArrId[i] := SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString;
      end;
      // On a tous les identifiants, on passe à la suppresion
      // ...
    end;
    Exemple à adapter avec un TStringList
    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
    var
      SLId: TStringList;
      i: Integer;
    begin
      SLId := TStringList.Create;
      try
        for i := 0 to SMDBGrid1.SelectedRows.Count - 1 do
        begin
          SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
          SLId.Add(SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString);
        end;
        // On a tous les identifiants, on passe à la suppresion
        // ...
      finally
        SLId.Free;
      end;
    end;
    Philippe.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut encore merci
    Encore merci a toi Ph.B de me venir en aide j'ai donc mis en place le code,le voici

    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
    procedure Tretir_cotisation.BitBtn4Click(Sender: TObject);
    var
      ArrId: array of String;
      i: Integer;
    begin
    if DBEdit3.Text = '' then begin
    ProInfoDialog1.InfoMessage:='Vous devez selectionner le paiement que vous voulez allouer';
    ProInfoDialog1.Execute ;
    DBLookupComboBox1.Color:=clYellow;
    DBLookupComboBox1.DropDown;;
    end
    else begin
      SetLength(ArrId, SMDBGrid1.SelectedRows.Count);
      for i := 0 to SMDBGrid1.SelectedRows.Count - 1 do
      begin
        SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
        ArrId[i] := SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString;
      end;
     for i:= 1 to SMDBGrid1.SelectedRows.Count do
    begin
      Datamodule1.Table9.Locate(ArrId[i]);
      Datamodule1.Table9.Delete;
    end;
     
      end;
      // Fermer la table à la fin du traitement
      Datamodule1.Table9.Active := False;
     
      retir_cotisation.Close;
    end;
    dans cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Datamodule1.Table9.Locate(ArrId[i]);
    j'ai le message pas assez de paramètre originaux

  6. #6
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par tarmo57 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Datamodule1.Table9.Locate(ArrId[i]);
    j'ai le message pas assez de paramètre originaux
    Vous ne seriez pas un petit peu flemmard ?
    sur l'instruction Locate vous aurait renseigné...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Datamodule1.Table9.Locate('Idadherent', ArrId[i], []);
    //... avec plusieurs colonnes
    Datamodule1.Table9.Locate('Idadherent;Id_cotis', VarArrayOf([ArrId[i], CotisId[i]]), []);
    Pour le 3° paramètres, les crochets correspondent à des options pour ne pas tenir compte de la casse des caractères, chercher sur une clé partielle, etc...
    Philippe.

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Vous ne seriez pas un petit peu flemmard ?
    sur l'instruction Locate vous aurait renseigné...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Datamodule1.Table9.Locate('Idadherent', ArrId[i], []);
    //... avec plusieurs colonnes
    Datamodule1.Table9.Locate('Idadherent;Id_cotis', VarArrayOf([ArrId[i], CotisId[i]]), []);
    Pour le 3° paramètres, les crochets correspondent à des options pour ne pas tenir compte de la casse des caractères, chercher sur une clé partielle, etc...
    Désole Ph.B le gros problème que j'ai je suis sur windows 7 et j'ai plus de F1 les fichier hlp ne sont plus pris en charge

    merci de ton aide

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut Encore merci Ph.B
    Encore merci Ph.B le code fonctionne bien .
    j'ai juste un petit problème si ne je sélectionne pas tous les membres ok pas de problemes
    Si je sélectionne tous les membres pour la suppression j'ai un message d'érreur

    Violation d'accés à l'adresse 00404580 dans le module 'projet.exe Lecture de l'adresse 0000001E

    Que veut dire ce message ???

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 044
    Points : 40 962
    Points
    40 962
    Billets dans le blog
    62
    Par défaut
    Je me demande ? pourquoi faire en deux passes :
    - sauver le bookmark dans un tableau
    - Effacer dans la table 9 selon tableau
    ce qui peut se faire en une passe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for i := 0 to SMDBGrid1.SelectedRows.Count - 1 do
      begin
        SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
      Datamodule1.Table9.Locate('idhaderent',SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString,[]);
      Datamodule1.Table9.Delete;
    end;
    de même , cette ligne
    Code ancien code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SMDBGrid1.DataSource.DataSet.GotoBookmark(pointer(SMDBGrid1.SelectedRows.Items[i]));
    me choque et me semble pouvoir être remplacer par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SMDBGrid1.DataSource.DataSet.Bookmark:=SMDBGrid1.SelectedRows.Items[i];
    Quant au message en lui même , je dirais que un array est a base zéro et que donc, la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for i:= 1 to SMDBGrid1.SelectedRows.Count do
    devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     for i:= 0 to SMDBGrid1.SelectedRows.Count-1 do
    et que cette partie devait planté même en cas de sélection simple (j'ai pas le courage de tester)

    je pourrais ensuite rajouter, que l'ouverture d'une table pour faire un locate pour faire un delete pourrait être avantageusement remplacée par une exécution directe de SQL . (il me semble me souvenir que tu utilises Paradox et donc BDE)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SQL:=Format('DELETE FROM TABLE9 WHERE idadherent=%s',[Quotedstr(SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString)]);
    Datamodule1.database1.Execute(SQL);
    ce qui améliorerait : la vitesse , la consommation de ressources etc.. quoique avec Paradox cela soit moins vrai , il est bon de prendre de bonnes ? habitudes

    Enfin l'excuse du fichier d'aide qui ne s'ouvre pas , hum cela mérite presque une , une petite recherche sur le net donne des solutions pour pouvoir lire les fichiers d'aide au format 'non reconnus'
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  10. #10
    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
    Citation Envoyé par SergioMaster Voir le message
    je pourrais ensuite rajouter, que l'ouverture d'une table pour faire un locate pour faire un delete pourrait être avantageusement remplacée par une exécution directe de SQL . (il me semble me souvenir que tu utilises Paradox et donc BDE)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SQL:=Format('DELETE FROM TABLE9 WHERE idadherent=%s',[Quotedstr(SMDBGrid1.DataSource.DataSet.FieldByName('Idadherent').AsString)]);
    Datamodule1.database1.Execute(SQL);
    ce qui améliorerait : la vitesse , la consommation de ressources etc.. quoique avec Paradox cela soit moins vrai , il est bon de prendre de bonnes ? habitudes
    Quand ce genre de situation arrive souvent, je préfère utiliser une liste d'entiers (ex: TGpIntegerList de "gabr") pour y mettre toutes les lignes sélectionnées, et faire ce genre de requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    qry.SQL.Text := Format('DELETE FROM TABLE9 WHERE idadherent IN (%s);', [il.AsDelimitedText(',')]);
    qry.ExecSQL;
    ("il" étant de type TGpIntegerList)

  11. #11
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Je me demande ? pourquoi faire en deux passes :
    - sauver le bookmark dans un tableau
    - Effacer dans la table 9 selon tableau
    ce qui peut se faire en une passe
    C'est en effet vrai, j'étais persuadé que les signets étaient désynchronisés lors de l'insertion ou la suppression d'une ligne !
    "Mea culpa, mea maxima culpa"
    Merci à Serge pour la rectification.
    Philippe.

  12. #12
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    483
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 483
    Points : 128
    Points
    128
    Par défaut merci a tous
    Grand merci a tous pour votre aide SergioMaster j'ai fais les modifications c'est parfait bon dimanche a tous.

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

Discussions similaires

  1. [AC-2003] Suppression d'un selection multiple dans une zone de liste
    Par yieiyiei dans le forum VBA Access
    Réponses: 15
    Dernier message: 25/02/2015, 15h34
  2. Réponses: 3
    Dernier message: 08/06/2010, 14h42
  3. Selection multiple dans un select multiple
    Par NizarK dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 27/02/2009, 10h58
  4. tous selectionné dans un select multiple
    Par yngwie44 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 28/08/2007, 15h54

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