Import csv [Résolu]

Signaler
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008
-
quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008
-
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

Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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...
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

Je te remercie, je vais travailler dessus et je te tiens au courant! :)
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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?
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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?
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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é...
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
c'est que tu n'as pas ouvert ton query :
procedure TForm1.FormCreate(Sender: TObject);
begin
  IboQuery1.Open;
end;

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

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;
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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...
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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...
Messages postés
4716
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
11
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
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Statut
Membre
Dernière intervention
25 novembre 2008

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.