Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Stringlist (https://www.delphipraxis.net/107978-stringlist.html)

manfred_h 5. Feb 2008 18:45


Stringlist
 
Hallo zusammen

habe da ein kleines Probelm.
Folgende Zeile aus einer DB muss ich aufteilen um sie danach zerteilt in einer anderen Tabelle zu speichern.
> AK SH 36 VA DV EZ
Es können bis zu 12 Werte sein die mit einem Leerzeichen voneinander getrennt sind.
Kann aber auch vorkommen das nur ein Wert drin ist.

mit folgendem Code kann ich die Zeile zwar einlesen wenn alles ausgefüllt ist aber erhalte
Fehlermeldungen wenn Werte fehlen.

Wie kann ich überprüfen wieviele Werte im String vorhanden sind?

Delphi-Quellcode:
        begin
          input := udm.t_SVADR.FieldByName('ART').AsString;
          sl := TStringList.Create; // StringList erstellen
          sl.Delimiter := ' ';      // Trennzeichen einstellen
          sl.DelimitedText := input;
          try
            FieldByName('ART_1').AsString := (sl[0]);
            FieldByName('ART_2').AsString := (sl[1]);
            FieldByName('ART_3').AsString := (sl[2]);
            FieldByName('ART_4').AsString := (sl[3]);
            FieldByName('ART_5').AsString := (sl[4]);
            FieldByName('ART_6').AsString := (sl[5]);
            FieldByName('ART_7').AsString := (sl[6]);
            FieldByName('ART_8').AsString := (sl[7]);
            FieldByName('ART_9').AsString := (sl[8]);
            FieldByName('ART_10').AsString := (sl[9]);
            FieldByName('ART_11').AsString := (sl[10]);
            FieldByName('ART_12').AsString := (sl[11]);
          finally
            sl.Free; // Speicher freigeben
          end;
Shalom
Manfred


[edit=Matze]Tippfehler im Titel korrigiert. MfG, Matze[/edit]

Klaus01 5. Feb 2008 18:48

Re: Strinlist
 
Hallo,

mit sl.count findest Du heraus wieviele Zeilen die StringList hat.

Grüße
Klaus

Matze 5. Feb 2008 18:49

Re: Strinlist
 
Hallo,

die Anzahl der Strings erhälst du mit

Delphi-Quellcode:
sl.Count;
An deiner Stelle würde ich dies mit einer Schleife lösen, in der du die einzelnen Zeilen/Strings verarbeiten kannst:

Delphi-Quellcode:
for i := 0 to sl.Count - 1 do
begin
  // ...
end;

marabu 5. Feb 2008 19:04

Re: Strinlist
 
Hallo Manfred,

eventuell ist es besser, wenn du die Werte nicht vereinzelst - deine Tabelle verliert durch die Wiederholungs-Feldgruppe ART_nn ihre Normalform. Wie groß ist denn der Wertevorrat für die Codes? Gibt es da insgesamt nur 12 Werte oder können maximal 12 zugeordnet werden? Tauchen diese Werte als Schlüssel in einer anderen Tabelle auf? Wieviele Datensätze hat die gezeigte Tabelle?

Freundliche Grüße

manfred_h 5. Feb 2008 19:16

Re: Strinlist
 
Hallo zusammmen
Hallo Marabu

Zitat:

Wie groß ist denn der Wertevorrat für die Codes?
Es können Maximal 12 Werte zugeordnet werden.

Zitat:

Tauchen diese Werte als Schlüssel in einer anderen Tabelle auf?
Nein ( Danke für den Tipp )

Zitat:

Wieviele Datensätze hat die gezeigte Tabelle?
Ca. 300

habe nun ein wenig rumgeteset:

Delphi-Quellcode:
        begin
          input := udm.t_SVADR.FieldByName('ART').AsString;
          sl := TStringList.Create; // StringList erstellen
          sl.Delimiter := ' ';      // Trennzeichen einstellen
          sl.DelimitedText := input;
          for anz := 0 to sl.Count -1 do
          try
            FieldByName('ART_0').AsString := (sl[anz]);
            FieldByName('ART_1').AsString := (sl[anz]);
            FieldByName('ART_2').AsString := (sl[anz]);
            FieldByName('ART_3').AsString := (sl[anz]);
            FieldByName('ART_4').AsString := (sl[anz]);
            FieldByName('ART_5').AsString := (sl[anz]);
            FieldByName('ART_6').AsString := (sl[anz]);
            FieldByName('ART_7').AsString := (sl[anz]);
            FieldByName('ART_8').AsString := (sl[anz]);
            FieldByName('ART_9').AsString := (sl[anz]);
            FieldByName('ART_10').AsString := (sl[anz]);
            FieldByName('ART_11').AsString := (sl[anz]);
          finally
          end;
( i kann ich hier nicht als variable nehmen da diese schon verwendet wird. )

Im Moment wird überall jeweils der erste Wert den er aus dem string list verwendet.
Das Problem sehe ich > (sl[anz]) ist ja überall gleich. Aber wie kann ich das ändern?
Danke für Eure Hilfe

Matze 5. Feb 2008 19:31

Re: Strinlist
 
Zitat:

Zitat von manfred_h
Im Moment wird überall jeweils der erste Wert den er aus dem string list verwendet.
Das Problem sehe ich > (sl[anz]) ist ja überall gleich. Aber wie kann ich das ändern?
Danke für Eure Hilfe

So:

Delphi-Quellcode:
for anz := 0 to sl.Count -1 do
begin
   FieldByName('ART_' + IntToStr(i)).AsString := sl[i];
end;

marabu 5. Feb 2008 20:23

Re: Strinlist
 
Bei nur zwölf möglichen Werten ist es vorteilhafter jedem Wert ein Feld zu spendieren - das vereinfacht Auswertungen kollosal.

Delphi-Quellcode:
with TStringList.Create do
try
  CommaText := udm.t_SVADR.FieldByName('ART').AsString;
  for i := 0 to Pred(Count) do
    FieldByName('ART_' + Strings[i).AsBoolean := True;
finally
  Free;
end;
Gute Nacht

manfred_h 6. Feb 2008 09:29

Re: Strinlist
 
Das einfüfen klappt nun :wink: Dank Eurer Hilfe.

Einzig ein Problem besteht noch:
z.T sind im String nicht alle "Felder" belegt z.B.
PA BS 10 VA EZ EZ
Hierbei wird der letzte EZ Wert direkt in das 6te Feld eingetragen anstatt in das 12te.
Zwischen den EZ Werten sind Leerschläge.
PA BS 10 VA EZ...................EZ

:gruebel:

marabu 6. Feb 2008 09:47

Re: Strinlist
 
Hallo,

dann musst du eine Übersetzung vorsehen:

Delphi-Quellcode:
with TStringList.Create do
try
  CommaText := udm.t_SVADR.FieldByName('ART').AsString;
  for i := 0 to Pred(Count) do
    FieldByName('ART_' + IntToStr(Succ(AnsiIndexText(Strings[i], [
      'AK', 'SH', '36', 'VA', 'DV', 'EZ' { ... }
    ])))).AsBoolean := True;
finally
  Free;
end;
Aber warum willst du das Feld ART_12 nennen und nicht ART_EZ?

Freundliche Grüße

manfred_h 6. Feb 2008 09:58

Re: Strinlist
 
Danke für Deinen Tipp. Werde das gleich versuchen. :thumb:

Zitat:

Zitat von marabu
Aber warum willst du das Feld ART_12 nennen und nicht ART_EZ?

Es kann auch ein anderer Wert als EZ im Feld sein.

Danke schon mal
Manfred

manfred_h 6. Feb 2008 14:45

Re: Strinlist
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von marabu
Delphi-Quellcode:
with TStringList.Create do
try
  CommaText := udm.t_SVADR.FieldByName('ART').AsString;
  for i := 0 to Pred(Count) do
    FieldByName('ART_' + IntToStr(Succ(AnsiIndexText(Strings[i], [
      'AK', 'SH', '36', 'VA', 'DV', 'EZ' { ... }
    ])))).AsBoolean := True;
finally
  Free;
end;

Hallo Marabu
leider komme ich nicht ganz klar mit Deinem Codebeispiel ( bin mir sicher das es für Dich absolut logisch ist ).
Die Werte PA BS 10 VA EZ...................EZ können völlg verschieden sein.
Das einzig feste ist das immer 2 Werte von einem Leerzeichen unterbochen werden. "Leerwerte" also nur 2 Leerzeichen die von einem Leerzeichen "getrennt" werden bestehen leider auch. ( Siehe Anhang )
Besteht eine Möglichkeit die Positionen anzusprechen ( bin schon die ganze Zeit in der Online-Suche ).

Danke für Eure Tipps
Manfred

marabu 6. Feb 2008 18:25

Re: Strinlist
 
Hallo Manfred,

vielleicht ist dir hiermit eher geholfen:

Delphi-Quellcode:
var
  i, iPos: Integer; // EDIT
  art, s: string;
begin
  // ...
  with := udm.t_SVADR do
  begin
    art := := FieldByName('ART').AsString;
    for i := 1 to 12 do
    begin
      iPos := Succ(Pred(i) * 3); // EDIT
      s := Trim(Copy(art, iPos, 2));
      if s = ''
        then FieldByName('ART_' + IntToStr(i)).Clear
        else FieldByName('ART_' + IntToStr(i)).AsString := s;
    end;
  end;
end;
Freundliche Grüße

manfred_h 7. Feb 2008 16:47

Re: Stringlist
 
Hallo Marabu

bin am experimentieren mit dem Code den ich von Dir erhalten habe.
An einem Punkt komme ich nicht ganz klar.

Habe das ganze bis jetzt wie folgt angepasst:

Delphi-Quellcode:
         begin
          // ...
          with fib_ds_svadr do
          begin
            art := FieldByName('ART').AsString;
            for anz := 1 to 12 do
            begin
              s := Trim(Copy(art, iPos ,2));
              if s = ''
                then FieldByName('ART_' + IntToStr(anz)).Clear
                else FieldByName('ART_' + IntToStr(anz)).AsString := s;
            end;
          end;
        end;
mit dieser Zeile habe ich Probleme:
Delphi-Quellcode:
s := Trim(Copy(art, iPos ,2));
Was ist iPos ?? habe schon mit Pos rumgetestet aber leider ohne den gewünschten Erfolg.
Hast Du hier noch einen Tipp. :oops:
( i habe ich durch anz ersetzt weil i schon verwendet wird )

Grüsse aus Basel
Manfred

shmia 7. Feb 2008 16:50

Re: Stringlist
 
Ihr macht das alle viel zu kompliziert!
Delphi-Quellcode:
sl := TStringList.Create; // StringList erstellen
sl.Delimiter := ' ';      // Trennzeichen einstellen
sl.DelimitedText := input;
while sl.Count < 12 do sl.Add(''); // <= der TRICK !!

marabu 7. Feb 2008 17:29

Re: Stringlist
 
Hallo Manfred,

eine wichtige Zeile habe ich offensichtlich vergessen hinzuschreiben:

Delphi-Quellcode:
for anz := 1 to 12 do
begin
  iPos := Succ(Pred(i) * 3); // Startposition im Gesamtstring
  s := Trim(Copy(art, iPos , 2));
  // ...
end;
Freundliche Grüße

peschai 8. Feb 2008 05:33

Re: Stringlist
 
In Ergänzung:

Du machts etwas ungewöhnliches, was mich interessiert ...
-> Du verwendest extra ein Leerzeichen als Trenner
Du solltest nun wissen, daß das Leerzeichen automatisch als Trenner betrachtet wird weann StrictDelimiter auf False steht, was Standard ist .... (Kommt da etwas durcheinenander wenn du auch ein Leerzeichen als Trenner benutzt ?) Also mit Delimiter=";" macht DelimitedText auch bei " " neue Lines... "A;B;C D E" führt zu den Zeilen "A","B","C","D","E"

Vielleicht kannst du dein Problem mit der sechsten Stelle anstell erwartet 12 aufgrund der Leerzeichen damit lösen, daß du StrictDelimiter auf True setzt ?

marabu 8. Feb 2008 05:51

Re: Stringlist
 
Moin,

soweit ich Manfred verstanden habe, steht ein String im fixed format zur Verfügung - die Trennzeichen dienen lediglich der Optik. Insbesondere werden nicht besetzte Positionen ebenfalls durch Leerstellen gekennzeichnet.

Code:
....+....0....+....2....+....3....+
PA BS 10 VA EZ                  EZ
Ansonsten würde ich für die Zerlegung die Eigenschaft CommaText verwenden, wie ich es bereits in Beitrag #7 gezeigt habe. Sie leistet ebenfalls die Zerlegung an Leerstellen und steht in allen Delphi-Versionen zur Verfügung, im Gegensatz zu StrictDelimiter und DelimitedText.

Freundliche Grüße

manfred_h 8. Feb 2008 09:26

Re: Stringlist
 
ES läuft !! :coder: :cheer:

Besten Dank für Eure Tipps und speziell Dir Marabu!! :balloon:

Delphi-Quellcode:
begin
with fib_ds_svadr do
begin
  art := FieldByName('ART').AsString;
  for anz := 1 to 12 do
  begin
    iPos := Succ(Pred(anz) * 3); // Startposition im Gesamtstring
    s := Trim(Copy(art, iPos , 2));
    if s = ''
      then FieldByName('ART_' + IntToStr(anz)).Clear
      else FieldByName('ART_' + IntToStr(anz)).AsString := s;
  end;
end;
end;
( i habe ich durch anz ersetzt weil i schon verwendet wird )

Shalom
Manfred


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:24 Uhr.

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