getlist [erledigt]

Alle Fragen um die Programmierung, die sich sonst nicht kategorisieren lassen. Von Makro bis Codeblock, von IF bis ENDIF

Moderator: Moderatoren

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

getlist [erledigt]

Beitrag von Manfred »

Hi,

mal wieder eine interessante Frage:

Ich habe eine Funktion, in der Eingaben über (1.)GET erfolgen. Das getlist dazu habe ich LOCAL getlist := {} gesetzt.

Innerhalb dieser GETs, die in einer anderen Funktion sind und das getlist per Parameter übergeben bekommen, hat man die Möglichkeit eine weitere, andere Eingabemaske mit (2.)GETs aufzurufen (auch hier eine getrennte Funktion der GETS mit getlist als Parameter), die wiederum vorher ein LOCAL getlist := {} haben.

Frage 1. das sind doch dann local gekapselte getlist, die sich nicht beeinflussen dürften?

Frage 2. Wenn ich in der 2.Eingabemaske ein CLEAR GETS aufrufe, ist es dann korrekt, das auch das READ von der 1.Maske abgebrochen wird, wenn ich die 2.Maske verlasse?

Ich habe das CLEAR GETS aus der 2.Maske ausgeremt und das Problem war weg.

Das verstehe ich jetzt aber nicht so ganz....

Ich hoffe ich habe es jetzt nicht wieder zu umständlich erklärt.

Eigentlich ist die Frage: Killt ein CLEAR GETS (aus einem 2.READ) in einem verschachtelten READ (verschachtelte GETs) die 1.Gets, obwohl beide getlist Local sind?
Zuletzt geändert von Manfred am Mo, 11. Mai 2009 20:32, insgesamt 1-mal geändert.
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Re: getlist

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben:Hi,
Eigentlich ist die Frage: Killt ein CLEAR GETS (aus einem 2.READ) in einem verschachtelten READ (verschachtelte GETs) die 1.Gets, obwohl beide getlist Local sind?
also adhoc hätte ich gesagt NO ... aber wenn du schon fragst wird es
einen Grund geben. Also hier der Code den ich verwendet habe :

Code: Alles auswählen

PROCEDURE MAIN
LOCAL a:= "2222"
LOCAL b:= "3333"
LOCAL GETLIST := {}

CLS
@ 10,10 SAY "1111"
@ 11,10 GET a  VALID BFUNC(@a)
@ 12,10 GET b
READ
CLEAR GETS
? a,b
RETURN

FUNCTION BFUNC(aa)
LOCAL c:= "4444"
LOCAL GETLIST := {}
@ 14,10 SAY c
@ 15,10 GET aa 
READ
CLEAR GETS
? aa
RETURN .T.
es geht also darum ob ich in die Zeile "@ 12,10 GET b" mit den "3333"
komme ... und siehe da ... es geht NICHT !!!

nun wollte ich das "nicht glauben" und hab das selbe nochmal unter
Cl*pper laufen lassen ... und das selbe Resultat, es geht NICHT !!!

nun bin ich irgendwie "beunruhigt", verwende ich doch nach jedem
READ auch ein CLEAR GETS ... und das "überall" ...:(((

grummel ... viel Arbeit das alles zu überprüfen ...
gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Jimmy,

hast Du Erfahrung mit Readmodal()
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi
Manfred hat geschrieben: hast Du Erfahrung mit Readmodal()
brauchst du gar nicht, ersetzte "CLEAR GETS" durch READKILL() !
das hab ich auch in meinen "verschachtelten GETs" ...

uffffff ... Glück gehabt :) ... wäre wohl sonst wirklich eine Menge
Arbeit gewesen alle "CLEAR GETS" zu überprüfen ...

gruss by OHR
Jimmy
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

da ich das früher auch mit lokalen GetList := {} gemacht habe, weiß ich dass es gehen muß, aber warum so umständlich das 2. READ mit clear gets löschen ?
Wenn das Read verlassen wurde ESC oder ENTER oder Pfeil ab, und die Funktion beendet wird, kommt man automatisch zum alten READ zurück und dort gibt es nur das dortige lokal getlist ...
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

die Frage habe ich erwartet.

Ich erkläre mal kurz, warum ich das so mache. Ich habe eine Funktion, in der das Promptmenue steht, für die Möglichkeiten Neu, suchen, ändern usw. Das Read steht auch in dieser Funktion. Die Gets werden aber in einer anderen Funktion ausgeführt und dazu wird das getlist per Parameter übergeben. Wenn ich jetzt den 1.Durchlauf der Gets gestartet habe, dann passiert es, dass das Read nicht abgebrochen wird, sondern mehrmals wieder von vorne beginnt. Also Clear Gets rein nach jedem Case und schon wird das Read verlassen. Ob das jetzt an dem Local getlist liegt, oder an der getrennten Funktion... keine Ahnung. Auf jeden Fall ist aus dem Grunde ein Clear Gets dadrin. Innerhalb der Gets, kann dann je nach Aufgabe nochmals ein Verteiler aufgerufen werden, der dan auch wieder GETs hat. usw.

Es ist halt so, das jede Funktion für sich alleine laufen soll, oder läuft, aber eben auch aus einem get heraus aufgerufen werden kann. Eigentlich SDI nur im Textmodus und mit den Tools.
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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

offensichtlich hatte ich nie so verschachtelte GET / READ Kombinationen, ich habe immer nur aus einer Eingabemaske heraus mit F2 Hilfsfenster aufgerufen, die halt lokale READs gemacht haben. Nach dem Ende wurde der Übergabewert übergeben.

Versuche es mit der Lösung von Jimmy.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Jimmy,

ich muß Dich erstmal enttäuschen, es klappt nicht.

Ich werde nochmal etwas basteln.
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
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Jimmy,

Ich nehme alles zurück und behaupte das Gegenteil. Es klappt doch. Ich habe das mit dem .T. nicht richtig gelesen und das eingesetzt. Es muß ohne .T. sein, dann klappt es.

Danke für den Tipp.
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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

da fällt mir ein, ARRAYs werden nicht per Value sondern per Referenz übergeben, d.h. dass alle Änderungen in den Funktionen auch in der aufrufenden Routine wirken. ACopy() kopiert nur eindimensionale zuverlässig. Eventuell verursacht dieses deine Probleme.
AClone() würde eine exakte völlig eigenständige Kopie machen.

Code: Alles auswählen

xyz( Getlist )

Function xyz(MyGetList)
    local getlist
    getlist := aclone(MyGetList)
... nur so ein Gedanke ...
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Hubert,

ich verstehe jetzt aber den Zusammenhang nicht. Ich übergebe das getlist per value und mit acopy() mache ich überhaupt nichts. Und da das getlist ein local ist, dürfte sich nur etwas tun, wenn es dann per Referenz übergeben werden würde, was aber nicht geschieht bei mir.
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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

du denkst, wie viele auch, dass du per Value übergibst, da du keinen @Referenzoperator benutzt, aber es gibt bei Arrays ausschließlich per Referenz - siehe das Beispiel:

Code: Alles auswählen

proc main()
    local aEinDim := { 1,2,3 }
    local aZweiDim := { {1,"A"},{2,"B"},{3,"C"} }
    cls
    ? "Vor Aufruf von Funktion"
    ? "aEinDim[2]    = ",aEinDim[2]
    ? "aZweiDim[2,2] = ",aZweiDim[2,2]
    ?
    ? "Funktion erhält Arrays als Parameter per VALUE ?",MyFunc(aEinDim,aZweiDim)
    ?
    ? "Nach Aufruf von Funktion"
    ? "aEinDim[2]    = ",aEinDim[2]
    ? "aZweiDim[2,2] = ",aZweiDim[2,2]
return

function MyFunc(a1,a2)
    a1[2]   := 5
    a2[2,2] := "Oh was ist hier los !"
return "Funktion ist fertig"
Das ist der Ausdruck den ich erhalte:
Vor Aufruf von Funktion
aEinDim[2] = 2
aZweiDim[2,2] = B

Funktion erhält Arrays als Parameter per VALUE ? Funktion ist fertig

Nach Aufruf von Funktion
aEinDim[2] = 5
aZweiDim[2,2] = Oh was ist hier los !
ACOPY() erzeugt für eindimensionale Arrays eine Kopie, ACLONE() erzeugt eine exacte Kopie bei mehreren Dimensionen.
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Jimmy,

ich will mal so sagen, jetzt habe ich das Problem, dass nach dem 2. Mal ins Read gehen, wieder das Read erst nach dem 2.Durchlauf durch die gets verlassen wird. Also genau der Grund, warum ich die Clear Gets eingebaut habe

Das verstehe ich nun überhaupt nicht.
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben:ich will mal so sagen, jetzt habe ich das Problem, dass nach dem 2. Mal ins Read gehen, wieder das Read erst nach dem 2.Durchlauf durch die gets verlassen wird. Also genau der Grund, warum ich die Clear Gets eingebaut habe
Das verstehe ich nun überhaupt nicht.
:-k hm ... deinen code müsste man jetzt sehen (im Debugger) wie tief
du die GETs verschachtelt hast ...

also ich habe CLEAR GETS jeweils "nach" dem READ in der 1st GET
"Ebene" um alle evtl. "offenen" GETs zu "terminieren"

In den "SubEbenen" verwende ich READKILL() um dortigen
GETs in "ihrer Ebene" zu "terminieren".

Also wenn du in der 3st "SubEbene" ein READKILL() loslässt
kommst du nur zur 2st "SubEbene". Mit einem GLEAR GETS
aus der 3st "Sub Ebene" kommt man bis zur 1st "Ebene"
nach dem READ.

willst du aus der 3st "SubEbene" evtl. "abbrechen" so kannst
du es mal mit READKEILL();Keyboard(K_DOWN) versuchen
um in die 1st "Ebene" zu kommen ohne es zu verlassen.

gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Noch eine Frage,

ein CLEAR GETS, wie weit reicht das eigentlich durch, bei verschachtelten lokalen Gets?

Wenn ich eine lokale Get Maske habe, die mit einem READ abgeschlossen wird und innerhalb dieser lokalen GET Maske rufe ich über VALID eine Funktion auf, die wiederum eine lokale GET Maske mit READ aufruft. Wenn ich beim zuletzt aufgerufenen READ ein CLEAR GETS aufrufe, gilt das dann für alle lokalen GET Masken mit READ, oder sollte das nur für das derzeitige lokale READ gelten?

Ich komme hier nicht weiter, ich habe es mit CLEAR GETS und mit READKILL() probiert. Clear GETS ist die einzige Möglichkeit, die wirklich beendet. Bei READKILL() habe ich ab dem 2. Durchlauf durch die GETS (egal, ob verschachtelt oder nicht) mindestens 2 Durchläufe durch die GETS, bevor ich aus der Maske raus komme. Ich hatte etwas ähnliches schon mal gehabt, da wurden alle GETS aufaddiert und das System dachte, es wären dementsprechende mehr. Hier ist es aber nicht der Fall.

Ich habe auch im Moment keine Idee, wie ich im Debugger prüfen kann, was da wirklich passiert. Weder im VX noch im XPPDBG.

Ich muß es noch ein wenig ausführlicher beschreiben. Die ganzen Eingaben werden in einer PROMPT Umgebung getätigt.

Code: Alles auswählen

FUNCTION kdanredevt()
         LOCAL getlist := {}
         LOCAL nAuswahl
         LOCAL oKdAnrede := kundenanrede():new():initvaria():dbOpen("anrede")

         MEMVAR oBild

         oKdAnrede:maske()
         DO WHILE .T.
            Clear Gets
            nAuswahl := oBild:MenueHorizontal(nAuswahl,"Kundenanreden",.T.)
            DO CASE
               CASE nAuswahl = 1                                                // Erfassen
                    oKdAnrede:felderleeren(oKdAnrede):maske():felder(getlist)
                    READ
                    IF LastKey() = K_ESC
                       LOOP
                    ENDIF

               CASE nAuswahl = 2                                                // Suchen
                    EXIT
            ENDCASE
         ENDDO .T.
         oKdAnrede:closeDb()
         RETURN(.T.)
Die Frage wäre hier einfach einmal, ist das mit dem CLEAR GETS in der "Schleife" ok so? Wenn ich es entferne, dann wird das READ nicht beendet. Ich habe es auch schon direkt hinter das READ gepackt, aber es ändert sich an oben genanntem Problem nichts. Ohne eine Verschachtelung klappt es einwandfrei mit CLEAR GETS. Mit READKILL() an gleicher Stelle habe ich aber ohne Verschachtelung auch schon das Problem, dass das READ erst nach 2-x Durchläufen beendet wird.
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben: ein CLEAR GETS, wie weit reicht das eigentlich durch, bei verschachtelten lokalen Gets?
CLEAR GETS löscht ALLE offenen GETs

Code: Alles auswählen

         DO WHILE .T.
            Clear Gets
...
                    READ
                    IF LastKey() = K_ESC
                       LOOP
                    ENDIF
hm ... ungewöhnlich ... ein CLEAR GETS "vor" einem READ ... ?
Die Frage wäre hier einfach einmal, ist das mit dem CLEAR GETS in der "Schleife" ok so?
nun ... hm ... also aus meiner Sicht sehr ungewöhlich wie du es anwendest

ich hab es mal so "gelernt" das ich "hinter" einem READ eine Anweisung
schreibe die das Get System "schliesst". Das wäre im "normal" Fall CLEAR
GETS. Nun gibt es aber die "verschachtelten" GETs wo man ja bekanntlich
mit LOCAL Getlist arbeitet um sich mit der "1st Ebene" nicht in gehege zu
kommen. Um nun eine solche LOCAL Getlist zu schliessen muss man
READKILL verwenden sonst wird auch die "1st Ebene" der GETs "gelöscht"
und man landet "hinter" dem READ der "1st Ebene".

hat man nun "2 verschachtete" LOCAL Getlist so kommt man mit READKILL nur jeweils "1 Ebene" zurück, also von 3st -> 2st, aber eben
nicht zu 1st !

willst du nun von der 3st zur 1st kommt es wieder darauf an was du
damit "aussagen" willst : Abbruch der ganzen Aktion (CLEAR GETS)
oder willst du das "Ergebniss" vom 3st ins 1st übernehmen (Keyboard) ?

deshalb sagte ich ungewöhlich, den ich "trenne" das "aufräumen" der
GETs nach dem READ von der "Steuerrung" wie ich das "Ergebniss"
zurück bekomme.

also :

Code: Alles auswählen

     IF oKdAnrede:felderleeren(oKdAnrede):maske():felder(getlist):tuwas
...
Methode oKdAnrede:tuwas
LOCAL RETVAR := .F.
...
                    READ
                    READKILL()
                    IF LastKey() = K_ESC 
                        RETVAR := .F. 
                    ELSEIF LastKey() = K_ENTER
                        RETVAR := .T. 
                        KEYBOARD(K_DOWN)
...   
                    ENDIF 
...
        RETURN (RETVAR)
also das ganze raus aus der "Schleife" ...

vielleicht solltest du "GUI" in Hinterkopf haben : Der User clicked
auf einen Button um "eine" Aktion auszuführen. Ergo entwickele ich
"eine" Methode für "eine" Aktion. Diese Aktion definiere ich nun als
UserEvent sodas man die von "überall" ansprechen kann indem man
ein PostEvent(myEvent) anwendet.

Code: Alles auswählen

#define xbeY_KNEU    xbeP_User + 1
#define xbeY_KEDIT   xbeP_User + 2
#define xbeY_KSUCH  xbeP_User + 3
...
DO WHILE ...
    nEvent := AppEvent( @mp1, @mp2, @oXbp)
  DO CASE
   CASE nEvent == xbeY_KNEU
...
   OTHERWISE
     oXbp:handleEvent( nEvent, mp1, mp2 )
  ENDCASE
ENDDO
...
FUNCTION myKunden
...
oBtn := XbpPushButton()....
oBtn:caption :="Kunden Neuaufnahme"
oBtn:activate := {|| PostAppEvent( xbeY_KNEU )}
...
hoffe dich nicht zu sehr verwirrt zu haben, aber unter GUI sind die Events
die eigendliche "Steuerrung" und nicht wie bei DOS das LastKey().

gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hi Jimmy,

hm, gut, das Clear Gets steht einerseits vor dem READ. Aber nur wenn das Prompt Menue begonnen wird. Danach steht es immer nach dem READ. Ich erspare mir halt so, das CLEAR GETS nach jedem READ, weil ich das Beispiel Menue etwas verkürzt habe. Es sind noch etliche Menuepunkte mehr drin: suchen, ändern, vorwärts, rückwärts usw.
Ich habe es aber auch zur Probe direkt hinter die READS gepackt, aber es hatte den gleichen Effekt.

OK, das mit dem CLear Gets ist jetzt geklärt. Ich befinde mich in der 2. Ebene und möchte in die 1.Ebene zurück und die wird dann direkt mit abgebrochen. Hast Du so erklärt, stimmt auch so. Wenn ich aber ein REadKill() anstatt des Clear GEts einbaue, dann habe ich den Effekt:

Egal, ob verschachtelt oder nicht, sobald das REad zum 2. Mal aufgerufen wird, wird das READ erst beendet, wenn die GETS mehrmals durchlaufen wurden. Sprich ich rufe das READ auf, befinde mich in den GET Feldern und müßte jetzt normalerweise nach dem Verlassen des letzten GET Feldes das READ jetzt verlassen, aber der Cursor springt wieder ins 1.Get Feld, geht dann per Enter alle weiteren GET Felder durch und springt nach dem letzten wieder ins 1.Get Feld. Das macht der so 2-x Mal.

Tja, nennt man sowas nicht den Teufel mit dem Belzebub austreiben?
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
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Moin,

nur damit keiner glaubt....

Ich kann mich auf den Kopf stellen und mit den Füßen Hurra schreien, es klappt nicht. Irgendwas mache ich mit den verschachtelten GETS verkehrt, oder ich habe einen Fehler entdeckt.

:evil: :x :?
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben: ... es klappt nicht. Irgendwas mache ich mit den verschachtelten GETS verkehrt...
ich würde versuchen das CLEAR GETS/READKILL immer nur nach
einen READ zu verwenden ... ich hab das "Gefühl" das bei der "Schleife"
irgendwo noch was anderes passieren muss ...

"wozu" setzt du es (CLEAR GETS) nun "genau" ein ? willst du in einem
"verschachteltem" GET :

a.) abbrechen, keine (weiteren) Werte übernehmen, zurück zu 1st Ebene
b.) alle Werte übernehmen und zurück zur 1st Ebene
c.) a.) oder b.) Aktion aber nur eine Ebene zurück
d.) ... nur um alle GETs zu schliessen

gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Hiho,
AUGE_OHR hat geschrieben:hi,
ich würde versuchen das CLEAR GETS/READKILL immer nur nach
einen READ zu verwenden ... ich hab das "Gefühl" das bei der "Schleife"
irgendwo noch was anderes passieren muss ...
Das habe ich alles schon ausprobiert, es hilft nicht. Ich habe beides direkt hinter das Read gesetzt.
"wozu" setzt du es (CLEAR GETS) nun "genau" ein ? willst du in einem
"verschachteltem" GET :

a.) abbrechen, keine (weiteren) Werte übernehmen, zurück zu 1st Ebene
b.) alle Werte übernehmen und zurück zur 1st Ebene
c.) a.) oder b.) Aktion aber nur eine Ebene zurück
d.) ... nur um alle GETs zu schliessen

gruss by OHR
Jimmy
Wenn es nicht drin ist, dann springt der Cursor nach dem letzten Get Feld, das ich mit RETURN beende wieder ins 1. und läuft nochmals durch. Erst beim 2.Durchlauf verläßt der Cursor dann das letzte GET Feld. Das passiert aber erst, nachdem einmal die Getfelder durchlaufen und dann zum 2. Mal aufgerufen wurden.

Und dieses Phänomen habe ich jetzt bei ReadKill() genauso. Ich kann kein Clear Gets machen, weil dann alles gekillt wird, aber ein Readkill() beendet nicht sofort. Ich kriege die Krätze....

Ich habe zur Vorsicht schon mal den Alaska Support informiert, mal sehen, was die dazu sagen. Vielleicht ist es ja eine ganz einfache Sache. :roll:
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
AUGE_OHR
Marvin
Marvin
Beiträge: 12906
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 45 Mal

Beitrag von AUGE_OHR »

moin,
Manfred hat geschrieben: Wenn es nicht drin ist, dann springt der Cursor nach dem letzten Get Feld, das ich mit RETURN beende wieder ins 1. und läuft nochmals durch.
hm ... sprechen wir hier von einem "Normalen" GET wie bei Cl*pper ?
wenn ja :
GET
GET
GET
READ
CLEAR GETS

also wenn da nicht eine Schleife ist kann man nach dem 3st GET
nicht mehr "zurück" auf das 2st oder das 1st ...
Erst beim 2.Durchlauf verläßt der Cursor dann das letzte GET Feld. Das passiert aber erst, nachdem einmal die Getfelder durchlaufen und dann zum 2. Mal aufgerufen wurden.
em, äh ... hast du kein VALID was überprüft ob eine Eingabe war ?
dort würde ich dann ein READKILL / Keyboard einbauen um die
folgenden GETs zu terminieren.
Also wenn 1st Feld keine Eingabe so terminieren 2st und 3st GET ... ???
Und dieses Phänomen habe ich jetzt bei ReadKill() genauso. Ich kann kein Clear Gets machen, weil dann alles gekillt wird, aber ein Readkill() beendet nicht sofort. Ich kriege die Krätze....
also das READKILL geht hinter das READ durch das es aktiviert
wird ... aber was ist dann mit der Schleife ... wie kommt er da bei dir
raus oder läst du ihn sofort wieder in ein GET/READ laufen ?

warum überhaupt eine "Schleife" in einem GET/READ sehe ich immer
noch nicht so richtig ... und wenn ich an GUI denke "graut" es mir davor
sowas "aufzulösen" und auf Events umzustellen !

siehe dir doch nochmal meinen letzten Vorschlag mit den Events an, ob
du nicht die "Schleife" auflösen kannst ... es reicht unter GUI wenn du
einen AppEvent-Loop hast um alle deine Aktionen zu steuen. Du musst
nur noch Events per PostEvent(raushier) verschicken.

eine weiter Frage Richtung GUI ist wie du die GET darstellst ... in einem
Pop-Up Fenster ? wenn ja sollte man da "umstellen" und die :Close()
Methode dafür verwenden um dort ein READKILL() einzu bauen.

Wenn ich nun ein "Fenster" (XbpCrt oder XbpDialog) abbrechen will,
rufe ich nur noch per PostAppEvent(xbeP_Close,,,oPopUp) auf und
muss mich um nichts mehr weiter kümmern (alles in der :Close()
Methode)

gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Moin Jimmy,

also: Es handelt sich hier um ein einfaches GET wie bei Clipper.

Clear Gets geht nicht, weil verschachtelt und dann alles abgebrochen wird. Also muß ReadKill() her. Das habe ich direkt nach dem Read eingebaut, bringt nichts. Ist auch m.E. das gleiche, als wenn es einmal in die Do While Schleife kommt, ganz an den Anfang. Außerdem habe ich ja nicht das Problem, das GETS zu oft abgebrochen wird, sondern das GETS nicht richtig beendet werden.

Da ist keine Schleife, und man kann normalerweise bei einem Clear Gets auch nicht zurück, es wird direkt beendet. Es geht hier auch nur um den Ersatz von Clear Gets.

Ich hatte bisher nie im letzten GetFeld über eine Validprüfung ein REadkill, oder so, weil es per Clear Gets IMMER geklappt hat. Solange keine Verschachtelung vorlag. Ich bin mir auch nicht mehr sicher, ob ich es jemals schon mit Verschachtelungen versucht habe. Es kann höchtens sein, das ich es NICHT mit lokalen getlists gebaut hatte.

Die Schleife ist keine Schleife in dem Sinne, es ist so, dass die GETS nicht automatisch verlassen werden, ab dem 2.Mal. Wie gesagt, beim 1.Mal aufrufen der Gets klappt es, sie werden nach dem letzten Get verlassen, sobald ich eine weitere Eingabe starte, und somit die Get Felder wieder aktiviere/aufrufe, springt der Cursor direkt nach dem letzten feld wieder in das 1. und durchläuft alle GEts erneut. Und das mindestens noch ein weiteres, bis ein 3.Mal.

Ich schätze mal, das die Verschachtelung von GETS wohl verschiedene Zustände kennt. 1. Get und dann ein weiteres GET , was sofort danach wieder ins 1. get zurückgeschickt wird und GET, wie bei mir, aus dem heraus wieder ein mehr oder weniger komplette Anwendung aufgerufen wird.

Ich habe gerade einmal ausprobiert, was passiert, wenn ich das REadkill() direkt in die Validabfrage des letzten GET Feldes einbaue. Gar nichts. Es bleibt so wie es ist. Es entsteht eine Schleife, genau so, wie oben beschrieben.
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
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Ich habe gerade einmal eine Testumgebung aufgebaut und das Problem nachgestellt auf ganz einfacher Basis. Das Grundkonzept klappt genau so, wie es klappen soll.

Jetzt muß ich mich einmal herantasten, wo denn bei dem echten Programm der Futtsack liegt.

1.Stufe Clear Gets 2.Stufe (verschachtelt) Readkill()
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
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo,

ist zwar schon ne weile her, aber ReadKill() kann doch nur wirken, wenn man im READ ist oder ?
Somit wäre das sinnlos:

Code: Alles auswählen

... GET test
READ
ReadKill()  <- hierhin kommt man erst NACH dem READ 
...
ClearGets() setzt meines Wissens das GETLIST-Array (wenn local, dann NUR local, wenn nicht, dann das Private ...) auf {} zurück. Wenn es local ist müßte ein Rücksprung aus der Routine (procedur function) in das offene zurückspringen. Es kommt aber natürlich drauf an, ob es wirklich ein locales Array ist, oder nur eine Referenz auf ein gemeinsames oder das private vom Programmanfang.
Aus dem Gedächtnis ein sinnvolles Beispiel für ClearGets()...

Code: Alles auswählen

set funtion F12 to ClearGets()
... GET Test
READ  <- hier drinn kann man mit F12 Read abbrechen ...
Um zu sehen wie die Abläufe sind und was wirklich geschieht ist hier der Debugger zu unübersichtlich, ich kann mich nur wiederholen:

Code: Alles auswählen

function PrintDebug(cTxt)
    set console off
    ? cTxt
    set console on
return nil
procedure Main()
...
set alternate to debug.txt
set alternate on
...
PrintDebug("ProgName:"+var2Char(getlist)+"????")
...
Bringt einen wunderbaren Programmablauf an den Mann ;-)

Sollte es zu kompliziert sein mit den Schleifen, solltest du darüber nachdenken den Ablauf zu vereinfachen, z.B. mit Zustandsvariablen und die @GET je nach Zustand aufbauen, bevor du in den READ gehst.
Einfacher ist meist auch Besser :D
Gruß
Hubert
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21186
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Vom Grundkonzept habe ich es so aufgebaut. Das hier klappt einwandfrei, so wie es soll.

Code: Alles auswählen

PROCEDURE main()
          LOCAL getlist := {}
          LOCAL nAuswahl
          LOCAL promptlist := {}

          MEMVAR feld1, feld2, feld3

          PRIVATE feld1
          PRIVATE feld2
          PRIVATE feld3

          WINIT()
          SEt DATE GERMAN
          SET CONSOLE OFF
          SET CONFIRM ON
          set CURSOR ON

          set wrap on
          set message TO MAXROW() Center
          DO WHILE .T.
             clear gets
             @  5, 1 PROMPT "1) Eingeben" MESSAGE ""
             @  6, 1 PROMPT "2) Ändern  " MESSAGE ""
             @  7, 1 PROMPT "2) Quit  " MESSAGE ""
             MENU TO nAuswahl
             DO CASE
                CASE nAuswahl = 1
                     feld1 := feld2 := feld3 := SPACE(5)
                     felderread(getlist)
                     READ

                CASE nAuswahl = 2
                     felderread(getlist)
                     READ

                CASE nAuswahl = 3
                     EXIT

             ENDCASE
          ENDDO .T.
          RETURN

********************************************************************************
FUNCTION felderread(getlist)
         MEMVAR feld1, feld2, feld3
         cls
         @  5, 1 GET feld1 PICTURE "XXXXX";
                 VALID pruef()
         @  6, 1 GET feld2 PICTURE "XXXXX"
         @  7, 1 GET feld3 PICTURE "XXXXX"
         RETURN(.T.)
********************************************************************************
FUNCTION pruef()
         eingabe2()
         RETURN(.T.)
********************************************************************************
FUNCTION eingabe2()
         LOCAL nAuswahl
         LOCAL getlist := {}
         LOCAL promptlist := {}

         MEMVAR feld4, feld5, feld6

         PRIVATE feld4
         PRIVATE feld5
         PRIVATE feld6

         WOPEN(5,1,15,20,.T.)
         WBOX()
         WCENTER(.T.)
         DO WHILE .T.
            ReadKill()
            @  5, 1 PROMPT "1) Eingeben" MESSAGE ""
            @  6, 1 PROMPT "2) Ändern  " MESSAGE ""
            @  7, 1 PROMPT "2) Zurück  " MESSAGE ""
            MENU TO nAuswahl
            DO CASE
               CASE nAuswahl = 1
                    feld4 := feld5 := feld6 := SPACE(5)
                    felderread2(getlist)
                    READ

               CASE nAuswahl = 2
                    felderread2(getlist)
                    READ

               CASE nAuswahl = 3
                    EXIT
            ENDCASE
         ENDDO .T.
         WCLOSE()
         RETURN(.T.)
********************************************************************************
FUNCTION felderread2(getlist)
         MEMVAR feld4, feld5, feld6

         cls
         @  5, 1 GET feld4 PICTURE "XXXXX"
         @  6, 1 GET feld5 PICTURE "XXXXX"
         @  7, 1 GET feld6 PICTURE "XXXXX"
         RETURN(.T.)
Und so soll es auch sein. Jetzt kann ich nur hoffen, dass ich möglichst schnell herausfinde, was an dem Originaltext gravierend anders ist, dass es so herummuckt.
Was auf jeden Fall schon mal klar ist, die GET Felder sind in einer Methode. Das dürfte es aber nicht sein. Die Prüf() Routinen sind auch in einer Methode. Alles in dem gleichen Objekt. Wobei natürlich die verschiedenen GET Felder mit den Prüf() Methoden in jeweils einem anderen Objekt stehen. Also in dem Falle wären es dann 2 Objekte
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!!
Antworten