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

Pascal Discussion :

Suppression d'un enregistrement


Sujet :

Pascal

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Suppression d'un enregistrement
    bonsoir à tous j'ai un probléme et je voudrais que vous m'aidiez. j'aimerai savoir comment supprime t-on un enregistrement. si par exemple l'enregistrement est un tableau comment supprime t-on la case i du tableau.merci d'avantage et aidez moi

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Hai,

    Pas le choix : il faut décaler tout ce qui est plus loin en le ramenant d'une case, et ne pas oublier que désormais le tableau contient 1 case de moins valide, même si toutes restent de fait accessibles.
    Si les cons volaient, il ferait nuit à midi.

  3. #3
    Membre habitué

    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    192
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 192
    Points : 176
    Points
    176
    Par défaut
    Bonjour,

    peut-être vais-je dire une bêtise...

    plutôt que de le supprimer physiquement par décalage, peut-être simplement mettre un flag (un indicateur comme quoi il ne faut plus l'utiliser) ?

    inconvénient il faut plus de place pour stocker les indicateurs, tests supplémentaires à mettre dans le code, temps cpu..


    avantage, la suppression n'est pas définitive, il suffit de rebasculer le flag...
    Un bon exemple vaut mieux qu'une longue explication confuse...

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Fai,
    Citation Envoyé par JoseF Voir le message
    Bonjour,

    peut-être vais-je dire une bêtise...

    plutôt que de le supprimer physiquement par décalage, peut-être simplement mettre un flag (un indicateur comme quoi il ne faut plus l'utiliser) ?

    inconvénient il faut plus de place pour stocker les indicateurs, tests supplémentaires à mettre dans le code, temps cpu..


    avantage, la suppression n'est pas définitive, il suffit de rebasculer le flag...
    Oui, c'est une bonne idée. On fait souvent comme ça quand on gère des fichiers correspondant à une base de données, l'emplacement inutilisé étant alors repris pour les prochaines données créées.

    C'était valable dans le temps, quand les bases de données disponibles étaient chères, et souvent assez lentes. Mais désormais, il existe de nombreuses possibilités gratuites dans ce domaine, généralement performantes, ce qui diminue considérablement l'intérêt d'une gestion de A à Z faite "à la main".

    Mais la question posée est "Suppression d'un enregistrement".
    Si les cons volaient, il ferait nuit à midi.

  5. #5
    Futur Membre du Club
    Inscrit en
    Décembre 2007
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 11
    Points : 8
    Points
    8
    Par défaut Suppression d'un enregistrement
    Pour le dernier élément du tableau, tu peux utiliser une variable NombreElement qui contient
    le nombre d'éléments valides du tableau. Donc à chaque suppression tu décremente cette variable de 1. Comme ca tu n'affichera qu'une seule fois le dernier élément du tableau en cas de suppression. Et si tu veux faire un ajout dans le tableau tu fais NombreElement:=NombreElement + NombreAjoute.
    RQ: NombreElement<=NombreElementMaxduTableau

  6. #6
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    Alors dans le cas d'un simple enregistrement, comment on fait. Et puis j'ai un pote de la fac qui m'a proposé d'essayer un technique mais j'y arrive pas; il dit qu'on peut creer un fichier temporaire pour copier tous les enregistrements sauf celui a suprimer en suite tout ramener dans l'ancien. Quelqu'un aurait une idée?

  7. #7
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Gio,
    Citation Envoyé par adivinenza Voir le message
    Alors dans le cas d'un simple enregistrement, comment on fait. Et puis j'ai un pote de la fac qui m'a proposé d'essayer un technique mais j'y arrive pas; il dit qu'on peut creer un fichier temporaire pour copier tous les enregistrements sauf celui a suprimer en suite tout ramener dans l'ancien. Quelqu'un aurait une idée?
    La bonne vieille technique qui nécessite de savoir écrire, et de disposer d'une feuille de papier et d'un crayon (ou d'une plume d'oie, pour les vrais nostalgiques ) :

    Image : on a N valeurs, on veut en supprimer une, sans laisser de trou à sa place.
    Il n'y a pas des milliers de solutions.

    Tu décris en clair comment tu ferais manuellement, et tu as ton(tes) algorithme(s).
    Si les cons volaient, il ferait nuit à midi.

  8. #8
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    bon concrètement, mon problème est le suivant : j'ai utiliser les seek, pour faire le décalage. donc je conserve l'enregistrement suivant dans un temp ensuite je recule et je déverse, c'est bien ça et ce jusqu'à la fin, mais pour faire cette boucle j'ai fait un "while not eof(fproduit) do ", mais problème : ça plante le programme. aucune réponse tout est bloqué

  9. #9
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Hai,

    Montre ton code, sinon il est impossible de t'aider par rapport à ce que tu as fait.
    Si les cons volaient, il ferait nuit à midi.

  10. #10
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    Voici le code en question
    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
    procedure manager_dell;
    begin
     writeln('donner le code du produit a supprimer');
     readln(code);
     reset(fproduit);
     read(fproduit,prod);
     while not eof(fproduit) do
       begin
       read(fproduit,prod);
        if prod.code = code then
         while not eof(fproduit) do
          begin
           code := prod.code;
           dsgn := prod.designation;
           pu := prod.pu;
           stock := prod.stock;
           seuil := prod.seuil;
           seek(fproduit,filepos(fproduit) - 1*sizeof(produit));
           prod.code := code;
           prod.dsgn := dsgn;
           prod.pu := pu;
           prod.stock := stock;
           prod.seuil := seuil;
          {prod := tempo;}
           write(fproduit,prod);
           seek(fproduit,filepos(fproduit) + 2*sizeof(produit));
          { truncate(fproduit);}
           break;
          end;
       end;
    end;
    Mais en plus je rencontre d'autre problèmes, "invalid file handle" et dans la faq on ne me dit pas comment remédier a ce problème.
    Je vous donne tout mon code en pièce jointe, si quelqu'un peut m'expliquer ces problèmes.
    Fichiers attachés Fichiers attachés

  11. #11
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Hai,

    Je n'ai fait que jeter un coup d'oeil, mais déjà, je vois :

    - Usage intensif de variables globales : à proscrire.
    (On peut pratiquement toujours s'en passer, et ça rend le code très dépendant d'une part, et d'autre par difficile à maintenir/lire)

    - Pour les Seek dans les fichiers, par exemple, dans la procédure recherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          Seek(fproduit, FilePos(fproduit) - (1 * SizeOf(fproduit)));
    le fonction FilePos tient compte de la taille de l'enregistrement, tes calculs sont donc faux. Dans le cas présent, il suffit donc de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          Seek(fproduit, FilePos(fproduit) - 1);
    Il est bien possible que ton problème vienne de là.

    - Pourquoi créer des procédures de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure verification(login, password : string; var acces : Boolean);
    alors qu'une saine programmation voit ici l'occasion d'utiliser une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function verification(login, password : string) : Boolean ;
    - Le code principal doit être découpé en fonctions/procédures (au moins une par menu géré).
    D'une manière générale, il vaut mieux écrire une fonction ou une procédure pour chaque tâche du programme, le programme principal se contentant de les organiser (ceci reste vrai à tous les niveaux : les différentes tâches d'une procédures sont elles-mêmes des procédures, etc. [procédure est ici pris au sens général de procédure ou fonction]).

    - Dans la procédure manager_dell, dont tu m'as parlé en MP, il y a une lecture de trop avant d'entrer dans la boucle While :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure manager_dell;
    begin
      Writeln('donner le code du produit a supprimer');
      Readln(code);
      Reset(fproduit);
      Read(fproduit, prod); { =========  ici }
      while not Eof(fproduit) do
      begin
        Read(fproduit, prod);
        if prod.code = code then
    A part ça, je n'ai pas lu en détail le code, corrige-le, et on reverra ça.
    Si les cons volaient, il ferait nuit à midi.

  12. #12
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    ok, je vais tester et dans l'apres midi je te fais signe, pour les nombreuses procedures utilisées, c'est le prof qui a imposer les proc au lieu des fonction.

  13. #13
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Hai,
    Citation Envoyé par adivinenza Voir le message
    ok, je vais tester et dans l'apres midi je te fais signe, pour les nombreuses procedures utilisées, c'est le prof qui a imposer les proc au lieu des fonction.
    Change de prof !!
    Si les cons volaient, il ferait nuit à midi.

  14. #14
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    ( comment faire pour le changer, le système me l'impose )

    j'ai rectifié la partie du code manager_dell, bon ca plante plus mais ça supprime pas non plus, alors surement qu'il y un problème au niveau du code lui meme mais moi je vois pas du tout.

    A propos de la technique avec un autre fichier, j'ai "finalement" pris un crayon et du papier et j'ai fait un petit prog, résultat : j'ai créé un virus ; bah ouais ça génère un fichier de 100 MO qui se duplique

    euh, quand tu dis trop de variables globales, tu parle de quelles variables au juste?

  15. #15
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Gai,
    Citation Envoyé par adivinenza Voir le message
    ( comment faire pour le changer, le système me l'impose )
    C'était de l'humour trollique.

    Citation Envoyé par adivinenza Voir le message
    j'ai rectifié la partie du code manager_dell, bon ca plante plus mais ça supprime pas non plus, alors surement qu'il y un problème au niveau du code lui meme mais moi je vois pas du tout.
    Mets-nous ton nouveau code.

    Citation Envoyé par adivinenza Voir le message
    A propos de la technique avec un autre fichier, j'ai "finalement" pris un crayon et du papier et j'ai fait un petit prog, résultat : j'ai créé un virus ; bah ouais ça génère un fichier de 100 MO qui se duplique
    Pas un virus, un bug

    Citation Envoyé par adivinenza Voir le message
    euh, quand tu dis trop de variables globales, tu parle de quelles variables au juste?
    Toutes les variables déclarées au niveau du programme principal (la section Var du programme) qui sont utilisées directement dans les procédures.

    Une procédure/fonction devrait recevoir en paramètre tous les éléments dont elle a besoin qui sont déclarés ailleurs, et n'utiliser que des variables locales pour ce qui lui est nécessaire localement.

    Exemple :

    Pas bon
    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
    program jai;
     
    Var
      i : Integer;
     
    Procedure carre;
    Begin
      i := i * i;
    End;
     
    Begin { programme principal }
      i := 1;
      Writeln(i);
      carre;
      Writeln(i);
      ReadLn;
    End.
    Bon
    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
    program jai;
     
    function carre(i : Integer) : Integer;
    Begin
      carre := i * i;
    End;
     
    Var
      i : Integer;
     
    Begin { programme principal }
      i := 1;
      Writeln(i);
      i := carre(i);
      Writeln(i);
      ReadLn;
    End.
    J'ai ici volontairement utilisé le même nom i pour la variable du programme et le nom du paramètre passé à la fonction carre : le nom du paramètre, qui est local à la fonction, prend le pas sur la variable déclarée à un niveau supérieur.

    Et dans le Bon exemple, j'ai déplacé la déclaration des variables du programme juste avant le Begin du programme principal, ce qui fait que toutes les procédures/fonctions déclarées avant ne connaissent pas ces variables, et ne peuvent donc pas les utiliser "par inadvertance".
    Si les cons volaient, il ferait nuit à midi.

  16. #16
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    bon je vais utiliser ta technique ca m'a l'air super "puissant". Mais bon concernat la suppression a proprement dite, tu me conseille quoi?

  17. #17
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Fio,

    Montre le nouveau code de ta procédure.
    Si les cons volaient, il ferait nuit à midi.

  18. #18
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    bon voici le code, il marche maintenant mais il y a un probleme, quand je supprime le premier enregistrement il dupilque ce dernier a la deuxieme place et je sais pas ce qui cloche dans ce code
    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
    procedure manager_dell;
    var code,stock,seuil :integer;
        dsgn : string;
        pu : real;
    begin
     writeln('donner le code du produit a supprimer');
     readln(code);
     reset(fproduit);
     while not eof(fproduit) do
       begin
       read(fproduit,prod);
        if prod.code = code then
         begin
         if eof(fproduit) then
           begin
            seek(fproduit,filepos(fproduit) - 1);
            truncate(fproduit);
           end
         else
         repeat
          begin
           writeln(filepos(fproduit)); writeln(prod.code);
           code := prod.code;
           dsgn := prod.designation;
           pu := prod.pu;
           stock := prod.stock;
           {seuil := prod.seuil;}
     
           write(fproduit,prod); {<=== c'est la, j'avais pas mis cette ecriture}
     
           seek(fproduit,filepos(fproduit) - 1 ); writeln(prod.code);
           writeln(filepos(fproduit));
           prod.code := code;          writeln(prod.code);
           prod.designation := dsgn;
           prod.pu := pu;
           prod.stock := stock;
           {prod.seuil := seuil;}
          {prod := tempo;}
           write(fproduit,prod);
           seek(fproduit,filepos(fproduit) + 2);
           end;
          until eof(fproduit);
          seek(fproduit,filepos(fproduit) - 1);
          truncate(fproduit);
         writeln('produit supprim‚'); readkey;
     
        end;
       end;
    end;

  19. #19
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Heo,

    Moi, je sais ce qui cloche : tu te compliques beaucoup trop la vie.

    Il faut faire:

    - Trouver la position de l'enregistrement à supprimer

    - S'il existe

    - faire une boucle de cette position +1 à la fin du fichier pour décaler les enregistrements vers l'avant (une bonne vieille boucle For convient très bien)

    - supprimer le dernier enregistrement.

    Tes Seek avec des valeurs uniquement par rapport à FilePos, sans être fondamentalement faux, compliquent beaucoup ton code.

    Petit exemple vite fait sur le gaz (et donc plutôt sommaire), n'utilisant pas de variables globales

    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    program test_03;
     
      {$N+}
      {$X+}
     
    uses
      crt, Dos, strings;
     
    type
     
      str5 = string[5];
      rints = record
        n : Integer;
        s : str5;
      end;
      fints = file of rints;
     
    procedure remplir (var f : fints);
    var
      i : integer;
      t : rints;
    begin
      rewrite(f);
      FillChar(t,sizeof(rints),0); {pour que le contenu soit propre}
      for i := 0 to 6 do
      begin
        t.n := i;
        Str(i,t.s);
        write(f,t);
      end;
    end;
     
    function trouve (var f : fints; n : integer) : integer;
    { renvoie -1 si n'existe pas, sinon la position dans le fichier }
    var
      res : integer;
      t : rints;
    begin
      res := -1;
      reset(f);
      while not(eof(f)) and (res = -1) do
      begin
        read(f,t);
        if (t.n = n) then res := FilePos(f)-1; {-1 … cause du Read !! }
      end;
      trouve := res;
    end;
     
    procedure supprime (var f : fints; n : integer);
    var
      t : rints;
      i,place : integer;
    begin
      place := trouve(f,n);
      if (place >= 0) then
      begin
        for i := place + 1 to FileSize(f) - 1 do
        begin
          seek(f,i);
          read(f,t);
          seek(f,i-1);
          write(f,t);
        end;
        seek(f,FileSize(f) -1);
        Truncate(f);
      end;
    end;
     
    { programme principal }
    var
      f : fints;
     
    begin
      assign(f,'datas.dat');
      remplir(f);
      Reset(f);
     
      writeln(filesize(f));
      supprime(f,1);
      supprime(f,5);
     
      close(f);
     
      ReadLn;
    end.
    Il faudrait faire tout ça plus proprement, entre autres :
    - des constantes plutôt que des valeurs "magiques"
    - contrôler systématiquement tous les accès fichiers
    ...
    Si les cons volaient, il ferait nuit à midi.

  20. #20
    Membre habitué Avatar de adivinenza
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Points : 141
    Points
    141
    Par défaut
    Bon je vais essayer tes conseils, mais il me semble que pour la suppression c'est ce que j'ai fait, mais je comprend pas pourquoi pour le premier ca marche pas.
    Mais est ce que le fait d'utiliser une boucle peut m'éviter d'utiliser des variables temporaires?

Discussions similaires

  1. Suppression d'un enregistrement
    Par charliejo dans le forum Bases de données
    Réponses: 7
    Dernier message: 16/03/2006, 11h13
  2. [VB][rdo] Strategie de suppression massive d'enregistrements
    Par Bicky dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 12/10/2005, 14h12
  3. suppression automatique des enregistrements
    Par abdou.sahraoui dans le forum Langage SQL
    Réponses: 4
    Dernier message: 02/08/2005, 13h45
  4. [VB.NET]Suppression d'un enregistrement dans un DataGrid
    Par San Soussy dans le forum ASP.NET
    Réponses: 4
    Dernier message: 16/06/2005, 10h30
  5. Suppression d'un enregistrement
    Par denisfavre dans le forum IHM
    Réponses: 3
    Dernier message: 04/10/2004, 11h03

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