DCBROWSECOL mit valid [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:

DCBROWSECOL mit valid [erledigt]

Beitrag von Ewald »

Hallo,
ich möchte mit express und dcbrowse eine DBF bearbeiten, in der Stücklisten gespeichert sind.
Das Ganze soll eine alte Clipper-Version mit dbedit ersetzen. Dabei bekomme ich folgendes
Problem nicht gebacken:
In der DBF gibt es ein Feld "Pos". Es ist ein 3stelliges Zeichenfeld.
Diese Feld enthält eine fortlaufende Nummer, die aber editierbar sein soll.
Bei der Eingabe in dieses Feld soll folgendes passieren.
Die eingegeben Nummer soll mit strzero() auf 3 Stellen gebracht werden.
Also aus "23" wird "023" usw.
In der Clipper Version habe ich das mit valid und einer Funktion gelöst.
Dort habe ich den eingegeben Wert in eine Zahl geändert, mit strzero() zurückgeschrieben
und gespeichert. Das bekomme ich trotz etlicher Versuche mit dcbrowsecol nicht hin.
Ich kann zwar den Wert in der Funktion wie gehabt ändern, bekomme ihn aber nicht in die
Datenbank zurückgeschrieben.
Wahrscheinlich habe ich da ein erhebliches Verständnisproblem. Anbei ein Auszug aus dem
Quellcode.

@ 2,0 dcbrowse obrowse size 90,20 ;
EDIT xbeBRW_ItemSelected ;
MODE DCGUI_BROWSE_EDITACROSSDOWN ;
DELETE xbeK_DEL

DCBROWSECOL FIELD sl6 PARENT oBrowse
DCBROWSECOL FIELD pos PARENT oBrowse ;
HEADER "POS" valid {||machpos(pos)}

dcread gui fit ;
addbuttons

funktion machpos(vpos)
vnpos:=val(vpos) // funktioniert
vcpos:=strzero(vnpos,3) // funktioniert
repl pos with vcpos // das geht nicht
return .t.

Nachdem Tom mir bei meinem smiley-Problem mit einen Einzeiler geholfen hat, hoffe ich mal,
dass es auch hierfür eine (für mich verständliche) Lösung gibt. Wäre schön, wenn mir jemand
aufs Fahrrad helfen könnte.
Zuletzt geändert von Ewald am Sa, 30. Mai 2009 16:15, insgesamt 1-mal geändert.
Benutzeravatar
Josef Stockinger
UDF-Programmierer
UDF-Programmierer
Beiträge: 53
Registriert: So, 25. Sep 2005 18:06
Wohnort: Nähe Regensburg
Kontaktdaten:

Beitrag von Josef Stockinger »

Hallo Ewald,

versuchs mal über den Umweg mit der Option :

Code: Alles auswählen

DCBROWSECOL ... HEADER "POS" EDITOR 'NREDIT'

Code: Alles auswählen

 @ nil,nil DCGET xnil PICTURE 'XXX' GETID 'NREDIT'
und setze dann beim GET erst VALID ein.

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

Beitrag von Ewald »

Hallo Josef,
das hat funktioniert. Ist mir zwar noch nicht ganz klar was da passiert, aber ich werde mal eine Nacht darüber schlafen.
Nochmals danke
Gruß
Ewald
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

Code: Alles auswählen

 @ nil,nil DCGET xnil PICTURE 'XXX' GETID 'NREDIT'
Wie kann man denn wohl die Variable xnil wieder leeren ? Ich würde diese Variable gerne nach Verarbeitung (Speicherung in das Datenbankfeld) wieder leeren. xnil="" oder rele xnil innerhalb der Funktion haben keine Auswirkung. Der eingegebe Wert bleibt als Vorgabe für die nächste Eingabe erhalten.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Kann eigentlich nicht sein, da Du direkt die datenbank bearbeitest und der aktuelle Wert des jeweiligen Datensatzes drinstehen müßte.
Vielleicht wäre es hilfreich wenn Du beim DCBROWSE die Alias Anweisung benutzt.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Ewald,

hier nochmal ein Beispiel:

@ 2, 3 DCBROWSE oBrowse1 ALIAS 'lg' SIZE lastcol-8, lastrow-8 ;
EDIT xbeBRW_ItemSelected MODE ;
iif ( ("fi")->across, DCGUI_BROWSE_EDITACROSSDOWN ,DCGUI_BROWSE_EDITDOWN ) ;
NOSOFTTRACK ;
SCOPE ;
EVAL {|| oBrowse1:goTop() }


DCSETPARENT oBrowse1
DCBROWSECOL field ("lg")->lg_anr HEADER mess327 ;
PROTECT {|| .t. } ;
WIDTH 2 PICTURE "999"
DCBROWSECOL field ("lg")->lg_str HEADER mess61 ;
WIDTH 16 EDITOR 'LGSTR' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_land HEADER mess62 ;
WIDTH 3 EDITOR 'LGLND' PICTURE "XXX"
DCBROWSECOL field ("lg")->lg_plz HEADER mess7 ;
WIDTH 3 EDITOR 'LGPLZ' PICTURE "@L0 99999"
DCBROWSECOL field ("lg")->lg_ort HEADER mess63 ;
WIDTH 16 EDITOR 'LGORT' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_ablz HEADER mess333 ;
WIDTH 3 EDITOR 'LGABLZ' PICTURE "999"

DCBROWSECOL field ("lg")->lg_nap1 HEADER mess335 ;
WIDTH 16 EDITOR 'NAP1' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_nap2 HEADER mess336 ;
WIDTH 16 EDITOR 'NAP2' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_apstr HEADER mess337 ;
WIDTH 16 EDITOR 'APSTR' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_aplnd HEADER mess338 ;
WIDTH 3 EDITOR 'APLND' PICTURE "XXX"
DCBROWSECOL field ("lg")->lg_applz HEADER mess339 ;
WIDTH 3 EDITOR 'APPLZ' PICTURE "@L0 99999"
DCBROWSECOL field ("lg")->lg_aport HEADER mess340 ;
WIDTH 16 EDITOR 'APORT' ;
PICTURE "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_aptel HEADER mess341 ;
WIDTH 10 EDITOR 'APTEL' ;
PICTURE "XXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_aphandy HEADER mess342 ;
WIDTH 10 EDITOR 'APHANDY' ;
PICTURE "XXXXXXXXXXXXXXX"
DCBROWSECOL field ("lg")->lg_apfax HEADER mess343 ;
WIDTH 10 EDITOR 'APFAX' ;
PICTURE "XXXXXXXXXXXXXXX"

@ nil,nil DCGET xNil PICT 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' GETID 'LGSTR'
@ nil,nil DCGET xNil PICT 'XXX' GETID 'LGLND'
@ nil,nil DCGET xNil PICT '@L0 99999' GETID 'LGPLZ'
@ nil,nil DCGET xNil PICT 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' GETID 'LGORT'
@ nil,nil DCGET xNil PICT '999' GETID 'LGABLZ' ;
MESSAGE mess334
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

und da war es wieder, mein valid problem.
ich hatte xnil als variable deklariert. Darum wurde der Wert wohl gepeichert. Wenn ich nicht deklariere, steht der Wert der Feldvariablen im Eingabefeld. Nur kann ich den dann wieder nicht an eine Funktion übergeben und wie unter Punkt 1 beschrieben bearbeiten.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Ewald, was heißt das? Bekommst Du eine Fehlermeldung?

Als erstes solltes Du dein Valid Code ändern und dort

valid { || machpos(pos,GetList,oBrowse ) }

Dann die Funktion selbst:

function machpos(vpos,xGetlist,xBrowse)

if valtype( xBrowse ) = 'O'
xBrowse:refreshall()
xBrowse:forcestable()
endif
DC_GetRefresh(xGetlist, nil, DCGETREFRESH_TYPE_EXCLUDE, {GETLIST_BROWSE})

Erst nach dem refresh siehst Du was wirklich in der DB steht. Wenn dies nichts nützt, hilft manchmal folgendes:

Reclock
dann pos := strzero(vpos,3)
Unlock
und dann den Refresh
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

eine Nachtschicht später ... Habe alles gegeben, hat aber nicht gereicht.
Ich habe das mal zusammengestrichen und browse nur noch das Feld "POS".
Um einen Überblick für mich zu bekommen übergebe ich der Funktion zusätzlich die DBF und die Satznummer. Mit den beiden Messageboxen lasse ich mir zu Laufzeit anzeigen, was in der Funktion passiert ist.
Die 1. Messagebox zeigt mir richtig die übergeben Werte an.
Die 2. Messagebox zeigt mir an, dass das Feld POS in der DBF stueposi mit der Satznummer x in strzero(pos) geändert ist !
Das ist aber leider nicht so. Im browse-Fenster steht nach wie vor meine Eingabe und die Datenbank ist auch nicht geändert. Unverständlich für mich ist auch, dass
pos :=ywert ein anderes Verhalten zeigt als
stueposi->pos:=ywert
Leider führt jedoch wie gesagt beides nicht zu Ziel.
Nachfolgend noch mal der Quellcode, wie er sich nach Änderung X zur Zeit darstellt. Hat mich teilweise an alte Basiczeiten erinnert. Damals sagte man noch Spaghetticode oder auch quick and dirty :)

use stueposi excl new

@ 2,0 dcbrowse obrowse size 90,20 ;
EDIT xbeBRW_ItemSelected ;
MODE DCGUI_BROWSE_EDITACROSSDOWN ;
INSERT DCGUI_BROWSE_SUBMODE_2 ;
APPEND DCGUI_BROWSE_SUBMODE_2 ;
DELETE xbeK_DEL ;
message str(recno())

DCBROWSECOL FIELD stueposi->pos PARENT oBrowse ;
HEADER "Pos" editor 'NREDIT'

@ nil,nil dcget xnil picture 'XXX' getid 'NREDIT' ;
valid {||machpos(pos,dbf(),recno(),getlist,obrowse)} ;
getfont "8.Arial"

dcread gui fit ;
addbuttons

commit
close all

return

function machpos(vpos,vdbf,vrec,xgetlist,xobrowse)
msgbox("Vor replace"+" "+pos+" "+vdbf+" "+str(vrec))
ywert:=strzero(val(vpos),3)
select(vdbf)
go vrec
satzlock()
*replace pos with ywert // geht nicht
*replace stueposi->pos with ywert // geht nicht
*pos:=ywert // verändert feld pos (in der Funktion) nicht !!!
stueposi->pos:=ywert // verändert feld pos (in der Funktion)
msgbox("Nach replace"+" "+pos+" "+dbf()+" "+str(recno())) // angeblich geändert, zeigt das gewünschte Ergebnis
commit
dc_getrefresh(xgetlist)
return .t.

Auf den Punkt gebracht möchte ich eingentlich folgendes erreichen. Beim Browsen soll die Möglichkeit bestehen, den Feldinhalt zu ändern. Diese Eingabe muss jedoch in einer Funktion überprüft werden (z.B. gibt es diese Teilenr. /Kundennr etc. überhaupt). Natürlich könnte man den Anwender so lange tippen lassen, bis er etwas gültiges eingibt. Aber was wäre das für eine Lösung ...
Innerhalb der Funktion soll der eingegeben Wert maschinell (wie strzero())oder manuell .zB. durch Auswahl aus einer Listbox geändert und in die Datenbank geschrieben werden.
Ich denke, das ist irgendwie Tagesgeschäft und sicherlich möglich.
Aber wie ??
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Ewald,

dcbrowse bzw. xbpbrowse muss den Satz praktisch neu einlesen,
damit er richtig dargestellt wird, das erreichst Du eigentlich hiermit.

if valtype( xBrowse ) = 'O'
xBrowse:refreshall()
xBrowse:forcestable()
endif
DC_GetRefresh(xGetlist, nil, DCGETREFRESH_TYPE_EXCLUDE, {GETLIST_BROWSE})

Wenn Du Dein dc_getrefresh damit ersetzt sollte es eigentlich gehen.
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

Habe die Änderung eingebaut, das Ergebnis bleibt aber das gleiche. In der Funktion sehe ich das (angeblich) geänderte Feld - aber leider nur dort. Die Datenbank und das Browsefenster bleiben unverändert - sprich dort steht die ursprüngliche Eingabe.

use stueli index stuenumm new
seek vnr+vindex
if found()
copy to stueposi while nrkbi+index1=vnr+vindex for !dele()
else
copy stru to c:&vdatei
endif

close all
use stueposi excl new

@ 2,0 dcbrowse obrowse size 90,20 ;
EDIT xbeBRW_ItemSelected ;
MODE DCGUI_BROWSE_EDITACROSSDOWN ;
INSERT DCGUI_BROWSE_SUBMODE_2 ;
APPEND DCGUI_BROWSE_SUBMODE_2 ;
DELETE xbeK_DEL ;
message str(recno())

DCBROWSECOL FIELD stueposi->pos PARENT oBrowse ;
HEADER "Pos" editor 'NREDIT'

@ nil,nil dcget xnil picture 'XXX' getid 'NREDIT' ;
valid {||machpos(pos,dbf(),recno(),getlist,obrowse)} ;
getfont "8.Arial"

dcread gui fit ;
addbuttons

commit
close all

return

function machpos(vpos,vdbf,vrec,xgetlist,xbrowse)

msgbox("Vor replace"+" "+pos+" "+vdbf+" "+str(vrec))
ywert:=strzero(val(vpos),3)
select(vdbf)
go vrec
satzlock()
*replace pos with ywert // geht nicht
*replace stueposi->pos with ywert // geht nicht
*pos:=ywert // ver„ndert feld pos nicht !!!
stueposi->pos:=ywert // ver„ndert feld pos
msgbox("Nach replace"+" "+pos+" "+dbf()+" "+str(recno())) // angeblich ge„ndert
commit
if valtype( xBrowse ) = 'O'
xBrowse:refreshall()
xBrowse:forcestable()
endif
DC_GetRefresh(xGetlist, nil, DCGETREFRESH_TYPE_EXCLUDE, {GETLIST_BROWSE})
return .t.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Koverhage »

Probier es bitte so,
wenn das auch nicht geht, kann ich Dir nicht mehr weiterhelfen.

use stueli index stuenumm new
seek vnr+vindex
if found()
copy to stueposi while nrkbi+index1=vnr+vindex for !dele()
else
copy stru to c:&vdatei
endif

close all
use stueposi alias stueposi excl new

@ 2,0 dcbrowse obrowse ALIAS "stueposi" size 90,20 ;
EDIT xbeBRW_ItemSelected ;
MODE DCGUI_BROWSE_EDITACROSSDOWN ;
INSERT DCGUI_BROWSE_SUBMODE_2 ;
APPEND DCGUI_BROWSE_SUBMODE_2 ;
DELETE xbeK_DEL ;
message str(recno())

DCBROWSECOL FIELD stueposi->pos PICT "XXX" ;
valid {||machpos(("stueposi")->pos,getlist,obrowse)} ;
PARENT oBrowse

dcread gui fit ;
addbuttons

close all

return



function machpos(vpos,xgetlist,xbrowse)

** go vrec // nicht notwendig steht ja auf aktuellen Satz

** satzlock() //

do while !("stueposi")->(dbrlock(RecNo()))
enddo

stueposi->pos := strzero(val(vpos),3)

("stueposi")->( DbCommit() )
("stueposi")->(dbrunlock(RecNo()))

if valtype( xBrowse ) = 'O'
xBrowse:refreshall()
xBrowse:forcestable()
endif
DC_GetRefresh(xGetlist, nil, DCGETREFRESH_TYPE_EXCLUDE, {GETLIST_BROWSE})
return .t.
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

Hallo Koverhage (ist das der Name ?)
ich möchte mich an dieser Stelle ausdrücklich für Deine Bemühungen bedanken.
Der letzte Lösungsansatz führt leider zum gleichen Ergebnis wie meine anderen Versuche. Eingentlich unvorstellbar.
Das es irgendwie geht habe ich ja zwischendurch zufällig bemerkt, als ich die Variable XNIL deklariert hatte. Da hatte ich allerdings den Teufel mit dem Belzebub? ausgetrieben - oder so ähnlich.
Da ich in diese Geschichte jetzt allderdings einige Tage investiert habe, werde ich es weiterversuchen und an dieser Stelle bei Erfolg berichten - oder es meldet sich noch jemand, der die Lösung auf der Hand hat ...
Schön wäre es ja.
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von Wolfgang Ciriack »

Hallo Ewald,
hier ist eine quick and dirty Lösung für dein Problem:

Code: Alles auswählen

PROCEDURE Main
local GetList:={}, GetOptions
local cAlias, oBrowse

use test alias te new
OrdCreate("test1","tepos","pos")
dbsetorder(1)
dbgotop()
cAlias:=alias()


DCGET OPTIONS ;
      NOMINBUTTON ;
      NOMAXBUTTON ;
      NOSUPERVISE

@ 1,1 DCBROWSE oBrowse ;
      DATA cAlias ;
      SIZE 20,20 ;
      FIT ;
      EDIT xbeBRW_ItemSelected MODE DCGUI_BROWSE_EDITACROSSDOWN ;
      NOHSCROLL 

DCBROWSECOL DATA {|| val(te->pos)} PICTURE "@L0 999" ;
            HEADER "Position" PARENT oBrowse WIDTH 4 ;
            EDITOR "IDPNR" 
DCBROWSECOL FIELD te->name ;
            HEADER "Name" PARENT oBrowse WIDTH 12 ;

@ NIL,NIL DCGET xNIL PICT "@K 999" GETID "IDPNR" ;
      VALID {|o| chkeing(o) }

DCREAD GUI ;
   TITLE "Test" ;
   OPTIONS GetOptions ;
   MODAL ;
   SETAPPWINDOW ;
   ADDBUTTONS ;
   FIT 

return

function chkeing(o)
local x, y, ret

x:=o:Editbuffer()
te->pos:=strzero(val(x),3)
return .T.
Bei mir hats jedenfalls funktioniert :razz:
Viele Grüße
Wolfgang
Ewald
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 475
Registriert: Sa, 08. Apr 2006 14:07
Wohnort: Datteln
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Ewald »

Hallo Wolfgang,
funktioniert auch bei mir hervorragend. Ich denke, von dieser Lösung war ich noch einige Lichtjahre entfernt. :shock: Nach einer kurzen Erholungspause werde ich mal versuchen, wie weit ich diese Funktion für mein weiteres Vorhaben verbiegen kann. Den UR-CODE finde ich ja hier im Forum noch einige Zeit wieder :lol:
Ist doch schon erstaunlich, wieviele Varianten/Probleme man aus 3 ganz einfachen Befehlszeilen zaubern kann.
Nochmal vielen Dank und Grüße nach Berlin
Ewald
Antworten