Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi In eine CSV Datei Reinschreiben??? (https://www.delphipraxis.net/97751-eine-csv-datei-reinschreiben.html)

r3v0 15. Aug 2007 14:52


In eine CSV Datei Reinschreiben???
 
Hallo Zusammen,

Ich habe ein Problem:

Ich habe eine CSV Datei mit einen Inhalt
BildName.jpg dann Datum und Betrag.

mit ; getrennt

jetzt will ich aber in diese datei bei einen klick auffem button auf in die CSV datei reinschreiben das das der Datensatz quasi erledigt ist :)

mein bisheriger Code:


Der CODE Liest nur von der CSV datei ein und füllt ein String Grid!

Delphi-Quellcode:
unit Inhaltcsvfrm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, ExtCtrls, Math;

type
  Tfrminhaltcsv = class(TForm)
    Panel1: TPanel;
    pnlgridkorreckte: TPanel;
    pnlRadiobtn: TPanel;
    RadioGroup: TRadioGroup;
    pnlgridfalsch: TPanel;
    GridFalscheSchecks: TStringGrid;
    GridKorrekteGrid: TStringGrid;
    pnlButtonOKsetzen: TPanel;
    btnOK: TButton;
    procedure FormCreate(Sender: TObject);
    procedure RadioGroupClick(Sender: TObject);
  private
    { Private-Deklarationen }
    lst : TList;
    lstganz: TList;
  public
    { Public-Deklarationen }
    procedure lesencsv(Dateiname, Pfad: String);
    procedure lesencsvganz(Dateiname, Pfad: String);
  end;

var
  frminhaltcsv: Tfrminhaltcsv;

implementation

{$R *.dfm}

type
  Inhaltcsvdateikaputt = class
  private
  public
    Bildname: String;
    Betrag: currency;
    Erleidigt: String;
    Zeile: Integer;
    Datum : String;
end;

type
  Inhaltcsvdateiganz = class
  private
  public
    Bildname: String;
    Zeile: integer;
end;

{ Tfrminhaltcsv }

procedure Tfrminhaltcsv.lesencsv(Dateiname, Pfad: String);
var
  f: Textfile;
  sZeile,Bildnameneu,Bildnamehilfe : String;
  iZeile,i : integer;
  bild : Inhaltcsvdateikaputt;
  function GetNext : String;
  var
    iPos : integer;
  begin
    iPos := Pos(';', sZeile);
    if (iPos > 0) then
    begin
      Result := copy(sZeile, 1, iPos-1);
      delete(sZeile, 1,iPos);
    end
    else
    begin
      Result := sZeile;
      sZeile := '';
    end;
  end;
begin
   AssignFile(f, IncludeTrailingBackslash(Pfad) + Dateiname);
   Reset(f);
  Bildnamehilfe:= '';
   try
     iZeile := 0;
    Readln(f, sZeile);
    // falls gefüllt, müssen evtl Objecte zerstört werden
//    lst.Clear;

    // ### hier könnte man die Spalten aus der csv-Datei bestimmen
      while (not Eof(f)) do
      begin
         Readln(f, sZeile);
      inc(iZeile);
      Bildnameneu:= Getnext;

      if Copy(Bildnameneu,0,37) <> Copy(Bildnamehilfe,0,37) then
      begin
        bild := Inhaltcsvdateikaputt.Create();
        bild.Bildname := Bildnameneu;
        Bildnamehilfe:= Bildnameneu;
        bild.Datum := GetNext;
        bild.Betrag := StrToFloatDef(GetNext(), 0);
        bild.Zeile := iZeile;
        lst.Add(bild);
      end;
      end;
   finally
       CloseFile(f);
   end;
  GridFalscheSchecks.RowCount:= lst.Count+1;
  GridFalscheschecks.ColWidths[0]:= Canvas.TextWidth(bild.Bildname) +10;
  for i:= 0 to lst.Count - 1 do
  begin
    GridFalscheSchecks.cells[0,i+1]:= Inhaltcsvdateikaputt(lst[i]).Bildname;
    GridFalscheSchecks.Cells[1,i+1]:= FloatToStr(Inhaltcsvdateikaputt(lst[i]).Betrag);
    GridFalscheSchecks.Cells[2,i+1]:= Inhaltcsvdateikaputt(lst[i]).Erleidigt;
  end;
  lesencsvganz(Dateiname,Pfad);
end;



procedure Tfrminhaltcsv.FormCreate(Sender: TObject);
begin
  lst:= TList.Create;
  lstganz:= TList.Create;
end;

procedure Tfrminhaltcsv.lesencsvganz(Dateiname, Pfad: String);
var
  g: Textfile;
  sZeile,Bildnameneu,Bildnamehilfe : String;
  iZeile,i : integer;
  bildganz : Inhaltcsvdateiganz;
  Dateinameganz: String;
  function GetNext : String;
  var
    iPos : integer;
  begin
    iPos := Pos(';', sZeile);
    if (iPos > 0) then
    begin
      Result := copy(sZeile, 1, iPos-1);
      delete(sZeile, 1,iPos);
    end
    else
    begin
      Result := sZeile;
      sZeile := '';
    end;
  end;
begin
  Dateinameganz:= copy(Dateiname,0,3) + '6' + copy(Dateiname,5,20);
   AssignFile(g, IncludeTrailingBackslash(Pfad) + Dateinameganz);
    Reset(g);
  Bildnamehilfe:= '';
   try
     iZeile := 0;
    Readln(g, sZeile);   // ### hier könnte man die Spalten aus der csv-Datei bestimmen
 //   if lstganz.Count <> 0 then
   //   lstganz.Clear;         // falls gefüllt, müssen evtl Objecte zerstört werden


      while (not Eof(g)) do
      begin
         Readln(g, sZeile);
      inc(iZeile);
      Bildnameneu:= Getnext;

      if Copy(Bildnameneu,0,37) <> Copy(Bildnamehilfe,0,37) then
      begin
        bildganz := Inhaltcsvdateiganz.Create();
        bildganz.Bildname := Bildnameneu;
        Bildnamehilfe:= Bildnameneu;
        bildganz.Zeile := iZeile;
        lstganz.Add(bildganz);
      end;
      end;
   finally
       CloseFile(g);
   end;
  GridKorrekteGrid.RowCount:= lstganz.Count+1;
  GridKorrekteGrid.ColWidths[0]:= Canvas.TextWidth(bildganz.Bildname) +10;
  for i:= 0 to lstganz.Count - 1 do
  begin
    GridKorrekteGrid.cells[0,i+1]:= Inhaltcsvdateiganz(lstganz[i]).Bildname;
  end;
end;

procedure Tfrminhaltcsv.RadioGroupClick(Sender: TObject);
begin
  if RadioGroup.ItemIndex = 0 then
  begin

  end
  else
  begin

  end;
end;

end.

mkinzler 15. Aug 2007 15:03

Re: In eine CSV Datei Reinschreiben???
 
Hier würde sich ein CSV-DataSet anbieten. Auf dieses kannst du dann wie auf eine Datenbank zugreifen.

r3v0 15. Aug 2007 15:10

Re: In eine CSV Datei Reinschreiben???
 
Öhm???
Hmm wie wo was...

mkinzler 15. Aug 2007 15:14

Re: In eine CSV Datei Reinschreiben???
 
Es gibt verschiedene DataSet-Komponenten z.B. in der JVCL, welche eine CSV-Datei als DataSet kappseln. Dieses kann man dann mit datensensitiven Komponenten verbinden und wie jedes andere DataSet manipulieren (First, Next, Last, Edit, Post)

r3v0 15. Aug 2007 15:31

Re: In eine CSV Datei Reinschreiben???
 
Hmm dafür brauch ich aber keine Datenbank oder?

Kann ich nicht einfacher das machen?

Ich habe die Zeilenangabe in die ich reinschreiben muss.
und ich habe die werte.
Kann ich dann nicht einfach die Zeile neuschreiben?
und hinten einfach nur ;JA dranhängen?
nur kapier ich noch nicht so ganz wie zum teufel ich in die datei schreiben kann.

mkinzler 15. Aug 2007 15:41

Re: In eine CSV Datei Reinschreiben???
 
Die Datei zu editieren ist schwer. du müsstest sie in den speicher laden, verändern und zurückschreiben.
Für meinen Vorschlag bräuchtest du keine Db sondern die CSV-Datei wird als DB betrachtet.

shmia 15. Aug 2007 16:00

Re: In eine CSV Datei Reinschreiben???
 
Und dann gäbe es noch die Möglichkeit eine CSV-Datei komplett in ein TStringGrid Control zu laden.
Jede Änderung wird im StringGrid vorgenommen.
Erst wenn der Benutzer auf Speichern klickt, wird das TStringGrid Control wieder als CSV-Datei gespeichert.
Die orginale CSV-Datei wird dabei komplett überschrieben. (keine Aktualisierung einzelner Felder oder Datensätze)
Das ist weniger elegant als das CSV-Dataset, aber man kommt mit Delphi Bordmitteln aus.

PS: das ist der Weg, den mkinzler schon mit du müsstest sie in den speicher laden, verändern und zurückschreiben angedeutet hat.

Luckie 15. Aug 2007 16:02

Re: In eine CSV Datei Reinschreiben???
 
Zitat:

Zitat von mkinzler
Die Datei zu editieren ist schwer. du müsstest sie in den speicher laden, verändern und zurückschreiben.

Und was ist daran schwer? Das ist doch schnell gemacht:

Delphi-Quellcode:
procedure AddCSVLine(Filename: String; const Values: array of const);
var
  i: Integer;
  s: String;
begin
  for i := 0 to length(Values) - 1 do
  begin
    s := s + Values[i].VPChar + ';';
  end;
  ShowMessage(s);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AddCSVLine('foobar.csv', ['Wert1', 'Wert2', 'Wert3', 'Wert4']);
end;

mkinzler 15. Aug 2007 16:07

Re: In eine CSV Datei Reinschreiben???
 
Zitat:

Und was ist daran schwer? Das ist doch schnell gemacht:
wenn man sich auskennt natürlich nicht.

r3v0 15. Aug 2007 16:49

Re: In eine CSV Datei Reinschreiben???
 
Hmm......

Ja

Mir ist eben noch eingefallen das es sich um ein Multiuser system handeln wird.

Das heißt die CSV als Datenbank herzrichten wäre nciht verkehrt.!

Mach ich das dann über Systemsteuerung - > Verwaltung - > Datenquellen (ODBC)
--> Hinzufügen --> Microsoft Text Treiber (*.txt , *.csv)

Und nachher mit ner ADO connection auf des Teil?

Und wie sieht es aus kann ich dann ohne das ich auf den anderen PC´s irgendwas installiere das Programm nutzen?

Davon habe ich leider null ahnung. Wäre nett wenn es mir einer wenn er kurz zeit hat step by step kurz schreibt.

shmia 15. Aug 2007 17:09

Re: In eine CSV Datei Reinschreiben???
 
Zitat:

Zitat von r3v0
Mir ist eben noch eingefallen das es sich um ein Multiuser system handeln wird.

Und das ist das KO-Kriterium für CSV-Dateien als Datenbankersatz.
Ohne richtige Datenbank geht bei einem Multiuser System gar nichts.

mkinzler 15. Aug 2007 17:40

Re: In eine CSV Datei Reinschreiben???
 
Also entweder:
-Daten in richtige Datenbank kopieren
-eigene MU-Steuerung implementieren
-csv-Datei als externe Textdatei vom DBMS verwalten lassen

r3v0 16. Aug 2007 20:53

Re: In eine CSV Datei Reinschreiben???
 
Okay habe das problem anders gelöst!

habe einfach die komplette csv datei in eine TStringList reingelesen habe die betreffende Zeile Neugeschrieben und dann den inhalt der TStringList wieder in die CSV datei geschrieben!
Das ganze dauert so 0,03 Sekunden. für die Zeit bräuchte ich eine sperre der datei!

dies habe ich noch nicht gelöst!
Wollte ich aber wie folgt machen!
Einfach mit einen try except den fehler E/A32 oder wie der auch immer heißt abfangen und dann kurz warten und nomma probieren! Weil wenn die CSV datei benutzt wird dann weiß ich das da einer schreibt/liest! dann soll der nächste warten bis die frei ist und TaDa es nomma probieren wenn sie dann wieder frei ist kann er auch schreiben! Holt sich halt die komplette datei und schreibt nur seine Zeile nochmals neu!
dann noch eine überprüfung ob schon ein ';OK' hinten dran hängt und dementsprechend reagieren!

gibt es noch sachen an die ich denken sollte??

mkinzler 16. Aug 2007 21:00

Re: In eine CSV Datei Reinschreiben???
 
Bei MU-Zugriff würde ich dir sehr zum Einsatz eines richtigen DBMS raten.

r3v0 16. Aug 2007 21:04

Re: In eine CSV Datei Reinschreiben???
 
kann ich dieses DBMS auch ohne datenbank usw laufen lassen!
Ich kriege leider keine Datenbank zur verfügung gestellt! Und ich darf auch nichts bei den Leuten isntallieren!

mkinzler 17. Aug 2007 06:52

Re: In eine CSV Datei Reinschreiben???
 
Das DBMS ist der Datenbankserver. Du fragst also ob man einen (Auto-)Motor auch ohne Auto nutzen kann.
darfst du nichts installiere oder darf es nur nichts kosten?

r3v0 17. Aug 2007 07:11

Re: In eine CSV Datei Reinschreiben???
 
darf nichts installieren!
Server haben wir hier genug rumstehen!
Doch die wollen das komplett ohne datenbank anbindung!
naja mal schauen! Heute 12 Uhr ist abgabe!
Das locking muss noch rein!

Jelly 17. Aug 2007 07:54

Re: In eine CSV Datei Reinschreiben???
 
Sichere dich ab, dass nicht du nachher die Haue kriegst, wenn es Probleme wegen dem Multiuserbetrieb gibt. Es ist doch immer das Gleiche.

Wegen dem CSV Locking. Du kannst versuchen, das ReadOnly Bit zu setzen, sobald du das Schreiben beginnst. Versucht gleichzeitig ein anderer User das Schreiben, kriegst du dort eine Exception, die du abfangen kannst und entsprechend drauf reagieren kannst.

marabu 17. Aug 2007 08:47

Re: In eine CSV Datei Reinschreiben???
 
Hallo,

Zitat:

Zitat von r3v0
habe einfach die komplette csv datei in eine TStringList reingelesen habe die betreffende Zeile Neugeschrieben und dann den inhalt der TStringList wieder in die CSV datei geschrieben!
Das ganze dauert so 0,03 Sekunden. für die Zeit bräuchte ich eine sperre der datei!

das Einlesen würde ich etwa so machen, dann hast du deine Sperre:

Delphi-Quellcode:
var
  fs: TFileSTream;
  fn: TFileName;
  s: TStrings;
begin
  // fn := ParamStr(1);
  try
    fs := TFileStream.Create(fn, fmOpenReadWrite or fmShareExclusive);
  except
    // try again later ...
    Exit;
  end;

  s := TStringList.Create;
  s.LoadFromStream(fs);
  // your own wicked code ...
  fs.Size := 0;
  s.SaveToStream(fs);
  s.Free;

  fs.Free;
end;
Grüße vom marabu

r3v0 17. Aug 2007 09:47

Re: In eine CSV Datei Reinschreiben???
 
Ich habe es nun mit so nem try except block abgefangen!
Darum ne repeat until Schleife gesetzt und nen Sleep er soll es halt 10 mal machen wenn nach dem 10ten mal es immer noch nicht klappert! dann ne Message ey da hat was nicht geklappt try it again!

So heute ist abgabe und ich bin fertig :)

Danke nochmals für eure Hilfe! :dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz