Feldinhalte aus DBF übernehmen
Moderator: Moderatoren
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Feldinhalte aus DBF übernehmen
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 ?
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
Klaus
- Jan
- Marvin
- Beiträge: 14662
- 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
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
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.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
- Manfred
- Foren-Administrator
- Beiträge: 21248
- Registriert: Di, 29. Nov 2005 16:58
- Wohnort: Kreis Wesel
- Hat sich bedankt: 211 Mal
- Danksagung erhalten: 71 Mal
Re: Feldinhalte aus DBF übernehmen
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.
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!!
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!!
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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.
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.
Herzlich,
Tom
Tom
- Martin Altmann
- Foren-Administrator
- Beiträge: 16586
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 116 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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
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
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.
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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.
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
Klaus
- Rolf Ramacher
- 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
Hi Klaus,
also du wirst mit diesem Verfahren über ein FieldGet und Fieldput() nicht hinwegkommen.
also du wirst mit diesem Verfahren über ein FieldGet und Fieldput() nicht hinwegkommen.
-
- Rekursionen-Architekt
- Beiträge: 315
- Registriert: Mo, 16. Okt 2006 13:04
- Wohnort: Region Stuttgart
Re: Feldinhalte aus DBF übernehmen
Hallo Klaus,
am einfachsten geht's mit dem Makro-Operator.
Gruß,
Günter
am einfachsten geht's mit dem Makro-Operator.
Code: Alles auswählen
out->&cFeldname := in->&cFeldname
Günter
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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
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.
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
das muss man nicht selbst machen, aber wenn andere Basiswerte gesetzt werden sollen, muss man das natürlich
noch einbauen.
Gruß
Hubert
Hubert
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
Hi,
wenn du eine Meldung willst, welche Felder NICHT übernommen werden, da in OUT kein Feld existiert ...
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
Hubert
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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?
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
Klaus
- brandelh
- Foren-Moderator
- Beiträge: 15710
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 73 Mal
- Danksagung erhalten: 38 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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)+")"
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
Hubert
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 105 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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
Tom
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2471
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Feldinhalte aus DBF übernehmen
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.
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
Klaus