Feldinhalte aus DBF übernehmen

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2471
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Feldinhalte aus DBF übernehmen

Beitrag von Koverhage »

Hallo,

habe 2 DBF Dateien, Kunde.dbf und kdtemp.dbf.
Die Daten aus kdtemp sollen in kunde übernommen werden.
Bisher habe ich das immer pro Feld codiert, wenn das Feld in kdtemp
nicht vorhanden ist, wird es mit einem vordefinierten Wert belegt,
wie hier:
Local M_lename1 := iif( type( '("kdin")->lename1' ) = "U",space(30),("kdin")->lename1)
Das ist relativ aufwendig, zumal wenn Felder hinzugekommen sind und ich vergessen
habe diese dann in die entsprechende Importroutine aufzunehmen.

Wollte daher eine Routine schreiben, die alle Felder aus der Importdatei
übernimmt, sofern es ein Feld mit gleichem Namen in der Datenbank gibt.

Stehe aber irgendwie auf dem Schlauch mit Fieldget, Fieldput und fieldname
denn die Reihenfolge der Felder muss ja nicht gleich sein.

Kann mich mal jemand schubsen ?
Gruß
Klaus
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14659
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Jan »

Hallo Klaus,

kannst Du nicht die Struktur der alten Datenbank mit DbStruct() einlesen, und dieses Array dann Satz für Satz durchgehen? Dann hast Du jedes Feld drin, egal, was mal zwischendurch irgendwann geändert wurde.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21211
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Re: Feldinhalte aus DBF übernehmen

Beitrag von Manfred »

Hi Klaus,

wenn Du die Reihenfolge nicht weißt, dann wirst Du wohl um ein Fieldpos nicht herumkommen. Du kennst ja den Namen des Sourcefeldes und damit kannst Du dann in der Zieldatei nach der Platzierung suchen.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9387
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 362 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Tom »

IsFieldVar(<cName>) ermittelt, ob in der selektierten Workarea ein Feld mit dem Namen in "cName" existiert.
FieldPos(<cName>) ermittelt die Position des Feldes.
FieldGet(FieldPos(<cName>)) würde dann den Inhalt des Feldes ermitteln.
FieltPut(FieldPos(<cName>),<xInhalt>) würde den Inhalt von "xInhalt" in dieses Feld schreiben.

Damit hast Du alles nötige zur Verfügung. :wink:
Herzlich,
Tom
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16536
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 113 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Martin Altmann »

Moins,
es werden mit dem normalen APPEND FROM-Kommando eh' nur die Felder importiert, die in der Zieldatenbank vorhanden sind (mit gleichen Namen).

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2471
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Koverhage »

Martin,

so habe ich es früher gemacht, hatte aber diverse Probleme damit.

Hab mir das in etwa so vorgestellt:

use kunde alias out
use kdtemp alias in

Zunächst alle Sätze in out löschen die dem eingegebenen Kriterium entsprechen.

dann
("out")->(dbappend())

for i:=1 to ("in")->(fcount())
cfeldname := ("in")->(fieldname(i)
("out")->(cfeldname) := ("in")->(cfeldname)
next

unlock

so könnte ich kein Feld vergessen.
Leider funktioniert das Ganze nicht wie ich möchte.
Ich bekomme zwar den Feldnamen, aber die Werte werden nicht nach out übertragen.
Gruß
Klaus
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1931
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Rolf Ramacher »

Hi Klaus,

also du wirst mit diesem Verfahren über ein FieldGet und Fieldput() nicht hinwegkommen.
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: Feldinhalte aus DBF übernehmen

Beitrag von Günter Beyes »

Hallo Klaus,

am einfachsten geht's mit dem Makro-Operator.

Code: Alles auswählen

out->&cFeldname := in->&cFeldname
Gruß,
Günter
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von brandelh »

Hallo Klaus,

sowas habe ich vor einigen Tagen auch gemacht ;-) du must wissen, welche der DBFs bei den Felder führt.
Ich verstehe dich so, dass das IN ist, also die Datei mit den Inputwerten.
Meine Funktion arbeitet bestehende Datensätze ein, ich habe diese nun so umgewandelt, dass nur angehängt wird.
Du musst aber gut testen, ob sich kein Fehler eingeschliechen hat ;-)

Code: Alles auswählen

...
nFeldAnz := IN->(fcount())
aFieldPos := array(nFeldAnz)
for x := 1 to nFeldAnz
     aFieldPos[x] := OUT->(fieldPos( IN->(fieldName(x)) )) // wo steht das Feld
next
IN->(dbGoTop())
do while ! IN->(eof())
    OUT->(dbAppend())
    if neterr()
       Fehlermeldung ...
    endif
    for x := 1 to nFeldAnz // REPLACE
        if aFieldPos[x]>0 // was tun wenn es ein Feld nicht gibt ?
          OUT->(fieldPut(aFieldPos[x], IN->(fieldGet(x))))
        endif
    next
    IN->(dbSkip())
enddo
Falls die OUT Datei mehr Felder hat, werden diese automatisch auf einen BLANK Wert je nach Datentyp gesetzt,
das muss man nicht selbst machen, aber wenn andere Basiswerte gesetzt werden sollen, muss man das natürlich
noch einbauen.
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von brandelh »

Hi,

wenn du eine Meldung willst, welche Felder NICHT übernommen werden, da in OUT kein Feld existiert ...

Code: Alles auswählen

...
cFehlFeld := ""
nFeldAnz := IN->(fcount())
aFieldPos := array(nFeldAnz)
for x := 1 to nFeldAnz
   aFieldPos[x] := OUT->(fieldPos( IN->(fieldName(x)) )) // wo steht das Feld
   if aFieldPos[x]=0
     // Fehlermeldung je Feld ? oder wie hier einmalig danach
     cFehlFeld += ", "+IN->(fieldName(x))
   endif
next
if ! empty(cFehlFeld)
   msgbox("Folgende Felder werden nicht übernommen:"+chr(13)+substr(cFehlFeld,3),"Mehr Felder in Quelle")
endif
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2471
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Koverhage »

Hi,

habe mich für diesen Weg entschieden (Günters Methode).
Das ist sogar für mich fast verständlich ;-)

Was mir nicht so ganz klar ist:
Ich war bisher immer der Meinung man könnte den Macrooperator & nicht
mit lokalen Variablen verwenden. Abr in diesem Fall funktioniert das Ganze.
Warum?

Code: Alles auswählen

* --
STATIC PROCEDURE IMP_dbf(nFelder)
* --
Local cFeldname, i:=0
("out")->(DbAppend(1))    // bestehende Satzsperre bleibt erhalten
for i:=1 to nFelder
   cFeldname := ("in")->(fieldname(i))
   ("out")->&cFeldname := ("in")->&cFeldname
next
("out")->(DbrUnlock(recno()))
("out")->(dbskip(0))
RETURN
Gruß
Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von brandelh »

Hallo,

dein Code hat aber 2 eventuelle Probleme !

1. Wenn in IN ein Feld vorkommt, das in OUT fehlt, dann krachts.
2. Durch die Macrozeile dürfte der Code langsamer sein, als meiner, was aber erst bei großen Dateien eine Rolle spielt (probiert habe ich es nicht ;-) )

wie immer muss ich die Schreibweise ("IN")-> kritisieren (ich kann nicht anders), das ist unnötig !
Wenn du wie hier einen fixen Alias verwendest, dann schreib sollte man den auch direkt
verwenden IN-> der Compiler muss genau dies sonst jede Zeile tun.
->&cFeldname kann je nach Inhalt zu Problemen führen, daher ist es hier besser ->&(cFeldname) zu verwenden.

Und genau aus dem letzten Grund funktioniert das auch, zur Laufzeit wird die Variable
cFeldname nicht mehr angesprochen sondern nur die Speicherstelle wo der Inhalt liegt.
Solange du nur den Inhalt einer Variablen willst, funktioniert & mit local und private.
Nur wenn du die Variable selbst im String angibst, so z.B.:
&("field->Name == alltrim(cSuchName)")
dann geht das nur wenn cSuchName eine Private ist, wobei natürlich das besser ist:
&("field->Name == "+alltrim(cSuchName)+")"
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9387
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 103 Mal
Danksagung erhalten: 362 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Tom »

Innerhalb von Variablen, die mit dem Makrooperator untersucht werden, dürfen keine LOCALs enthalten sein. Die Variablen selbst können LOCAL sein.

Code: Alles auswählen

LOCAL cTest := "Date()", cTest2 := "cTest"

? &cTest -> Datum
? &cTest2 -> kracht, weil "cTest" LOCAL ist. Wäre es PRIVATE, würde diese Zeile mit "Date()" antworten
Herzlich,
Tom
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2471
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Feldinhalte aus DBF übernehmen

Beitrag von Koverhage »

Hallo Hubert,

in out kann das Feld nur theoretisch fehlen. Warum ich das so machen möchte, ist ja der Grund das ich kein Feld
aus in vergessen kann.

Das ("in") kommt daher weil ich mal das C/S System von Phil Ide einsetzen wollte.

Die Geschwindigkeit ist für mich subjektiv betrachtet ausreichend.
Gruß
Klaus
Antworten