Import csv [Résolu]

Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
- 4 nov. 2008 à 15:04 - Dernière réponse :
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
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.
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
4 nov. 2008 à 19:49
3
Merci
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

Merci cs_cantador 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de cs_cantador
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
4 nov. 2008 à 16:13
0
Merci
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
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
4 nov. 2008 à 16:49
0
Merci
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...
Commenter la réponse de quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
5 nov. 2008 à 09:11
0
Merci
Je te remercie, je vais travailler dessus et je te tiens au courant! :)
Commenter la réponse de quentind59
Messages postés
11
Date d'inscription
vendredi 9 mai 2008
Dernière intervention
1 décembre 2008
10 nov. 2008 à 09:53
0
Merci
Il y a une source sur delphifr qui fais exactement ce que tu cherche, je l'utilise moi meme, en l ayant adapter a mon besoin spécifique...
Voila le lien :
http://www.delphifr.com/code.aspx?ID=27766

Tu poura remercier JMP77 pour cette source fort utile :)
En esperant que ca reponde a tes attentes...
cdt;

Brûle la Gomme!!! Pas ton Âme!!!
Commenter la réponse de cs_ezekiel62
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
10 nov. 2008 à 13:45
0
Merci
ezekiel62:
la source indiquée ne concerne pas l'importation dans une table mais dans un StringGrid et par ailleurs le parseur de f0xi est plus performant..

cantador
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
14 nov. 2008 à 10:31
0
Merci
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?
Commenter la réponse de quentind59
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
14 nov. 2008 à 10:36
0
Merci
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?
Commenter la réponse de quentind59
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
14 nov. 2008 à 14:57
0
Merci
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
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
14 nov. 2008 à 15:03
0
Merci
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é...
Commenter la réponse de quentind59
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
14 nov. 2008 à 15:17
0
Merci
c'est que tu n'as pas ouvert ton query :
procedure TForm1.FormCreate(Sender: TObject);
begin
  IboQuery1.Open;
end;

cantador
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
14 nov. 2008 à 15:20
0
Merci
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;
Commenter la réponse de quentind59
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
14 nov. 2008 à 15:32
0
Merci
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
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
14 nov. 2008 à 15:47
0
Merci
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...
Commenter la réponse de quentind59
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
14 nov. 2008 à 18:32
0
Merci
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
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
17 nov. 2008 à 10:34
0
Merci
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...
Commenter la réponse de quentind59
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Dernière intervention
27 mars 2018
17 nov. 2008 à 13:54
0
Merci
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
Commenter la réponse de cs_cantador
Messages postés
11
Date d'inscription
jeudi 8 mars 2007
Dernière intervention
25 novembre 2008
25 nov. 2008 à 11:11
0
Merci
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.
Commenter la réponse de quentind59

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.