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 :

Record avec champ "variable"


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut Record avec champ "variable"
    Bonjour,

    J'ai un petit problème de débutant mais je pense que cette section convient mieux pour mon cas...

    J'ai une procédure qui déclare et utilise localement un record dont une partie est "variable"; ce code fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    procedure Test;
    const
      NbMax = 10;
    type
      TMonRecord = record
        Tableau: array[0..NbMax - 1] of Integer;
      end;
    var
      UnRecord: TMonRecord;
      i1: Integer;
    begin
     //
    end;
    mais je voudrais passer la partie variable en paramètre de ma fonction, et là ça ne marche plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure Test(const NbMax: Integer);
    type
      TMonRecord = record
        Tableau: array[0..NbMax - 1] of Integer;
      end;
    var
      UnRecord: TMonRecord;
      i1: Integer;
    begin
     //
    end;
    Comment faire pour rendre mon record "dynamique", selon le paramètre passé à la procédure ?

    (Je sais, c'est niveau raz-de-la-moquette, mais j'ai toujours eu du mal avec les subtilités du langage)

    Merci

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure Test(const NbMax: Integer);
    type
      TMonRecord =  array of Integer;
    var
      UnRecord: TMonRecord;
      i1: Integer;
    begin
      SetLength(UnRecord, NbMax);
     //
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 093
    Par défaut
    Attention au terme "variable" en Delphi, il existe Partie variable des enregistrements, voir plus bas dans ma réponse, c'est plus tordu !

    @Paul Toth, TMonRecord n'est plus un record mais un type équivalent à TIntegerDynArray

    GoustiFruit, pour ton cas que Paul Toth a un peu trop simplifié, c'est la même chose avec le type string

    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
    const
      NbMax = 10;
     
    type
      TMonRecord = record 
        Tableau: Types.TIntegerDynArray; // Dès D6, sinon "array of Integer"
        Chaine: string;
        ChaineFixe: ShortString;
        ChaineDix: string[10];
      end;
     
    var
      UnRecord: TMonRecord;
      i: Integer;
    begin
      SetLength(UnRecord.Tableau, NbMax);
      for i := Low(UnRecord.Tableau) do High(UnRecord.Tableau) do
        UnRecord.Tableau[i] := i; 
     
      Chaine := 'Une Phrase Longue c''est  dynamique';
      SetLength(UnRecord.Chaine, NbMax); // Tronque la chaine !
     
      ChaineFixe = 'Une Phrase Longue ce n''est pas dynamique ici car toujours 255 caractères';
      ChaineDix := 'Pas plus de Dix ! Oups !'; // tronque !
     
    end;

    Un démo de la Partie variable des enregistrements, tu noteras que c'est différent mais aussi très intéressants !


    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
    procedure Test;
    const
      NbMax = 10;
    type
      TMonRecord = record
        case integer of
          0: (
               Tableau: array[0..NbMax - 1] of Integer;
             );
     
         1: (
               I1: Integer;
               I2: Integer;
               I3: Integer;
               I4: Integer;
               I5: Integer;
               I6: Integer;
               I7: Integer;
               I8: Integer;
               I9: Integer;
               I10: Integer;
             );
     
      end;
    var
      UnRecord: TMonRecord;
      i: Integer;
    begin
    begin
      SetLength(UnRecord.Tableau, NbMax);
      for i := Low(UnRecord.Tableau) do High(UnRecord.Tableau) do
        UnRecord.Tableau[i] := i; 
     
      ShowMessage(IntToStr(UnRecord.i1)); // contient 0 car partage l'espace mémoire avec Tableau[0]
      ShowMessage(IntToStr(UnRecord.i2)); // contient 1 partage avec Tableau[1]
      ShowMessage(IntToStr(UnRecord.i3)); // contient 2 partage avec Tableau[2]
      ...
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    @Paul Toth: mon exemple est hyper simplifié, en réalité mon enregistrement contient d'autres champs !

    @Paul Toth et @ ShaiLeTroll: je ne veux pas passer par SetLength car par la suite j'utilise un grand nombre d'enregistrements de type TMonRecord, je suis en D7 et ça ne me semble pas efficace de redimensionner pour chaque enregistrement !?

    Mais d'après vous il n'y a pas moyen de déclarer ce tableau dans mon record avec une taille dépendant d'un paramètre ? Vraiment obligé de passer par SetLength ?

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 093
    Par défaut
    Citation Envoyé par GoustiFruit Voir le message
    Mais d'après vous il n'y a pas moyen de déclarer ce tableau dans mon record avec une taille dépendant d'un paramètre ? Vraiment obligé de passer par SetLength ?
    C'est un simple tableau dynamique, c'est ultra standard comme pratique !


    Citation Envoyé par GoustiFruit Voir le message
    je suis en D7 et ça ne me semble pas efficace de redimensionner pour chaque enregistrement !?
    Si tu alloue le tableau qu'une seule fois, c'est tout à fait performant, regarde la String, cela passe son temps à faire ça !
    Par contre, si tu passe ton temps à changer de taille, cela devient discutable, il faudrait étudier une TList ou TObjectList,
    mais bon si tu utilises des Record, tu ne dois pas être familier de la POO en général

    Citation Envoyé par GoustiFruit Voir le message
    j'utilise un grand nombre d'enregistrements de type TMonRecord
    ?
    un Grand nombre ? 10 000 ? 100 000 ?
    Création de metaclass en dynamique
    Création d'objets "par lots"


    Deux méthodes,
    soit le SetLength pour le tableau dynamique
    soit une Partie variable des enregistrements, je pense que tu n'as pas envisagé cela avec ma démo :

    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 Test;
    type
      TMonRecord = record
        case integer of
          10: (Tableau10: array[0..9] of Integer;); 
          20: (Tableau20: array[0..19] of Integer;);
          30: (Tableau30: array[0..29] of Integer;);
      end;
    var
      UnRecord: TMonRecord;
      i: Integer;
    begin
      for i := Low(UnRecord.Tableau10) do High(UnRecord.Tableau10) do
        UnRecord.Tableau10[i] := i; 
     
      for i := Low(UnRecord.Tableau20) do High(UnRecord.Tableau20) do
        ShowMessage(UnRecord.Tableau20[i]); 
     
      for i := Low(UnRecord.Tableau20) do High(UnRecord.Tableau20) do
        UnRecord.Tableau20[i] := -i; 
     
      for i := Low(UnRecord.Tableau10) do High(UnRecord.Tableau10) do
        ShowMessage(UnRecord.Tableau10[i]); 
     
      for i := Low(UnRecord.Tableau20) do High(UnRecord.Tableau20) do
        ShowMessage(UnRecord.Tableau20[i]); 
     
      for i := Low(UnRecord.Tableau30) do High(UnRecord.Tableau30) do
        ShowMessage(UnRecord.Tableau30[i]); 
    end;
    en pratique dans le 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
    procedure FaireChose(TableauType: Integer);
    begin
      case TableauType of 
        10 : FaireChoseTableau(UnRecord.Tableau10);
        20 : FaireChoseTableau(UnRecord.Tableau20);
        30 : FaireChoseTableau(UnRecord.Tableau30);
      end;
    end;
     
    procedure FaireChoseTableau(const Tableau : array of Integer);
    var
      i: Integer
    begin
      for i := Low(Tableau) do High(Tableau ) do
        ShowMessage(Tableau [i]); 
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    ?
    un Grand nombre ? 10 000 ? 100 000 ?
    99% du temps ça serait quelques centaines, mais en théorie ça pourrait atteindre 5-10 millions dans certains cas.

    Deux méthodes,
    soit le SetLength pour le tableau dynamique
    soit une Partie variable des enregistrements, je pense que tu n'as pas envisagé cela avec ma démo :
    J'avais envisagé, mais les cas ne seront pas déterminés à l'avance, ils dépendront vraiment du paramètre.

    Bon, allons-y pour le SetLength...

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    C'est un simple tableau dynamique, c'est ultra standard comme pratique !
    tout à fait

    Citation Envoyé par ShaiLeTroll Voir le message
    ...
    Deux méthodes,
    soit le SetLength pour le tableau dynamique
    soit une Partie variable des enregistrements, je pense que tu n'as pas envisagé cela avec ma démo :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure Test;
    type
      TMonRecord = record
        case integer of
          10: (Tableau10: array[0..9] of Integer;); 
          20: (Tableau20: array[0..19] of Integer;);
          30: (Tableau30: array[0..29] of Integer;);
      end;
    ?????!!!! tu me fais quoi là Shai ?????!!!

    tout cela pour utiliser Low() et High() ?! c'est assez horrible
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

Discussions similaires

  1. Requête avec champ NULL simple quote
    Par tidou95220 dans le forum Requêtes
    Réponses: 2
    Dernier message: 13/07/2012, 13h15
  2. problème de Wshshell.run avec quotes & variable
    Par frenchlion dans le forum VBScript
    Réponses: 8
    Dernier message: 29/11/2011, 17h35

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