Struktur / ForEach

Anfängerfragen zum Programmieren mit PureBasic.
TheSaint
Beiträge: 143
Registriert: 21.12.2008 18:59

Struktur / ForEach

Beitrag von TheSaint »

Hallo Zusammen und ein Frohes Neues Jahr,

leider habe ich auch im neuen Jahr wieder viele Fragen. :lol:
Folgende Struktur habe ich:

Code: Alles auswählen

;-***** Structuren definieren
Structure structTab
  lId.l
  sName.s
EndStructure

Structure structZellinh
  lId.l
  lZeile.l
  lSpalte.l
  sSpaltenName.s
  sZelleninh.s
EndStructure

Structure structZeile
  lId.l
  lZeile.l
  qStringHash.q
EndStructure
;***** Structuren definieren Ende

Global NewList DB2Tab.structTab()
Global NewList DB2Zellinh.structZellinh()
Global NewList DB2Zeile.structZeile()

Jetzt habe ich zu folgendem Code eine Frage:

Code: Alles auswählen

ResetList(DB2Zeile())

ForEach DB2Zeile()
  Debug "InBearbeitung: " + DB2Tab()\sName + " | "+ DB2Zellinh()\sSpaltenName
  Debug "List = " + Str(DB2Zeile())
  If DB2Zeile()\lId = 56
    CallDebugger
  EndIf
Next
Warum bekomme ich in der Zeile:

Code: Alles auswählen

 Debug "InBearbeitung: " + DB2Tab()\sName + " | "+ DB2Zellinh()\sSpaltenName 
immer nur die letzte gespeicherte Information angezeigt??
aber nicht die gerade aktuelle und in Bearbeitung befindliche Info?

Könnte mir jemand erklären, was ich hier noch machen muss,
damit es funktioniert?

Vielen Dank und viele Grüße
Little John

Beitrag von Little John »

Der Grund ist, das Du mit

Code: Alles auswählen

ForEach DB2Zeile()
eben nur die Liste DB2Zeile() durchläufst, und nicht die beiden anderen Listen.
Die drei Listen sind ja nicht irgendwie unsichtbar synchronisiert oder sowas. :-)
Daher bleibt in den Listen DB2Tab() und DB2Zellinh() jeweils die ganze Zeit das selbe Elemente aktuell.

Gruß, Little John
TheSaint
Beiträge: 143
Registriert: 21.12.2008 18:59

Beitrag von TheSaint »

Hallo Little John,

wünsche Dir ein Frohes Neues Jahr.

Also, wenn ich das richtig verstehe, müsste ich den Code so
ergänzen:

Code: Alles auswählen

ForEach DB2Tab()
  ForEach DB2Zellinh()
    ForEach DB2Zeile() 
      Debug "InBearbeitung: " + DB2Tab()\sName + " | "+ DB2Zellinh()\sSpaltenName 
damit ich auf alle Informationen zugreifen kann???

Hm, kann man das auch anders gestalten??

Viele Grüße
Benutzeravatar
jear
Beiträge: 288
Registriert: 17.10.2004 01:59
Wohnort: Ammerland

Beitrag von jear »

@TheSaint

Nee, das wird noch doller. Nun durchläuft das Ganze die Schleifen n1 * n2 * n3 mal und es ändern sich immer nur die Angaben aus der Liste, deren Index sich gerade ändert.

Für Dein Problem gibt es verschiedene Lösungen, je nach Anforderungen.

Wenn alle 3 Listen genau die gleiche Anzahl Mitglieder haben und die zusammengehörenden Informationen unter dem jeweils gleichen Listenindex liegen, dann kannst Du auch mit dem Listenindex einer der Listen in die anderen Listen greifen.

etwa so:

Code: Alles auswählen

ForEach Liste1()
  ix = ListIndex(Liste1())
  SelectElement(Liste2(), ix) : SelectElement(Liste3(), ix)
  ; nun stehen alle 3 Listen "parallel" und man kann die Strukturfelder auslesen
Next
Es fragt sich dann aber, warum nicht nur eine Liste mit den drei Strukturen?

Wenn die Listen nicht auf diese Art "parallel" organisiert sind, kann man sie sowieso nur nacheinander auslesen.

Gibt es Ordnungsmerkmale, die den Zusammenhang zwischen bestimmten Mitgliedern definieren, dann muss man die Listen immer wieder nach diesen Merkmalen durchsuchen oder aber von vornherein eine weitere Liste der Indizes anlegen, die diese Zusammenhänge beschreiben.
Man ist nie zu alt zum lernen, auch wenn man dabei manchmal alt aussieht!
Little John

Beitrag von Little John »

TheSaint hat geschrieben:Hallo Little John,

wünsche Dir ein Frohes Neues Jahr.
Danke, das wünsche ich Dir -- und allen anderen hier -- auch!
TheSaint hat geschrieben:Also, wenn ich das richtig verstehe, müsste ich den Code so
ergänzen:

Code: Alles auswählen

ForEach DB2Tab()
  ForEach DB2Zellinh()
    ForEach DB2Zeile() 
      Debug "InBearbeitung: " + DB2Tab()\sName + " | "+ DB2Zellinh()\sSpaltenName 
damit ich auf alle Informationen zugreifen kann???

Hm, kann man das auch anders gestalten??

Viele Grüße
Es hängt davon ab, wie die Daten in den 3 Listen inhaltlich zusammengehören, und was Du überhaupt bezweckst.
Soll nur jedes Element in jeder Liste 1x angezeigt werden? Das macht der obige Code nicht. Angenommen, zu dem Zeitpunkt wo der Code abläuft habe die Liste DB2Tab() 100 Elemente, und die Liste DB2Zellinh() 70 Elemente: Dann wird jedes Element von DB2Zellinh() 100 mal aufgerufen, und jedes Element von DB2Zeile() 100*70 = 7000 mal. Abgesehen von der Frage, ob das tatsächlich beabsichtigt ist, kommt so schnell eine große Anzahl von Schleifendurchläufen zustande, was entspr. viel Zeit benötigt.

Am besten beschreibst Du mal (möglichst kurz und präzise) in Worten, nicht mit Code, was Dein Programm eigentlich machen soll.

Gruß, Little John
TheSaint
Beiträge: 143
Registriert: 21.12.2008 18:59

Beitrag von TheSaint »

Hallo jear,
hallo Little John,

vielen Dank für Eure Antworten.

Hm, dann versuche ich mal zu beschreiben, was ich mache:

Ich vergleiche zwei Datenbanken miteinander.
Zelle für Zelle, ob sich etwas verändert hat und was sich verändert hat.

lId.l = beinhaltet die Tabellen-Nr

in allen LinkedList der ersten Datenbank
Global NewList DB1Tab.structTab()
Global NewList DB1Zellinh.structZellinh()
Global NewList DB1Zeile.structZeile()

als auch in der zweiten datenbank
Global NewList DB2Tab.structTab()
Global NewList DB2Zellinh.structZellinh()
Global NewList DB2Zeile.structZeile()

Code: Alles auswählen

ForEach DB2Zeile()
         Debug "InBearbeitung: " + DB2Tab()\sName + " | "+ DB2Zellinh()\sSpaltenName+ " | "+ Str(DB2Zeile()\lZeile)
  ForEach DB1Zeile()
     If DB2Zeile()\qStringHash=DB1Zeile()\qStringHash
       lx.l = 1
       Break
     EndIf
  Next
  If lx = 1
    Debug "Datensatz vorhanden: " + DB2Tab()\sName +". "+ DB2Zellinh()\sSpaltenName +" und identisch"
      else
        Debug "Datensatz nicht vorhanden: " + DB2Tab()\sName +". "+ DB2Zellinh()\sSpaltenName +" und nicht identisch"
  endif
Next
Um jede Zelle in einer Tabelle zu vergleichen, habe ich oben aufgeführte Struktur verwendet. Wenn es jedoch eine einfachere oder bessere Lösung dafür gibt, wäre ich sehr über eine Hilfestellung dankbar.

Aber das Ziel ist es, jede Zelle in einer Zeile in der entsprechenden Tabelle der beiden Datenbanken zu vergleichen.

Ich hoffe ich konnte es verständlich erläutern???

Schon mal vielen Dank für Eure Geduld und Hilfe.

Viele Grüße
Little John

Beitrag von Little John »

Eine Datenbank besteht ja zunächst einmal aus einer (oder mehreren) Datei(en) auf der Festplate. Die Verarbeitung der Daten hängt entscheidend davon ab, in welche Datenstrukturen sie aus der Datei eingelesen werden. Du möchtest verknüpfte Listen verwenden, aber die genaue Art und Weise wie Du sie einsetzen willst ist mir nicht ganz klar, und die dazu verwendeten Strukturen scheinen mir nicht sinnvoll zu sein. So würde ich beispielsweise nicht in jedem structZellinh-Listenelement <sSpaltenName.s> speichern. Das ist eine (möglicherweise beträchtliche) Verschwendung von Platz im Arbeitsspeicher. Auch sieht es mir so aus, als ob in der Liste DB1Zellinh.structZellinh() ( bzw. DB2Zellinh.structZellinh() ) alle Feldinhalte einer Tabelle der betr. Datenbank gespeichert werden sollen. Ich weiß nicht, ob das sinnvoll ist.

Am einfachsten ist es, wenn immer die gleiche Datenbank bearbeitet werden soll, deren Aufbau sich nicht ändert. Dann braucht man nur eine Struktur, diese nimmt einen Datensatz (Zeile) auf, z.B.

Code: Alles auswählen

;-- Listen definieren
Structure Adresse
   Id.i
   Nachname.s
   Vorname.s
   PLZ.i
   Ort.s
   Strasse.s
EndStructure

NewList Db1.Adresse()
NewList Db2.Adresse()


;-- Daten aus Datei(en) in die beiden Listen einlesen
; ...


;-- Listen vergleichen
ForEach Db1()
   ForEach Db2()
      ; Je nach Situation und Bedarf kann man hier die kompletten Datensätze vergleichen,
      ; oder auch Feld für Feld.
      ; Man kann bei einem gefundenen Unterschied diesen anzeigen und das Programm
      ; beenden, oder man kann alle Unterschiede im Arbeitsspeicher oder in einer Datei
      ; "sammeln".
   Next
Next
Dies ist absichtlich nur ein grobes Schema, um den "roten Faden" zu zeigen.

Wenn das Programm verschiedene Datenbanken verarbeiten können soll, der Datensatz-Aufbau also erst zur Laufzeit des Programms bekannt ist, dann wird das ganze komplzierter. Dann würde ich wahrscheinlich 2-dimensionale Arrays verwenden -- oder XML. Hast Du übrigens die Verwendung von PureBasics Database-Library in Betracht gezogen?

Gruß, Little John
TheSaint
Beiträge: 143
Registriert: 21.12.2008 18:59

Beitrag von TheSaint »

Hallo Little John,

danke für Deine Antwort.

Hm, leider komme ich nicht so richtig weiter.
Also die Datenbank besteht aus 160 Tabellen.
Diese Tabellen sind mit unterschiedlich vielen Zeilen und
Spalten versehen.
Der Aufbau der Datenbank steht fest und ändert sich nicht.
D.h., damit ich alle Tabellen und alle Zeilen und deren Inhalt mit der zweiten Datenbank auf Veränderungen vergleichen kann, muss ich diese doch in eine Struktur einlesen.
Deshalb habe ich die o. g. Struktur gewählt.
Hm, nur ich weis im moment nicht wie ich die Struktur auf
dein Beispiel abändern könnte, damit ich alle Daten einlesen kann.

Damit ich auf die Datenbank zugreifen kann und alle Tabellen auslesen kann, benutze ich PBOSL-ExDatabase. Meintest Du diese lib?

Irgendwie bin ich jetzt unschlüssig, was, wie ich weiter machen
könnte, sollte.

Schon mal vielen Dank.

Viele Grüße
TheSaint
Beiträge: 143
Registriert: 21.12.2008 18:59

Beitrag von TheSaint »

Hallo jear,

ich habe jedoch ein Problem daraus nur eine Struktur zu machen:
Wie kriege ich den nur in einer Struktur die ganzen Infos?

Die benötigten Inhalte aus der bzw. den Datenbanken sind:

Tabellen Name
Spalten Name
Zeilen Nr
Spalten Nr
Zellen Inhalt
Zeilen Inhalt
ZeilenHash (den ich als Vergleich für beide Datenbanken nutze).

Brauche doch getrennte Stukturen um alle Daten heraus zu holen,
oder? Wegen den SQL Abfragen denke ich...

Vielleicht könntest Du hier noch mal helfen.

Vielen Dank und viele Grüße
Little John

Beitrag von Little John »

TheSaint hat geschrieben:Damit ich auf die Datenbank zugreifen kann und alle Tabellen auslesen kann, benutze ich PBOSL-ExDatabase. Meintest Du diese lib?
Nein, ich meinte die Database-Library im Lieferumfang von PureBasic, siehe in der Hilfe "Referenz-Handbuch" > "Allgemeine Libraries" > "Database". PBOSL-ExDatabase kenne ich nicht, kann daher nichts dazu sagen.

Gruß, Little John
Antworten