dcbrowse mit Datumsfeld [erledigt]

Moderator: Moderatoren

Antworten
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

dcbrowse mit Datumsfeld [erledigt]

Beitrag von Ewald »

Ich habe zum Thema Browser dieses Problem.
Wenn ich in das Programm in das erste Feld (Field-Variante) ein Datum eintrage, funktioniert das wie erwartet.
Trägt man in das 2 Feld ein Datum ein, poppt EXPRESS die Fehlermeldung "INVALID DATE ENTERED" auf, wenn das Feld leer war.
Stand schon ein Datum drin, passiert nichts.
Hat jemand eine Idee, woran das liegt ?

Code: Alles auswählen

#include "appevent.ch"
#include "dcdialog.ch"

proc main
set date germ
use bladbf excl new     // irgendeine DBF mit einem Datumsfeld
calias:=alias()
@ 0,0 dcbrowse obrowse alias calias size 30,10 edit xbeBRW_ItemSelected

dcbrowsecol field (calias)->datum    heading "Datum " parent obrowse width 6
dcbrowsecol data {||(calias)->datum} heading "Datum " parent obrowse width 6

dcread gui fit

close (calias)

return
Zuletzt geändert von Ewald am Sa, 30. Mai 2009 15:40, insgesamt 1-mal geändert.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Hallo, Ewald.

Ein Browse, das gleichzeitig das Editieren der Feldinhalte zulässt, ist NUR mit "DCBROWSECOL FIELD" möglich. Bei Übergabe eines Codeblocks, der ja alles mögliche enthalten kann (z.B. auch die Auswertung mehrerer Felder), ist das System schlicht und ergreifend (und verständlicherweise) damit überfordert, die Daten zurückzuschreiben. Wenn Du Dein Beispiel auf die zweite Spalte reduzierst und dort ein Datum überschreibst, landet es ja auch NICHT in der Datenbank. Offenbar versucht Roger dennoch, den Datentyp zu ermitteln (Typ des Rückgabewerts des Codeblocks), aber erstens nicht zuverlässig und zweitens ohne Wirkung, da eben nicht zurückgeschrieben werden kann. In solchen Fällen müsstest Du eigene Editoren schreiben und überlagern.
Herzlich,
Tom
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Ewald »

Hallo Tom,
ich habe das Beispiel nur testweise zusammengezimmert. Ich spreche auch überhaupt nicht vom Ändern der Datenbank.
Ich will ja die Spalte 2 nutzen und dann mit einem eigenen Editor weitermachen. Hatte ich soweit fertig und konnte auch in nummerische Felder und Zeichenfelder schreiben. Nur sobald ein Datumsfeld ins Spiel kommt, kann ich überhaupt keine Eingabe machen und somit auch nichts an den Editor weitergeben.
Es kommt sofort "Invalid Date Entered".
Gruß
Ewald
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Hallo, Ewald.

Ich verstehe Dein Problem nicht. Dieser Code hier arbeitet einwandfrei, mit leeren wie mit vorgefüllten Datumsfeldern. Die DBF hat zwei Felder - "TEST/C/30" und "Datum/D/8":

Code: Alles auswählen

#include "appevent.ch"
#include "dcdialog.ch"
#pragma library("dclipx.lib")

proc main
set date germ
use bladbf excl new     // irgendeine DBF mit einem Datumsfeld
calias:=alias()
@ 0,0 dcbrowse obrowse alias calias size 30,10 edit xbeBRW_ItemSelected

dcbrowsecol field (calias)->test heading "Test" parent obrowse
dcbrowsecol field (calias)->datum heading "Datum" parent obrowse

dcread gui fit eval {||SetAppFocus(oBrowse)}

close (calias)

return

procedure appsys() ; Return
Herzlich,
Tom
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Ewald »

Hallo Tom,
das geht wie gesagt bei mir auch reibungslos. Eben die Field Variante.
Ich bin dabei, mir einen Universal Browser zu bauen, mit dem ich auch mit crypt verschüsselte Felder browsen kann. Sowohl lesen als auch schreiben. Den habe ich auch schon fast fertig, aber leider geht das (noch) nicht mit Datumsfeldern. Als Basis dazu habe ich dieses Programm genommen, dass hervorragend funktioniert, bis ich versuche damit ein Datums-Feld zu verändern. Jetzt bin ich etwas verdattert, da ich etliche Programme in dieser Art laufen habe und bin nur durch Zufall bisher nicht auf eine Datumsfeld gekommen.
Liege ich denn total deneben ? Kann das überhaupt nicht funktionieren ?

Code: Alles auswählen

#include "appevent.ch"
#include "dcdialog.ch"

procedure main    
local getlist:={}
set date germ

parameter vbank
use (vbank) excl new
calias:=alias()
ns=0

@ 0,1 dcbrowse obrowse alias calias size 170,30 ;
      itemmarked {||ns:=obrowse:colpos} ;
      edit xbeBRW_ItemSelected ;
      mode 7 

for j := 1 to (cAlias)->(FCount())

dcbrowsecol data &( '{||' + calias+ '->' + fieldname(j) + '}' ) ;
       parent obrowse header (cAlias)->(FieldName(j)) editor "XED"

next

@ nil,nil dcget xnil getid 'XED' ;
          valid {|o|xedit(o)}

dcread gui fit 

return 

*---------------------------------

function xedit(o)

vwert:=o:editbuffer()

do case
  case type(fieldname(ns)) = "N"
       fieldput(ns,val(vwert))

  case type(fieldname(ns)) = "D"
       fieldput(ns,ctod(vwert))

  case type(fieldname(ns)) = "C"
       fieldput(ns,vwert)

endcase

return .t.

*--------------------------------
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Hallo, Ewald.

Dieser Code hier funktioniert. Ich habe Deine Tabelle "vbank" gegen "bladbf" ausgetauscht, das müsstest Du zurückändern:

Code: Alles auswählen

#pragma library("dclipx.lib")

procedure main
local getlist:={}
set date germ

use bladbf excl new
calias:=alias()
ns=0

@ 0,1 dcbrowse obrowse alias calias size 170,30 ;
      itemmarked {||ns:=obrowse:colpos} ;
      edit xbeBRW_ItemSelected ;
      mode 7

for i := 1 to (cAlias)->(FCount())

  cFieldName := FieldName(i)
  bFieldBlock := FieldWBlock(cFieldName,cAlias)

  dcbrowsecol data bFieldBlock header cFieldName parent oBrowse ;
  editor 'XED'

next

@ nil,nil dcget xNil getid 'XED' ;
          valid {|o|writefield(o:EditBuffer())}

dcread gui fit eval {||SetAppFocus(oBrowse)}

return

procedure AppSys() ; RETURN

*---------------------------------

function writefield(vwert)

do case
  case type(fieldname(ns)) = "N"
       fieldput(ns,val(vwert))

  case type(fieldname(ns)) = "D"
       fieldput(ns,ctod(vwert))

  case type(fieldname(ns)) = "C"
       fieldput(ns,vwert)

endcase

return .t.
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Erklärung dazu: Die Funktion "FieldWBlock" (eine Xbase++-Funktion) erzeugt den "richtigen" Get/Set-Codeblock für den Umgang mit dem Feld. Schau Dir einfach mal den Rückgabewert an. Damit ist Dein Browse-Editor dann allgemeingültig.
Herzlich,
Tom
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Ewald »

Hallo Tom,
stimmt, das funktioniert jetzt. Vielen Dank für die Tips.
Mal sehen, ob ich da irgendwo die Info über die crypt-Felder, die ich in meinen Anwendungen natürlich kenne und hinterlegt habe, noch reinbasteln kann.
Das habe ich bisher in der Schleife beim Aufbau berücksichtigt.
Beispiel: wenn DBF=LAGER und Feld=BEZ dann ist das Feld verschlüsselt und im Browse nicht "BEZ" verwenden sondern crypt(BEZ,vcode).
Der etwas verwirrende Code dafür ist hier:
Ich finde so ein Tool für "Admin" Eingriffe in die Datenbanken bei Kunden super. Mal schnell durch eine Tabelle browsen, auch wenn die Daten verschlüsselt sind.
Das kann einem kein fertiges Tool bieten.

Code: Alles auswählen

FOR j := 1 TO (cAlias)->(FCount())
vfeld = fieldname(j)
if schlussel(calias-vfeld)                                   //  hier stehen die verschlüselten Felder  z. B. LAGERBEZ
 cfeld =  '{||crypt('+cAlias+'->'+vfeld + ',vcode)}'   // verschlüsselt
    else
 cfeld =  '{||'      +cAlias+'->'+vfeld + '       }'   // nicht verschlüsselt
endif
next
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Hallo, Ewald.

Freut mich, dass das soweit funktioniert.

Das Problem mit den verschlüsselten Feldern müsstest Du im Set/Get-Codeblock und in der Funktion, die die Feldinhalte durchschreibt, berücksichtigen. Wenn Du Dir den Rückgabewert von "FieldWBlock/FieldBlock" anschaust, siehst Du, wie diese Codeblöcke aufgebaut werden müssen, und dort könntest Du dann die entsprechenden Ver- und Entschlüsselungsfunktionen greifen lassen.

Für ein Feld 'name' sieht FieldBlock so aus, und das kannst Du natürlich auch selbst machen (ohne FieldBlock):

Code: Alles auswählen

{|x| IIf(x==NIL,FIELD->name,FIELD->name:=x) }
Statt also hier direkt das Feld einzulesen (TRUE-Seite der Abfrage), müsstest Du Dein Crypt abfangen, und beim Durchschreiben (FALSE-Seite) ebenfalls. Dat isses dann ooch schon. :wink:

Edit: Ich würde bei allen Feldern, die nicht verschlüsselt sind, auf Field(W)Block zurückgreifen und nur für die anderen Fälle den Codeblock selbst bauen.
Herzlich,
Tom
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Ewald »

Hallo Tom,
jetzt wird es fast zum "Chat" ,-)
Diese Variante, die ich grade als Vorstufe versucht habe, editiert alles - inkl. Datums-Felder (ohne INVALID_DATE_ENTERED).
Und ich denk mich laust der berühmte Affe, sie schreibt auch direkt in die DBF zurück. Ohne Editor.

Code: Alles auswählen

#include "appevent.ch"
#include "dcdialog.ch"

procedure main
local getlist:={}
set date germ

parameter vdbf
use (vdbf) excl new
calias:=alias()
ns=0

@ 0,1 dcbrowse obrowse alias calias size 170,30 ;
      edit xbeBRW_ItemSelected ;
      mode 7

for i := 1 to (cAlias)->(FCount())
 cField := FieldName(i)
 bfield  =  '{|x|'+cAlias+'->(iif(x==NIL,FIELD->'+cfield+',FIELD->'+cfield+':=x))}'

 dcbrowsecol data &(bField) header cField parent oBrowse 

next

dcread gui fit eval {||SetAppFocus(oBrowse)}

return

procedure AppSys() ; RETURN
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: dcbrowse mit Datumsfeld

Beitrag von Tom »

Hallo, Chatpartner. 8)

Ja, das hatte ich vergessen: Der Get/Set-Codeblock macht den Editor überflüssig. Den benötigt man in solchen Konstellationen eigentlich nur, wenn man spezielle Sachen wie Date-Picker, Auswahllisten und so Zeug einbauen will.
Herzlich,
Tom
Antworten