Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   2 INI Dateien vergleichen (https://www.delphipraxis.net/169656-2-ini-dateien-vergleichen.html)

Dr. Jack 2. Aug 2012 18:01

2 INI Dateien vergleichen
 
Hallo zusammen,

ich habe 2 kleine Datenbanken (enthält Artikel und Bestände, Lagerorte etc...) als INI-Datei. Eine Lokale Datenbank L und eine Remote Datenbank R.

Ich möchte nun die 2 Datenbanken vergleichen, d.h. die Remote DB soll in der Lokalen DB nachsehen ob die Artikelnummer existiert. Wenn nicht soll sie aktualisiert werden, d.h. der Eintrag wird zugefügt. Und genau bei dieser Umsetzung komme ich nicht weiter.

Mein Ansatz, in dem ich 2 for to do schleifen einsetze funktioniert nicht, denn wenn die Artikelnummer in einer Datenbank mit 168 Einträgen schon existiert
tut er so als gibt es diese Artikelnummer 167x nicht aber 1x schon --> er legt also 167 neue Datensätze an? Hat wer eine Idee?

himitsu 2. Aug 2012 18:08

AW: 2 INI Dateien vergleichen
 
Doch, das mit der Schleife funktioniert schon, aber du mußt erst alles durchsehn (bei der inneren Prüf-Schleife), ob es das gibt
und danach kannst du dann entsprechend reagieren.
Vorher eine Variable setzen, bei Fund deren Status ändern und dann die Variable auswerten.

Sir Rufo 2. Aug 2012 18:11

AW: 2 INI Dateien vergleichen
 
Schau dir doch mal in der Online-Hilfe an, was Delphi-Referenz durchsuchenTIniFile so zur Verfügung stellt ;)

PS Die eigentliche Frage an die Ini-Datei ist ja: "Existiert der Eintrag xy schon?"

Dr. Jack 2. Aug 2012 18:32

AW: 2 INI Dateien vergleichen
 
ja genau die innere Schleife ist mein Problem:

sie geht gerade 168 Artikel durch

Bsp. die Artikelnummer 4711 soll gesucht werden

die innere Schleife sagt dann 167 x gibts nicht und 1x gibts doch.

wie lasse ich diese inner Schleife durch die gesamte Datei laufen bzw. setze eine
Finde-Variable?


Delphi-Quellcode:
    for L := 1 to strtoint(DB_Lokal_index_read) do
            begin  // pfad definieren
                    ini:=Tinifile.create(einstellungen.artikelreg);


                    DB_Lokal_artikelnummer:= ini.readstring(inttostr(L), 'artikelnummer', DB_Lokal_artikelnummer);
                    if (DB_Lokal_artikelnummer='-1')or (DB_Lokal_artikelnummer='') then DB_Lokal_artikelnummer:='0';
                      // nummern vergleichen
                    if    (RDB_artikelnummer=DB_Lokal_artikelnummer)
                    then  begin
                           break
                           end;

              end;

Sir Rufo 2. Aug 2012 18:42

AW: 2 INI Dateien vergleichen
 
Ok, der Wink mit dem Zaunpfahl war wohl zu wenig, jetzt halt mit dem ganzen Zaun wedeln:
Delphi-Referenz durchsuchenTIniFile.ValueExists

Dr. Jack 2. Aug 2012 21:47

AW: 2 INI Dateien vergleichen
 
ist ini.valueExists wirklich richtig?

meine ini-Datenbank ist so aufgebaut:

[1]
artikelnummer=4711
[2]
artikelnummer=01234567
[3]
artikelnummer=106

in den Beschreibungen steht, dass ValueExisis einen Schlüssel sucht,
also guckt er, ob "artikelnummer" existiert?
ich checks net...

DanielProgramming 2. Aug 2012 21:56

AW: 2 INI Dateien vergleichen
 
Ja valueExists prüft ob artikelnummer existiert, alternativ möchtest du vielleicht vorher per sectionExists prüfen ob [1], [2] oder [3] existieren.

Uwe Raabe 2. Aug 2012 22:03

AW: 2 INI Dateien vergleichen
 
Das funktioniert aber nur, wenn die Artikelnummern in beiden INI-Dateien auch immer in der gleichen Section stehen.

Wenn sowas vorkommt:

INI1:
Zitat:

[1]
artikelnummer=4711
[2]
artikelnummer=01234567
[3]
artikelnummer=106
INI2:
Zitat:

[1]
artikelnummer=4711
[2]
artikelnummer=106
[3]
artikelnummer=01234567
nutzt ValueExists leider nichts.

Dr. Jack 2. Aug 2012 22:30

AW: 2 INI Dateien vergleichen
 
Mein Problem ist in der "if then else" Abfrage folgendes:

if lokale_artilenummer=remote_artikelnummer
then break
--> ok funktioniert, wenn der Artikel existiert, dann keinen neuen Datensatz anlegen


aber im else Teil passiert folgendes:

er vergleicht wieder und stellt fest dass 4711 nicht 106 ist --> also würde er
4711 neu anlegen, weil er nicht weiß, dass der Artikel noch kommt

tabelle 1 tabelle 2
--------- ---------
4711 --> 106 ==> 4711 ungleich 106 -> neuen Datensatz anlgen
............. 4711
............. 01234567

ich hab keinen Plan wie ich das lösen soll, hat jemand dazu vielleicht einen Quellcode?

Bjoerk 2. Aug 2012 22:40

AW: 2 INI Dateien vergleichen
 
ReadSections

ReadSectionValues

Sir Rufo 2. Aug 2012 23:12

AW: 2 INI Dateien vergleichen
 
Abgesehen davon, dass ich die Struktur suboptimal finde und etwas an den Fähigkeiten einer Uni-Datei vorbeiorganisiert ist - und eine echte Datenbank (sei es auch Access) besser wäre - hier ein Lösungsansatz für dein Problem:

Du beschreibst eigentlich genau das Problem. Erst wenn das Element aus Tabelle A mit allen Elementen aus der Tabelle B verglichen wurde, kann man zuverlässig sagen, ob dieses Element in Tabelle B existiert oder eben nicht.

Code:
Für alle Artikel in Tabelle A -> ArtA

  FlagExistiert <- Falsch

  Für alle Artikel in Tabelle B -> ArtB
    Wenn ArtB = ArtA dann FlagExistiert <- Wahr
  Ende Für

  Wenn Nicht FlagExistiert dann
    ArtA in Tabelle B anlegen
  Ende Wenn

Ende Für

Uwe Raabe 3. Aug 2012 07:53

AW: 2 INI Dateien vergleichen
 
Da ich ja gestern Abend wohl schon arge Konzentrationsprobleme hatte, nun nochmal von vorn:
Delphi-Quellcode:
TInifile.ValueExists
bringt dir, wie du schon bemerkt hast, in diesem Fall gar nichts, da es lediglich prüft, ob in einem "Datensatz" ein "Feld" Artikelnummer existiert - das tut es aber immer.

Der Sir hat insofern auch Recht, daß die Verwendung einer INI-Datei als Datenbank in hohem Grade suboptimal ist, da sie dafür nicht gedacht ist. So gestaltet sich das Suchen nach Datensätzen mit bestimmten Feldinhalten als äußerst schwierig, wie wir hier alle feststellen können.

Mit der aktuellen Datenstruktur in den INI-Dateien bleibt nur ein verschachtelter Schleifendurchlauf, wie ihn Sir Rufo skizziert hat. Ich würde in der inneren Schleife allerdings noch ein Break einbauen, wenn der Datensatz gefunden wurde.

Um die Datenstruktur zu verbessern, könnte man die Sections nicht mit der Recordnummer versehen, sondern z.B. mit der Artikelnummer, die ja offensichtlich ein eindeutiger Schlüssel ist. So kann man einfach prüfen, ob eine Artikelnummer vorhanden ist:
Delphi-Quellcode:
TInifile.SectionExists
. Beim Löschen oder Umbenennen einer Artikelnummer muss dann allerdings die alte Section gelöscht werden:
Delphi-Quellcode:
TInifile.EraseSection
.

Aus Performancegründen würde sich auch die Verwendung von
Delphi-Quellcode:
TMemInifile
anbieten - vorausgesetzt, die Dateien sind nicht übergroß; aber dann wäre eh eine andere Lösung angebracht. Bei
Delphi-Quellcode:
TMemInifile
das
Delphi-Quellcode:
UpdateFile
nicht vergessen, um Änderungen auf die Platte zu schreiben.

Und ich habe aus diesem Thread auch was gelernt: Wenn jemand mit dem Zaun wedelt, pass auf, daß kein Brett vor deinem Kopf hängen bleibt.

Dr. Jack 3. Aug 2012 20:35

AW: 2 INI Dateien vergleichen
 
Ok danke für die Struktur und die sehr ausführlichen Hinweise, das werde ich nun versuchen umzusetzen.
Ich hoffe ihr seht mir die aus eurer Sicht einfachen Fragen nach :-)

Dr. Jack 3. Aug 2012 22:08

AW: 2 INI Dateien vergleichen
 
Tausend Dank, ich hab es... Die Flagvariable ist die Lösung.

(OK die INI-Datei ist wirklich suboptimal, aber sie schafft für das kleine Programm
ca. 70 Artikel/ Sekunde zu lesen :-) )

himitsu 4. Aug 2012 00:41

AW: 2 INI Dateien vergleichen
 
PS: INI über die WinAPI (da braucht man sich nicht wundern, daß diese veraltet und nur für kleine Daten ist) lädt die Datei nicht beim Create.
Und TIniFile kapselt nur die API.

Für jeden einzelnen Lesezugriff wird jedesmal die ganze Datei neu geladen, der Wert gesucht und alles wieder entladen.
Und noch schlimmer sind Schreibzugriffe, wo ebenfalls bei jedem Zugriff die Datei neu gelesen, der Wert verändert, alles zurückgeschrieben und entladen wird.

Bjoerk 4. Aug 2012 10:48

AW: 2 INI Dateien vergleichen
 
Die Vorgehensweise dürfe überhaupt relativ fehleranfällig sein. Was machst du denn z. B bei sowas:

Remotefile
[Section1]
Ident1 = 1234

DB
[Section1]
Ident1 = 5678

Angenommen, 1234 ist in der gesamten DB nicht vorhanden, soll also upgedatet werden, der Eintrag ist in der DB jedoch anderweitig vergeben!?

Dr. Jack 7. Aug 2012 23:53

AW: 2 INI Dateien vergleichen
 
@Bjoerk: Bei den "Nummern" handelt es sich um 8 bzw. 13 stellige EAN-Codes. Dass diese doppeltin meiner lokalen DB existieren halte ich für ausgeschlossen, andernfalls wird der Artikel einfach nicht angelegt.
Die Codes werden von der Gesellschaft GS1 verwaltet, diemachen das schon :-)
Ganz im Gegenteil, du hast teilweise, übertrieben formuliert für jeden Quatsch 5 unterschiedliche EAN-Codes.

@himitsu: Ja ich denke, der ganze Spaß sollte mal langsam in eine SQL-DB rein. Ab und zu fliegt mal eine access violation, ich glaube bei 350 Artikeln kein Wunder, oder?

Jumpy 8. Aug 2012 07:22

AW: 2 INI Dateien vergleichen
 
Irgendwie hätte es glaub ich auch Sinn gemacht, eine eigene Datenstruktur zu erfinden, wenn man den schon mit einer Textdatei arbeiten möchte. Aber wie auch immer: Eine SQL-DB ist wahrlich der einzig sinnvolle Weg, vor allem, wenn die Datenmenge noch größer wird und wenn man mal fortgeschrittenere Operationen auf der Datenmenge durchführen will.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:16 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