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 :

Comment stocker la valeur d'un ensemble Set Of ?


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut Comment stocker la valeur d'un ensemble Set Of ?
    bonjour,

    en rapport avec d'utilisateursmon post sur la gestion de droits d'utilisateurs

    une question reste en suspend, dans le cas ou j'utilise un ensemble pour stoquer les droits (voir proposition de higgins): comment recuperer la valeur de l'ensemble pour la stoquée dans une base de donnée.

    par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
     droits = (rien,ecrire,lire,modifier);
     
    ...
    var
     mesdroits : set of droits;
    begin
     mesdroits = [ecrire,lire];
    ...
    end;
    j'ai bien une partie de moi qui me dit, la valeur d'un ensemble c un peu aberant, mais comme j'en suis pas sur je demande confirmation.

    sinon faut il que je cree du code pour transcrire cet ensemble en valeurs/masque binaire ?

    le but etant tjrs de stoquer les droits ds une table.

    bonus: ça existe pas un equivalent de for each ... do en delphi ?

    merci d'avance
    Elrick

  2. #2
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    il n'existe pas un moyen de stocker directement un ensemble dans une bdd. Il faut tester l'appartenance à l'ensemble et stocker l'ordre de l'element.

    Le foreach si chèrs au Basic n'existe malheureusement pas en Delphi. Il viens tout juste d'être rajouté à D2005. Et dire qu'on l'avaient en VB depuis la version 4.
    http://www.pocketmt.com GLCD Font Creator home site.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    mouhais c'est ce qu'il me semblait pour les 2 questions

    bon bah me reste plus qu'a faire une belle petite classe qui me transforme un ensemble en mot binaire et inversement

    puis un gros case bien degueu pour remplacer le foreach ! :p

    merci octal

  4. #4
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    de rien ...
    n'oublies pas le tag [RESOLU] en cliquant en bas sur le bouton RESOLU
    http://www.pocketmt.com GLCD Font Creator home site.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    j'mettrais le tag resolu quand j'aurais finit d'implementer tt ça et que j'pourrais fournir une reponse a ma propre question sous forme d'un mini tuto :p
    comme ça tt le monde en profitera

    en attendant si d'autres personnes ont des idées
    vous genez pas !

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Points : 711
    Points
    711
    Par défaut
    Bonjour,

    Au lieu de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    type
     droits = (rien,ecrire,lire,modifier);
     
    ...
    var
     mesdroits : set of droits;
    Tu crées également un type pour l'ensemble
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
     droits = (rien,ecrire,lire,modifier);
     setofdroits : set of droits;
    Les ensembles n'étant que des champs de bits (positionné à 1 si la valeur correspondante existe dans la variable),
    l'esemble setofdroits a une taille de 1 octet (aisément vérifié avec sizeof).

    d'après la définition de droits, on a les valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      rien := 0;
      ecrire := 1;
      lire := 2;
      modifier := 3;
    et d'après celle de setofdroits, on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      rien      dans bit 0
      ecrire               1
      lire                   2
      modifier            3
    d'où tu obtiens pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var
      mesdroits : setofdroits;
      ...
      mesdroits := [ecrire,lire];
    Les bits 1 et 2 positionnés soit en entier : 6

    Donc un moyen de s'en sortir est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var
      p : pointer;
      v : byte;   { pour sizeof(setofdroits) = 1 }
    .....
     
      p := @mesdroits;
      v := byte(p^);  { et on peut sauver v comme un byte ordinaire }
      ...
     
      { et pour récupérer la valeur de mesdroits, après avoir récupéré v comme un byte }
      p := @v;
      mesdroits := setofdroits(p^);
    Compilation sans erreur ne signifie pas programme sans erreur.
    L'indentation n'a pas été imaginée pour faire beau, mais pour faciliter la lecture des programmes.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    hmmm effectivement c'est une piste a etudier

    j'pensais faire comme ça au debut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    var
    i : droits
    droitsbinaire : cardinal;
    begin
    ...
    for i := rien to modifier do
    begin
    if i in mesdroitsutilisateurs then
    droitsbinaire := droitsbinaire + (1 shl mod(i) );
    end;
    ...
    end;
    mais effectivement ta methode est plus directe
    j'v etudier ça demain au taf, merci

  8. #8
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    bonjour thewho,
    en poussant plus loin ton raisonnement, on "pourrais" pratiquement "sérialisé" n'importe quel type de donnée delphi. Le pb avec la solution que tu propose c'est qu'elle est directement liée à la représentation interne que donne ACTUELLEMENT delphi pour le type "set of". Or cette représentation pourra être changée par Borland à tout moment et ton soft tombera à l'eau. L'idéal (comme s'il y en avait ) serait d'utiliser une réprésentation complètement indépendante de l'implémentation du compilo.
    http://www.pocketmt.com GLCD Font Creator home site.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    un peu ds le style de ma 'solution' non ?? :p

  10. #10
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    Citation Envoyé par sfxElrick
    un peu ds le style de ma 'solution' non ?? :p
    non nje parle pas de ta sol. La tienne est "bonne"
    c'est de la sol de thewho que je paralais. le fait de considérer qu'un SET OF sera tjr codé sur un byte et que un byte sera tjr de 8 bit (ce qui donne les 255 val possible dans un ensemble) est un pari très risqué. surtout si ton code devait être repris (pour évolution) sous .NET par exemple. Les résultats risqueraient d'être bizzaroide si borland decidait de changer la représentation interne des SET.
    http://www.pocketmt.com GLCD Font Creator home site.

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Points : 711
    Points
    711
    Par défaut
    Bonjour,
    Citation Envoyé par octal
    Citation Envoyé par sfxElrick
    un peu ds le style de ma 'solution' non ?? :p
    non nje parle pas de ta sol. La tienne est "bonne"
    c'est de la sol de thewho que je paralais. le fait de considérer qu'un SET OF sera tjr codé sur un byte et que un byte sera tjr de 8 bit (ce qui donne les 255 val possible dans un ensemble) est un pari très risqué. surtout si ton code devait être repris (pour évolution) sous .NET par exemple. Les résultats risqueraient d'être bizzaroide si borland decidait de changer la représentation interne des SET.
    Je n'ai jamais dit ça !!

    Pour ce que j'ai écrit en rouge : 8 bits, à raison de 1 bit/valeur, ça donne 8 valeurs possibles.

    Il est clair qu'il faut adapter à chaque cas (entre autres, si l'ensemble contient plus de 8 valeurs possibles, alors il sera stocké sur plusieurs octets, suffisamment pour disposer d'un bit/valeur possible, et même plus si les valeurs ne sont pas contigues, auquel cas Delphi sacrifie de la place pour éviter les algorithme trop complexes pour stocker/extraire une valeur).

    Et si tu veux prendre en compte toutes les évolutions futures, que par définition tu ne connais pas, alors tu n'auras jamais un code réellement garanti pour fonctionner dans toutes les futures versions de Delphi.

    Après tout, tes programmes actuels assument probablement que Integer est codé sur 32 bits, or cela changera, sans le moindre doute, de manière beaucoup plus sûre que la représentation des ensembles (qui évoluera peut-être aussi, comment savoir ?)
    Compilation sans erreur ne signifie pas programme sans erreur.
    L'indentation n'a pas été imaginée pour faire beau, mais pour faciliter la lecture des programmes.

  12. #12
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    Citation Envoyé par thewho
    Bonjour,

    Et si tu veux prendre en compte toutes les évolutions futures, que par définition tu ne connais pas, alors tu n'auras jamais un code réellement garanti pour fonctionner dans toutes les futures versions de Delphi.
    j'ai des codes écris en TurboPascal6 qui continuent à compiler sous Delphi.

    Citation Envoyé par thewho
    Bonjour,
    Après tout, tes programmes actuels assument probablement que Integer est codé sur 32 bits, or cela changera, sans le moindre doute, de manière beaucoup plus sûre que la représentation des ensembles (qui évoluera peut-être aussi, comment savoir ?)
    Je ne considère JAMAIS que tel ou tel type de donnée fait 2 oyu 17 octet. J'utilise les type tjr de manière générique, si vous aviez fait du dev en multiplateforme vous me comprendriez. Quand je fais des dev pour du low level (l'ELECTRONIQUE principalement) j'ai créé une unité qui identifie les type d'une manière générique
    TYPE
    Byte8 = Byte;
    Int_32 = Integer;
    Int_64 = Int64
    ...

    comme cela si la représentation interne des type de base change, je ne changerais que mes déclaration, tous le reste du code restant indépenant. Et c'est cette meme technique qui est utilisée dans tous les framework multiplateform du genre GTK, OPENGL, ....
    bref, je voudrais pas polimiquer à propos des techniques de programmation, chacun est libre de choisir sa voie (et espérer qu'elle soit la bonne ).
    Pour ma part je pense qu'une petite procedure (ou classe) qui irait scruter l'ensemble peut être plus portable que d'aller chercher l'octet qui encode l'ensemble. De plus qu'arrivera t'il si le nombre d'elt devait changer pour passer à plus de 8 bit ????
    bon courage ... je considère cette discussion comme close
    http://www.pocketmt.com GLCD Font Creator home site.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    bon j'ai bien compris les arguments de chacuns et je les prends en compte

    mais je recadre un peu le sujet sur les questions initiales.

    j'en rajoute une au passage:

    existe il des fonctions dans delphi pour determiner l'element le plus grand et le plus petit (ou le premier et le dernier) d'un ensemble ?
    le parcour d'ensemble se faisant par:

    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
     
    Type
    Valeurs = (mePremier,meSecond,meTroisieme,...,meDernier);
    Const
    MonEnsemble = set of Valeurs;
    var
    i : Valeurs;
    ...
    begin
    ...
    for i := mePremier to meDernier do
    begin
    //faire les verifications d'apartenance par exemple
    ...
    end;
    ...
    end;
    (d'apres l'aide de delphi)
    il faut pouvoir connaitre le premier et le dernier element de l'ensemble (le premier et le dernier element de valeurs dans l'exemple), donc a part tjrs me reporter au def de mes valeurs, ou definir des constantes, y a t'il un moyen plus generique ?

  14. #14
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    tu peux parcourir l'ensemble des valeur de ton ensemble d'une manière générique en utilisant High() et Low() comme pour les intervalles.

    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
     
     
    type
      TValeurs  = (mePremier,meSecond,meTroisieme,meDernier);
      TEnsemble = set of TValeurs;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      iterateur   : TValeurs;
      ens : TEnsemble;
    begin
      ens := [meSecond];
      for iterateur := Low(TValeurs) to High(Tvaleurs) do
      begin
      //faire les verifications d'apartenance par exemple
        if (iterateur in ens) then  showMessage(intToStr(Ord(iterateur)) + ' est dans ens')
      end;
    end;
    Pour récupérer l'ordre de l'element j'ai utilisé ORD(itérateur) mais tu peux avoir une représentation textuelle en utilisant un tableau de chaine qui mappe tes valeurs du genre ce que fait Borland avec le type TColor et les valeurs clRed, clBlue .... qui possedent une représentation textuelle en 'RED' 'BLUE', .....
    charges l'unité GRAPHICS et analyse TCOLOR et l'ensemble des valeurs avec leur tableau de correspondance
    Colors: array[0..51] of TIdentMapEntry = (....
    si t'es sous D7 tu trouvera celà à la ligne 1283 environ ...
    bon courage
    http://www.pocketmt.com GLCD Font Creator home site.

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    merci bien, j'v voir ça tt de suite

  16. #16
    Membre habitué Avatar de phplive
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 179
    Points : 150
    Points
    150
    Par défaut
    Bsr

    Pour récupérer les noms utilisés dans les types énumérés sous forme de chaîne tu peux aussi utiliser le fonction GetEnumName qui entre dans la catégorie des RTTI

    Il suffit d'ajouter l'unité TypInfo

    Ce qui donne :


    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
    type
      TValeurs  = (mePremier,meSecond,meTroisieme,meDernier);
      TEnsemble = set of TValeurs;
     
     
    implementation
     
    uses TypInfo;
     
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      iterateur   : TValeurs;
      ens : TEnsemble;
    begin
      ens := [meSecond];
      for iterateur := Low(TValeurs) to High(Tvaleurs) do
      begin
      //faire les verifications d'apartenance par exemple
        if (iterateur in ens) then
          showMessage(intToStr(Ord(iterateur)) + ' est dans ens = ['+
            GetEnumName(TypeInfo(TValeurs),Ord(iterateur))+']');
      end;
    end;
    @+
    Php
    @+
    Php

    D7 Enterprise - XP sp2
    The Truth is Out There

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 54
    Points : 23
    Points
    23
    Par défaut
    apres avoir chercher ce qu'etait le RTTI .. (j'ai appris un truc me coucherais moin bete ce soir), j'pense que j'vais me contenter du tableau de mappage

    mais merci de m'avoir appris un nouveau truc ! :p

  18. #18
    Membre éprouvé
    Avatar de octal
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    441
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 441
    Points : 957
    Points
    957
    Par défaut
    La RTTI est utile pour récupérer ce genre d'info, mais sache que Borland ne donne aucune garantie quand à la compatibilité des fonction de la RTTI dans les versions futures de son compilo (cherchez sur le site du DrBobs concernant la RTTI et ce qu'en dit borland si vous voulez plus d'infos)
    http://www.pocketmt.com GLCD Font Creator home site.

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

Discussions similaires

  1. Comment stocker la valeur d'une couleur ?
    Par 0n31l dans le forum VB.NET
    Réponses: 8
    Dernier message: 21/06/2014, 16h04
  2. Réponses: 2
    Dernier message: 14/05/2014, 10h23
  3. Comment stocker les valeurs de variables
    Par herroP dans le forum VB.NET
    Réponses: 18
    Dernier message: 10/07/2012, 15h54
  4. [AC-2003] Comment stocker les valeurs d'un champ d'un recordset
    Par megdi dans le forum VBA Access
    Réponses: 1
    Dernier message: 07/09/2009, 13h29
  5. Comment stocker une valeure ecrite dans un JFrame
    Par aphilippartd dans le forum Débuter
    Réponses: 3
    Dernier message: 12/12/2008, 18h10

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