Announcement

Collapse
No announcement yet.

Text Datei mit festen Feldgrößen einlesen ?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Text Datei mit festen Feldgrößen einlesen ?

    Wie kann ich eine Text Datei mit festen Feldlängen einlesen ? Ich habe folgendes probiert: Über Filestream werden nur die benutzten Zeichen eingelesen, die Leerzeichen werden ausgelassen. Dadurch kommt mein Programm aus dem "Tritt". Z.B.
    type
    TPerson = record
    Name: string[50];
    Vorname: string[18];
    Anrede: string[10];
    Titel: string[2];
    Stelle: string[20];
    Ort: string[10];
    Raum: string[10];
    Vorwahl: string[20];
    NbTel: string[10];
    FaxVorwahl: string[20];
    NbFax: string[10];
    Email: string[56];
    Kurzwahl: string[9];
    end;
    Der Name wird eingelesen und ist aber nur 32 Zeichen lang, dadurch stimmen die Zuordnungen für die nächsten Felder nicht.
    Vilen Dank für Eure Hilfe
    Andreas Bleckat

  • #2
    Hallo Andreas Bleckat,

    es muss eine Regelmäsigkeit gefunden werden, z.B. dass Name und Vorname in der Textdatei durch ein Semikolon getrennt sind. Wenn dies vorliegt, muss man eine Funktion erstellen, die dann aus einer beliebigen Länge max. die 50 Stellen - am Beispiel Name- zurückgibt.
    Die Regelmäsigkeit kann auch sein, dass im Text die Zeilenreihenfolge immer gleich ist, was heissen soll:
    x= Name
    x+1= Vorname
    x+2= Anrede
    ...
    Auch wenn dann eine Zeile frei ist, die aber für das Feld vorgesehen ist, hat man trotzdem die Regelmäsigkeit.

    Gruss Peter Wol

    Comment


    • #3
      Hallo Andreas,

      wieso werden denn die Leerzeichen ausgelassen. Das sollte eingentlich nicht sein. Sind denn die Leerzeichen in der Datei tatsächlich enthalten?

      Wenn die Leerzeichen in der Datei sind, aber über FileStream nicht eingelesen werden:<BR>
      Notfalls würde ich die Datei in eine TStringList lesen und zeilenweise abarbeiten. Jede Zeile sollte hierbei einen Datensatz repräsentieren. Diese Zeilen kannst Du dann aufschlüsseln...

      Grüße Joche

      Comment


      • #4
        Hallo,
        leider gibt es kein Trennzeichen ( in der Textdatei. Nur die vorgegebenen Feldlängen, die nicht bis zum letzten Zeichen genutzt werden. Die Daten eines Datensatzes (z.B. eine Person)liegen hintereinander in der Datei. Dann kommt die nächste Zeile. Mein Lösungsansatz war eben über TFilestream alles einzulesen und die einzelnen Feldlängen über String [50] vorgeben.
        z.B.:<PRE>
        type
        TPerson = record
        Name: string[50];
        Vorname: string[18];
        Anrede: string[10];
        end;
        Stream := TFileStream.Create'C:\Telefon.txt',fmOpenRead);
        Stream.Read(Person.Name, sizeof(Person.Name));

        Memo1.Lines.Add('Name:' + Person[index].Name);
        Memo1.Lines.Add('Vorname:' + Person[index].Vorname);
        </PRE>
        Der String Name ist leider nicht 50 Zeichen lang, sondern nur 32 Zeichen, dann kommt geich Vorname, 18 Zeichen zu früh.Wenn es nicht mit Stream und String[50] geht, dann muss ich eben alle Zeichen einlesen und abzählen. Es sah ja nur so schön bequem und logisch aus...
        Gruss
        Andreas Blecka

        Comment


        • #5
          Hallo Andreas Bleckat,

          posten Sie doch 'mal eine Beispieldatei (mit geänderten Inhalt, zwecks Datenschutz) oder schicken Sie mir diese unter [email protected]
          Vielleicht hilft das zum Verständnis weiter.

          Gruss Peter Wol

          Comment


          • #6
            Hallo Andreas,

            entweder gibt es ein Trennzeichen, oder eine festgelegte Länge, die dann auch genutzt werden muß?? Ich würde mir auch gerne die Beispieldatei ansehen: [email protected].

            Grüße Joche

            Comment


            • #7
              Hallo nochmal,

              ich habe Deine Frage nochmal gelesen. Da steht, daß die Daten in der Datei eine feste Feldlänge haben. Also vermute ich den Fehler in Deiner Einlesesroutine. Da Du die aber nicht gepostet hast (was mir eh nichst so viel nützen würde: BCB-ler), möchte ich den Weg über eine TStringList nochmal vorschlagen. Lies die Daten in eine selbige und arbeite sie zeilenweise ab. Wenn Du (zumindest temporär) einen AnsiString verwendest, kannst Du die Leerzeichen mit dem Befehl Trim() oder TrimRight entfernen. Beispiel zum Einlesen des Namens:

              Gegeben sei:<BR>
              TStringList slTemp<BR>
              AnsiString asTemp<BR>

              <PRE>
              asTemp := slTemp.Strings[zeilennummer].SubString(1,50) // Zeichen 1-50 auslesen -> Name
              Name := asTemp.TrimRight(); // überflüssige Leerzeichen rechts entfernen
              asTemp := slTemp.Strings[zeilennummer].SubString(51,18); // Zeichen 51-69 auslesen -> Vorname
              Vorname := asTemp.TrimRight();
              </PRE>

              Fehlt noch das Einlesen der anderen Variablen. Das Ganze dann noch in eine Schleife gesetzt - fertig.

              Grüße Jochen

              P.S. Wie schon angedeutet, stamme ich aus dem C++ Lager, falls der 'Delphi-Code' also Fehler enthält... :

              Comment


              • #8
                Hallo Andreas,

                ich habe die Beispieldaten erhalten. Funktioniert einwandfrei unter Verwendung eine TStringList...

                Grüße Joche

                Comment


                • #9
                  Hallo Andreas,

                  ich kann mich Jochen nur anschliessen. Die Funktion TrimRight und TrimLeft kannte ich allerdings noch nicht. Wieder etwas gelernt.

                  Gruss Peter Wol

                  Comment


                  • #10
                    Hallo zusammen,

                    solange die einzulesende Datei relativ klein ist, dann kann man den Weg über die StringList gehen. Dieser Weg hat den Vorteil das er sehr einfach zu coden ist. Sobald die Dateien aber größer werden (im MB Bereich), dann wird das ganze kriechend langsam.

                    In meinem Project von mir lese ich die betreffende Datei in einen Memory-Stream und suche im ersten Schritt in der Datei nach den Zeilenende-Zeichen und merke mir die Positionen. Wenn ausschließlich mit festen Datensatzlängen gearbeitet wird, dann könnte man sich das sparen. Das ganze wird von entsprechnd optimierten Assemblerroutinen erledigt.

                    Sobald die Infos vorliegen werden dann Zeilenweise die Daten ausgelesen. Das langsamste daran ist bei mir das Schreiben der Daten in die DB.

                    Gruß

                    Torste

                    Comment


                    • #11
                      Hallo Torsten,

                      das ist die Version für Fortgeschrittene. Da gehen wir nächstes Mal näher drauf ein.

                      Die Datei ist ziemlich klein. Hatte sie zum testen. Außerdem ist eine TStringList gar nicht so langsam, zumindest im Vergleich mit TRichEdit.

                      >Sobald die Dateien...

                      Dann würde ich das sowieso in einer richtigen DB speichern. Spart man sich den ganzen Verwaltungsoverhead.

                      Grüße Joche

                      Comment


                      • #12
                        Hallo Jochen,

                        &ltdas ist die Version für Fortgeschrittene. Da gehen wir nächstes Mal näher drauf ein. &gl

                        Da haste wohl Recht. In meiner alten Firma hatten alle ziemlichen Respekt vor der damals bestehenden Implementierung der Schnittstelle (mich eingeschlosssen). Irgendwann mußte dann aber eine Erweiterung vorgenommen werden. Über den Mist den ich da zu sehen bekommen habe, ist mir bald schlecht geworden (ein Wunder das das jemals funktioniert hat). Dadurch das die Schnittstelle frei konfigurierbar war (feste Feldlänge, Feldtrenner, Feldreihenfolge usw.) ist automatisch eine wesentlich höhere Komplexität gegeben.

                        Gruß

                        Torste

                        Comment


                        • #13
                          Hallo Torsten,

                          <I>ist automatisch eine wesentlich höhere Komplexität gegeben.</I>

                          Sozusagen eine Eierlegende Wollmilchsau. Bedeutet immer ernormen Aufwand. Sowas habe ich mir abgewöhnt. Notfalls tut es immer noch die gute alte Paradox DB. Da muß man zwar mit ein paar Problemen rechnen, aber der Implementierungs- und Pflegeaufwand ist doch deutlich geringer = Zeitersparnis = Kostenersparnis = glückliche Geschäftsleitung.

                          Grüße Joche

                          Comment


                          • #14
                            Hallo Jochen,

                            aber was will man machen, wenn es diese Funktionalität schon Jahrelang gibt und die Kunden damit arbeiten.

                            Außerdem brauchten wir eine flexible Schnittstellenanbindung an externe Warenwirtschaftssysteme.

                            Funktioniert hat es erstaunlicher Weise ja sogar. Nur Anpassungen/Erweiterungen waren extrem kompliziert und Fehlerträchtig. Naja mittlerweile läuft eh der Antrag auf Eröffnung des Insolvenzverfahren.

                            Zum Glück geht mich das nicht mehr viel an.

                            Gruß

                            Torste

                            Comment


                            • #15
                              Hallo Torsten,

                              in dem Fall muß man dann wohl da durch. Aber eben wegen dem immensen Aufwand bei der Pflege und der hohen Fehlerträchtigkeitig, sollte man solchen Lösungen nur dann einsetzen wenn es unumgänglich ist.

                              Hier ging es um eine kleine Telefonliste, knapp 300 kB groß. Ich hätte das trotzdem über eine Tabelle gemacht: keine Leseroutine nötig, keine Schreibroutine nötig, kein Verwaltungsaufwand für die Objekte nötig, keine eigene Such-, Filter- und Sortierroutine notwendig, keine eigene Doublettenerkennung nötig usw... Datenbanken können das alles 'ab Werk'. Und so schwer ist SQL dann auch wieder nicht.

                              Ich finde TStringList immer noch nicht langsam. Anzahl Elemente in der Datei: 1203, Dauer zum Einlesen ca. 30 ms. Das Gleiche mit einem TRichEdit dauert dann schon ca. 900 ms. Verwechselt Du das vielleicht?

                              Grüße Joche

                              Comment

                              Working...
                              X