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 :

Passer une StringGrid dans un MemoryStream


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 222
    Par défaut Passer une StringGrid dans un MemoryStream
    Bonjour à tous,

    Aujourd'hui je m'essaye au Stream mais je m'embrouille un peu ...
    J'ai une StringGrid de 40 colonnes et plusieurs lignes, j'aimerai la passer dans un MemoryStream mais je me perds un peu sur ce coup là.

    Je pensais passer chaque ligne avec StringGrid.Rows[x].text ... mais je bugue complet
    Vous pouvez me dire comment faire ?

    Ensuite, il faudra que je fasse l'inverse ... passer de la MemoryStream à la StringGrid ...

    ... 1h après ...
    Pour écrire ma StringGrid dans le Stream j'ai fais ceci (non testé). Vous pensez que c'est bon ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
         for X := 0 to GridPrincipale do
         begin
            S1:= GridPrincipale.Rows[X].Text;
            Stream.Write(S1,SizeOf(S1));
         end;
     
         Stream.SaveToFile(NomFichier) ;
    Par contre, pour lire le Stream et le passer à la Stringgrid je coince encore. Je cherche un moyen de lire du début à la fin, mais pas de EOF comme avec les fichiers ...

  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
    aïe !

    tu enregistres dans ton stream l'adresse mémoire de toutes les chaînes...ça n'a strictement aucun intérêt

    la première chose à déterminer c'est le format que tu souhaites avoir dans ton fichier

    tu peux utiliser du JSON, du XML, du DFM mais là manifestement tu veux juste stocker dans un format propriétaire.

    mais pour pouvoir relire ton flux, il va falloir préparer les choses

    1) quelles sont les dimensions du tableau ?

    on va placer en début de flux, deux entiers, le nombre de colonnes et le nombre de lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    begin
      i := GridPrincipale.Cols;
      Stream.Write(i, SizeOf(i));
      i := GridPrincipale.Row;
      Stream.Write(i, SizeOf(i));
    end;
    2) on peut maintenant stocker les valeurs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for y := 0 to GridPrincipale.Rows - 1 do
      for x := 0 to GridPrincipale.Cols - 1 do
      begin
        s := GridPincipale.Cells[x, y];
        i := Length(s);
        Stream.Write(i, SizeOf(i));
        if i > 0 then
          Stream.Write(s[1], i * SizeOf(Char));
      end;
    voilà on a maintenant un flux pour un tableau dont on connait les dimensions et pour chaque cellule on a le contenu en précisant sa taille

    la lecture devient presque évidente...lire cols, rows, et pour chaque cellule lire la longueur du texte, puis le texte
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 541
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 541
    Billets dans le blog
    10
    Par défaut
    C'est déjà proposé par Delphi

    Exemple
    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
    function Serialize(O1: TComponent) : string ;
    var
      MS1, MS2: TMemoryStream;
      Sl1: TStringList;
    begin
      MS1 := TMemoryStream.Create;
      MS2 := TMemoryStream.Create;
      Sl1 := TStringList.Create;
      MS1.WriteComponent(O1);
      MS1.Seek(0, soFromBeginning);
      ObjectBinaryToText(MS1, MS2);
      MS2.Seek(0, soFromBeginning);
      Sl1.LoadFromStream(MS2);
      result := sl1.Text ;
      Sl1.Free;
      MS2.Free;
      MS1.Free
    end;
    Tu peux t'en inspirer. Si besoin d'exemple je te l'en envoie un

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    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 089
    Par défaut
    Tu peux utiliser un format classique comme le CSV : TStringGridCSVHelper

    un vieux code genre mon TStringGridCrossManager qui exporte un TStringGrid dans un fichier

    Le DFM comme proposé ci-dessus est pertinent aussi, le chargement étant un peu plus délicat sur la gestion de l'instance.
    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

  5. #5
    Membre éclairé

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 222
    Par défaut
    En fait c'est un CSV
    Donc ok, le plus simple est de passer par une StringList qui elle à tout ce qu'il faut pour passer par des Stream et les fichiers avec les SaveTo et LoadFrom
    Je m'étais dit que pour gagner du temps dans les boucles je pouvais directement mettre une string représentée par GridPrincipale.Rows[X].Text dans un Stream, mais visiblement celui ci ne se manipule pas comme une StringList ....
    Ou alors il y a quelque chose que je ne connais pas ?

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    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 089
    Par défaut
    En Lazarus : lcsvutils.LoadFromCSVFile

    En Delphi :
    Si l'on ne se préoccupe pas des performances, lire et écrire un CSV avec une TStringGrid VCL c'est juste enfantin.
    Si l'on ne préoccupe pas non plus des données multi-lignes, c'est vive 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
    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
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    unit DirtyStringGrid_MainForm;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids;
     
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        StringGrid1: TStringGrid;
        Button1: TButton;
        Button2: TButton;
        Memo2: TMemo;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
      TStringGridTool = record
      public
        class procedure LoadFromStream(AGrid: TStringGrid; AStream: TStream); static;
        class procedure SaveToStream(AGrid: TStringGrid; AStream: TStream); static;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    uses System.Math;
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      MS: TMemoryStream;
    begin
      MS := TMemoryStream.Create();
      try
        Memo1.Lines.SaveToStream(MS);
     
        MS.Seek(0, soBeginning);
        TStringGridTool.LoadFromStream(StringGrid1, MS);
      finally
        MS.Free();
      end;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
      MS: TMemoryStream;
    begin
      MS := TMemoryStream.Create();
      try
        TStringGridTool.SaveToStream(StringGrid1, MS);
     
        MS.Seek(0, soBeginning);
        Memo2.Lines.LoadFromStream(MS);
      finally
        MS.Free();
      end;
    end;
     
    { TStringGridTool }
     
    class procedure TStringGridTool.LoadFromStream(AGrid: TStringGrid; AStream: TStream);
    var
      Lines, Header: TStringList;
      I: Integer;
    begin
      Lines := TStringList.Create();
      try
        Lines.LoadFromStream(AStream);
     
        AGrid.FixedRows := 1; // Header ?
        AGrid.RowCount := Lines.Count;
        AGrid.FixedCols := 0;
        AGrid.ColCount := 0;
     
        if Lines.Count > 0 then
        begin
          Header := TStringList.Create();
          try
            Header.Delimiter := ';';
            Header.StrictDelimiter := True;
            Header.DelimitedText := Lines[0];
            AGrid.ColCount := Header.Count;
     
            AGrid.Rows[0].Assign(Header);
          finally
            Header.Free();
          end;
     
          for I := 1 to Lines.Count - 1 do
          begin
            AGrid.Rows[I].Delimiter := ';';
            AGrid.Rows[I].StrictDelimiter := True;
            AGrid.Rows[I].DelimitedText := Lines[I];
     
            AGrid.ColCount := Max(AGrid.ColCount, AGrid.Rows[I].Count);
          end;
        end;
      finally
        Lines.Free();
      end;
    end;
     
    class procedure TStringGridTool.SaveToStream(AGrid: TStringGrid; AStream: TStream);
    var
      Lines: TStringList;
      I: Integer;
    begin
      Lines := TStringList.Create();
      try
        Lines.Capacity := AGrid.RowCount;
     
        for I := 0 to AGrid.RowCount - 1 do
        begin
          AGrid.Rows[I].Delimiter := ';';
          Lines.Add(AGrid.Rows[I].DelimitedText);
        end;
     
        Lines.SaveToStream(AStream);
      finally
        Lines.Free();
      end;
    end;
     
    end.
    Evidemment TMemo et TMemoryStream c'est pour faire un démo simpliste à remplacer par un TFileStream

    et la DFM :

    Code DFM : 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
    object Form1: TForm1
      Left = 0
      Top = 0
      Caption = 'Form1'
      ClientHeight = 522
      ClientWidth = 710
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object Memo1: TMemo
        Left = 574
        Top = 8
        Width = 128
        Height = 86
        Lines.Strings = (
          'A;B;C'
          '1;2;3'
          '4;5;6'
          '7;8;9')
        TabOrder = 0
      end
      object StringGrid1: TStringGrid
        Left = 8
        Top = 8
        Width = 467
        Height = 434
        TabOrder = 1
      end
      object Button1: TButton
        Left = 481
        Top = 69
        Width = 75
        Height = 25
        Caption = 'Button1'
        TabOrder = 2
        OnClick = Button1Click
      end
      object Button2: TButton
        Left = 481
        Top = 100
        Width = 75
        Height = 25
        Caption = 'Button2'
        TabOrder = 3
        OnClick = Button2Click
      end
      object Memo2: TMemo
        Left = 574
        Top = 100
        Width = 128
        Height = 142
        Lines.Strings = (
          'Memo2')
        TabOrder = 4
      end
    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

  7. #7
    Membre éclairé

    Homme Profil pro
    Direction financière et formateur en gestion et contrôle de gestion
    Inscrit en
    Mai 2003
    Messages
    222
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Direction financière et formateur en gestion et contrôle de gestion
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2003
    Messages : 222
    Par défaut
    ShaiLeTroll là ma curiosité est piquée

    En Delphi :
    Si l'on ne se préoccupe pas des performances, ...
    Actuellement, je fais ceci pour passer d'une StringList dans laquelle j'ai chargé mon Stream vers une StringGrid

    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
     
      List_Transfert_Enregistrement:=TStringList.Create();
     
      Stream :=TMemoryStream.Create ;
      Stream.LoadFromFile(NomFichier);
      ...// traitement dans le TmemoryStream ...
      List_Transfert_Enregistrement.LoadFromStream(Stream);
     
      for X := 0 to GridDestination.RowCount - 1
      do Principale.GridPrincipale.Rows[X].Clear;
      GridDestination.RowCount := 1;
     
      for X := 0 to List_Transfert_Enregistrement.Count - 1 do
      begin
         if trim(List_Transfert_Enregistrement[X])<>''
         then begin
            GridDestination.Rows[GridDestination.RowCount - 1].QuoteChar := FQuoteChar;
            GridDestination.Rows[GridDestination.RowCount - 1].Delimiter := FSVdelimiter;
            GridDestination.Rows[GridDestination.RowCount - 1].StrictDelimiter := true;
            GridDestination.Rows[GridDestination.RowCount - 1].DelimitedText := List_Transfert_Enregistrement[X];
            GridDestination.RowCount := GridDestination.RowCount + 1;
         end;
      end;
    TStringGridTool.LoadFromStream(StringGrid1, MS);
    Serait-il plus rapide ?

    Tiens, j'ai droit à un
    TStringGridTool "Directive inconnue"

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

Discussions similaires

  1. [JDBC]Passer une valeur dans une requete KO
    Par joseph_p dans le forum JDBC
    Réponses: 6
    Dernier message: 16/02/2008, 17h00
  2. passer unee struct dans un buffer (char *)
    Par baert dans le forum C++
    Réponses: 2
    Dernier message: 20/02/2006, 21h49
  3. [VBA]Passer une variable dans une formule Excel
    Par David1974 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 27/01/2006, 16h52
  4. [Struts] Passer une variable dans l'url
    Par pilz dans le forum Struts 1
    Réponses: 2
    Dernier message: 30/03/2005, 15h23
  5. Sauver une StringGrid dans un fichier
    Par Rodrigue dans le forum C++Builder
    Réponses: 2
    Dernier message: 10/12/2003, 14h52

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