Import csv

Résolu
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008
- 4 nov. 2008 à 15:04
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008
- 25 nov. 2008 à 11:11
Bonjour,  je dois programmer sous delphi l'import d'un fichier csv dans une base de données interbase.
Mais mon code plante!! :s

 IBquery1.Active := False;
 IBquery1.SQL.Clear;
 IBquery1.SQL.Add('LOAD DATA INFILE ''''C:\quantum\orders.txt'''' REPLACE INTO TABLE orders');
 IBquery1.SQL.Add('FIELDS TERMINATED BY '''';'''' ENCLOSED BY ''''".''''"''''."'''' ESCAPED BY ''''\\\\'''' ');
 IBquery1.SQL.Add('LINES TERMINATED BY ''''\\r\\n''''');
 IBquery1.Active := True;

Quelqu'un voit la solution ou a peut être une autre solution?

Merci d'avance.

16 réponses

cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
4 nov. 2008 à 19:49
Voilà une solution générale qui fonctionne sur mon micro avec mes composants (avec licence)

A toi d'adapter le code avec tes composants en précisant également qu'il n'y a pas de clé primaire auto-incrémentale, mais que si tu en as une ça marchera aussi, en modifiant l'index j :

unit Unit1;


interface


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, DBTables, StrUtils, IBODataset, IB_Components;


type
  TForm1 = class(TForm)
    Button1: TButton;
    IBOQuery1: TIBOQuery;
    Connexion: TIB_Connection;
    Transaction: TIB_Transaction;
    IBOQuery1CODETEMPO: TIntegerField;
    IBOQuery1CHAMP1: TDateField;
    IBOQuery1CHAMP2: TStringField;
    IBOQuery1CHAMP3: TIntegerField;
    procedure Button1Click(Sender: TObject);
    procedure ConnexionBeforeConnect(Sender: TIB_Connection);
    procedure FormCreate(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;


var
  Form1: TForm1;


implementation


{$R *.dfm}
   ///////////pm : f0xi   ////////////////////////////
function Parser(const Chaine, Separat: string; const Occurence: cardinal = 1): string;
var
  i, p1, p2, ld: integer;
begin
  Result := '';
  if (posex(Separat, Chaine[1]) = 1) and (Occurence <= 1) then exit;
  p1 := 1;
  ld := Length(Separat);
  for I := 1 to Occurence - 1 do
  begin
    p1 := posex(Separat, Chaine, p1);
    if P1 = 0 then
      exit
    else
      p1 := p1 + ld;
  end;
  p2 := posex(Separat, Chaine, p1);
  if p2 = 0 then
    p2 := length(Chaine) + 1;
  Result := copy(Chaine, p1, p2 - p1);
end;



procedure TForm1.ConnexionBeforeConnect(Sender: TIB_Connection);
begin
  Connexion.Username : = 'login';
  Connexion.Password := 'password';
end;



procedure TForm1.Button1Click(Sender: TObject);
var
  SL: TStringList;
  i, j: integer;
begin
  try
    screen.Cursor : = CrHourGlass;
    SL := TStringList.create;
    SL.loadFromFile('FichCSV.csv');   // ton fichier .CSV


    for i := 0 to SL.Count - 1 do
    begin
      IBOQuery1.Append;
      for j := 0 to IBOQuery1.FieldCount - 1 do
        IBOQuery1.fields[ j ].Text : = Parser(SL.Strings[i], ';', j + 1);
      IBOQuery1.Post;
    end;



  finally
    screen.Cursor := CrDefault;
    SL.Free;
  end;
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
  IboQuery1.Open;
end;



end.


cantador
3
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
4 nov. 2008 à 16:13
bonjour,
soit tu cherches un compo qui le fait direct..
soit tu lis ton fichier csv en parsant (gestion du séparateur)
et ensuite sur la table tu boucles sur les champs et tu append et post.

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

4 nov. 2008 à 16:49
Merci de te pencher sur mon problème cantador. En fai il n'y a pas d'erreur de syntaxe mais une erreur a l'execution :

erreur : Le projet Project1.exe a provoqué une classe d'exception EIBclient error avec le message'Opération annulée à la demande de l'utilisateur.'. Processus stoppé.

Je suis encore débutant sur delphi as tu un exemple de code a me proposer avec la gestion du séparateur...
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

5 nov. 2008 à 09:11
Je te remercie, je vais travailler dessus et je te tiens au courant! :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

14 nov. 2008 à 10:31
Cantador, j'ai essayé de remanier le code que tu m'avais mis ci dessous mais je bloque sur un point. Ca doit être tout bête mais pas moyen de trouver :s

Quand je met IBQuery1.open dans form.activate, il me met l'erreur instruction sql vide.
Quand je ne met pas IBQuery1.open, il me l'erreur impossible d'effectuer cette opération sur un ensemble de données fermé.

Saurais tu d'ou viens cette erreur?
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

14 nov. 2008 à 10:36
Après j' ai aussi essayé de travailler sur le code d'ezekiel en voulant récuperer les données du stringgrid dans un ibquery mais ça bloque à ce point la :
     For J:=0 to Y do
     StringGrid1.Cells[I,J+1] := CsvExtract1.TabResult[I,J];
      IBQuery1.Edit;
      IBQuery1.text := StringGrid1.Cells[I,J];  {[Erreur] Unit1.pas(249): Affectation impossible à une propriété en lecture seule}
      IBQuery1.Post;

Des idées?
0
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
14 nov. 2008 à 14:57
Quand je met IBQuery1.open dans form.activate, il me met l'erreur instruction sql vide.



ça veut dire que la propriété SQL est vide et donc ton query ne peut pas s'ouvrir.


essaie en mettant : select * from MaTable

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

14 nov. 2008 à 15:03
J'ai essayé le programme se lance mais quand je clique sur le bouton pour importer il me met l'erreur impossible d'effectuer cette opération sur un ensemble de données fermé...
0
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
14 nov. 2008 à 15:17
c'est que tu n'as pas ouvert ton query :
procedure TForm1.FormCreate(Sender: TObject);
begin
  IboQuery1.Open;
end;

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

14 nov. 2008 à 15:20
mon code pour le bouton d'import :

procedure TForm1.Button2Click(Sender: TObject);
var
  SL: TStringList;
  i, j: integer;
begin
  try
    screen.Cursor := CrHourGlass;
    SL := TStringList.create;
    SL.loadFromFile('Orders.txt');  
    for i := 0 to SL.Count - 1 do
    begin
      IBQuery1.Append;
      for j := 0 to IBQuery1.FieldCount - 1 do
        IBQuery1.fields[j].Text := Parser(SL.Strings[i], ';', j + 1);
      IBQuery1.Post;
    end;


  finally
    screen.Cursor := CrDefault;
    SL.Free;
  end;


end;


function Parser(const Chaine, Separat: string; const Occurence: cardinal = 1): string;
var
  i, p1, p2, ld: integer;
begin
  Result := '';
  if (posex(Separat, Chaine[1]) = 1) and (Occurence <= 1) then exit;
  p1 := 1;
  ld := Length(Separat);
  for I := 1 to Occurence - 1 do
  begin
    p1 := posex(Separat, Chaine, p1);
    if P1 = 0 then
      exit
    else
      p1 := p1 + ld;
  end;
  p2 := posex(Separat, Chaine, p1);
  if p2 = 0 then
    p2 := length(Chaine) + 1;
  Result := copy(Chaine, p1, p2 - p1);
end;


procedure TForm1.FormActivate(Sender: TObject);
begin
ibquery1.Open;
end;
0
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
14 nov. 2008 à 15:32
mets un point d'arrêt sur :
for i := 0 to SL.Count - 1 do
et teste si à cet endroit ton query est ouvert..


et il faut aussi que le fichier orders.txt soit dans ton projet sinon il faut mettre le chemin d'accès complet.

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

14 nov. 2008 à 15:47
Merci de ton aide cantador.
Le fichier csv est bien dans mon projet, c'est pour ça que j'ai pas mis le chemin. J'ai mis un point d'arrêt sur la ligne
for i := 0 to SL.Count - 1 do
par contre je ne sais pas comment faire pour tester si le query est ouvert ou pas...
j'ai essayé de mettre ibquery1.open; juste avant la ligne ci-dessus pour le forcer a "open" mais il me met quand même l'erreur.

si tu veux je peux t'envoyer mon source...
0
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
14 nov. 2008 à 18:32
Pour évaluer/Modifier CTRL F7 sur le point d'arrêt.
Ton query doit s'ouvrir aussi en changeant manuelllement la propriété active !

Jette un oeil sur la propriété DataBaseName..

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

17 nov. 2008 à 10:34
Alors ou j'en suis?!!
1) En mettant manuelement IBQuery1.active := true; j' ai toujours la même erreur.
2)En utilisant évaluer sur mes lignes de codes, je trouve plusieurs choses bizarres...
    -SL.loadFromFile('c:\quantum\Orders.txt'); -> (aucune valeur)
    -IBQuery1.append ->(point d'arrêt sur for i := 0 to SL.Count - 1 do) :
                                            " Exception Delphi EDatabaseError à $994F935 "
                                  ->(point d'arrêt sur for j := 0 to IBQuery1.FieldCount - 1 do) :
                                            " Identificateur non déclaré : 'IBQuery1' "
3)Propriété database name? Le chemin est bon j'utilise déjà cette base sur d'autre programmes...
0
cs_cantador
Messages postés
4720
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
31 juillet 2021
14
17 nov. 2008 à 13:54
dur dur.. la programmation..

1) En mettant manuelement IBQuery1.active := true; j' ai toujours la même erreur.

inutile d'aller plus loin, il faut régler d'abord ce problème :
si ton databasename est bon alors c'est ta requête qui ne va pas..

cantador
0
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

25 nov. 2008 à 11:11
C'est bon!! :D La solution était simple. J'ai utilisé une table au lieu d'un query et ça a fonctionné. Merci pour votre aide Cantador et Ezekiel.
0