Bonjour à tous,

Je récupère des fichiers au format CSV d’une machine que je souhaite ouvrir dans un TStringrid pour qu’il soit en colonnes.
Jusque là tout va bien. Mais il y a un mais, sinon je ne serais pas là.

Le format d’une ligne est du style : 2010,0,125,’’FORME,COURBE’’,563,0, ‘’coupe directe,par0893,,,,
Le séparateur choisit est la virgule mais il ne faudrait pas créer de colonne supplémentaire si un ensemble se trouve entre guillemets. Et là, je calle !

Si quelqu’un peut me donner un coup de main ce serait sympa.
Ce sont mes premiers pas en Dephi, soyez indulgents svp.

Voila mon 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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
{-----------------------------------------------------}
{ Click sur le bouton Menu ouvrir.                                           }
{-------------------------------------------------------------}
procedure TForm1.MnuOuvrirClick(Sender: TObject);
var
I,J,X,Y : Integer;
OpenDialog1 : TOpenDialog;
CsvExtract : TCsvExtraction;
 
begin
{On crée dynamiquement la boite d'ouverture de fichier}
OpenDialog1 := TOpenDialog.Create(nil);
 
   Try
   {On sélectionne les types de fichiers que la BAD peut ouvrir}
   OpenDialog1.Filter := 'Csv Files (*.csv)|*.csv';
   OpenDialog1.Title := 'Sélectionnez un fichier CSV';
      If Not OpenDialog1.Execute then  Exit;
      try
      begin
 
      {On lance analyse du fichier}
      ExtractCsvData(MnuTab.Checked,MnuPointVirgule.Checked,MnuVirgule.Checked,
      MnuEspace.Checked,MnuAutre.Checked,BoutEffLigne.Cancel,EditOther.Text,OpenDialog1.FileName,CsvExtract);
      {On détemrine le nombre de ligne du tableau}
      X := High(CsvExtract.TabResultat);
      Y := High(CsvExtract.TabResultat[1]);
      StringGrille.RowCount := Y + 2;
      StringGrille.ColCount := X + 1;
 
         {On affiche les données dans le stringrid}
         For I:=0 to X do
         begin
         StringGrille.Cells[I,0] := 'Col. ' + IntToStr(I+1) + ' ';
 
            For J:=0 to Y do
            StringGrille.Cells[I,J+1] := CsvExtract.TabResultat[I,J];
         end;
      end;
 
   {On appelle la procedure de redimensionnent des colonnes}
   MnuRedimClick (nil);
 
   StringGrille.Visible:= true;
   MnuRedim.Enabled:= true;
   MnuOuvrir.Enabled:= false;
   //MnuEnregistrer.Enabled:= True;
   MnuFermer.Enabled:= True;
   LblPosition.Visible:= True;
 
   except
   ShowMessage( 'Le fichier est déja ouvert, incompatible ou vide !');
   end;
 
   finally
   {On détruit BAD pour libérer la mémoire}
   OpenDialog1.Free;
 
   end;
end;
 
{------------------------------------------------------------------------------}
{ Exportation des données du fichier dans un tableau.                          }
{------------------------------------------------------------------------------}
procedure TForm1.ExtractCsvData(BoolTab,BoolPointVirgule,BoolVirgule,BoolEspace,BoolAutre,EffaceLigne : Boolean;
          SeparAutre : ShortString; NomFichier : AnsiString; var CsvExtract : TCsvExtraction);
 
const
SeparTab       = Chr(9);
SeparPtVirgule = ';';
SeparVirgule   = ',';
SeparEspace    = ' ';
 
   {Récupèration de la position des séparateurs}
   function RecupPosSepar(BoolTab,BoolPtVirgule,BoolVirgule,BoolEspace,BoolAutre : Boolean;
            SeparAutre : ShortString; Texte : String) : Integer;
 
   var
   I : Word;
   P : Array[1..5] of Integer;
 
   begin
 
      {Initialisation des positions des séparateurs à une valeur}
      For I:=1 to 5 do P[I] := 999999999;
 
      {Si le séparateur est démandé et que sa position est > 0 alors on conserve sa position}
      If (BoolTab) and (Pos(SeparTab,Texte) > 0) then P[1] := Pos(SeparTab,Texte);
 
      If (BoolPtVirgule) and (Pos(SeparPtVirgule,Texte) > 0) then P[2] := Pos(SeparPtVirgule,Texte);
 
      If (BoolVirgule) and (Pos(SeparVirgule,Texte) > 0) then P[3] := Pos(SeparVirgule,Texte);
 
      If (BoolEspace) and (Pos(SeparEspace,Texte) > 0) then P[4] := Pos(SeparEspace,Texte);
 
      If (BoolAutre) and (Pos(SeparAutre,Texte) > 0) then P[5] := Pos(SeparAutre,Texte);
 
   {On prend la plus petite valeur pour avoir obtenir le premier séparateur}
   Result := MinIntValue(P);
 
      {Si le résultat égal la valeur de départ alors on dit que le resultat = 0
      sinon s'il manque le séparateur en fin de ligne on perdra le dernier caractère}
      If Result = 999999999 then Result := 0;
   end;
 
   {On scanne tous les items qui comportent le caractère # et on les supprime}
   procedure VideListe(var ListeTemp : TStringList);
 
   var
   I : Integer;
 
   begin
   I := 0;
 
      While I < ListeTemp.Count do
      begin
         {Dabord on verifie que le champ soit remplit sinon erreur
          quand on fait juste un test sur le premier chr}
         If (Length(ListeTemp.Strings[I]) = 0) then ListeTemp.Delete(I)
         else
         begin
 
            If (ListeTemp.Strings[I][1] = '#') then ListeTemp.Delete(I)
            else Inc(I);
         end;
      end;
   end;
 
   {Récupération des différents champs}
   function RecupChamps(Ligne : String) : TStringList;
 
   var
   P0 : Integer;
 
   begin
   {On crée la liste de sortie}
   Result := TStringList.Create;
   {On recherche les ; et on insere les différents item dans la tableau}
   P0 := RecupPosSepar(BoolTab,BoolPointVirgule,BoolVirgule,BoolEspace,BoolAutre,SeparAutre,Ligne);
 
      While P0 > 0 do
      begin
      {On insere le champ}
      Result.Add(Copy(Ligne,1,P0-1));
      {On supprime ce champ du flux de données}
      Delete(Ligne,1,P0);
      {On récupère le champ suivant}
      P0 := RecupPosSepar(BoolTab,BoolPointVirgule,BoolVirgule,BoolEspace,BoolAutre,SeparAutre,Ligne);
      end;
 
      {S'il n'y a pas de séparateur à la fin de la ligne}
      If Length(Ligne) > 0 then Result.Add(Ligne);
   end;
 
var
Liste,Champs : TStringList;
I,J : Integer;
 
begin
{On crée dynamiquement la liste qui va contenir les lignes du fichier}
Liste := TStringList.Create;
 
   Try
 
      If FileExists(NomFichier) then
 
      begin
      {On charge le fichier}
      Liste.LoadFromFile(NomFichier);
      {On efface les cases vides ou commencant par #}
      //If EffaceRangee then VideListe(Liste);
      {On initialise le tableau}
      SetLength(CsvExtract.TabResultat,0,Liste.Count);
      {On fait toutes les lignes du fichier}
         For I:=0 to Liste.Count-1 do
         begin
         {On recupere les différents champ de la ligne}
         Champs := RecupChamps(Liste.Strings[I]);
            Try
               {On définit la taille du tableau}
               If High(CsvExtract.TabResultat) < Champs.Count then
               SetLength(CsvExtract.TabResultat,Champs.Count,Liste.Count);
               {On ajoute les lignes de la liste au tableau}
                  For J:=0 to Champs.Count-1 do
                  CsvExtract.TabResultat[J,I] := Champs.Strings[J];
            Finally
            Champs.Free;
            end;
         end;
      end
      else
      ShowMessage('Le chemin suivant : "' + NomFichier + '" n''est pas valide.');
 
   finally
   {On détruit le tstringlist pour libérer la mémoire}
   Liste.Free;
   end;
 
 
end;
Merci d'avance