Speicherauslastung [ERLEDIGT]

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

Moderator: Moderatoren

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:

Beitrag von brandelh »

Manfred hat geschrieben:Hi Hubert,
welche Frage meinst Du denn?
Ich warte wenn auf gezielte Frage dazu. Die Vergangenheit hat gezeigt, dass ich meine Fragen nie so genau stellen konnte, als dass sie von allen verstanden wurde. Oder war meine Frage gar nicht gemeint?
Deine Frage war, warum dein Programm langsamer wird bzw. Speicher verbraucht. Ohne Quellcodestudium kann man nur Raten woran es liegen könnte. Das meinte ich.
Gruß
Hubert
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

Beitrag von Manfred »

Hi Hubert,

das war klar. Ich wollte nur bevor ich hier etliches an Code aufliste evtl. schon wissen, ob es generelle Fehler gibt, die man auch ohne Code beschreiben kann. Es hätte ja sein können, dass sowas schon bekannt ist und beim Hybridmodus normal.

Code: Alles auswählen

METHOD vo:AnzeigeStatistikStammdaten(cModus)
       LOCAL nI            := 0
       LOCAL nLen          := 0
       LOCAL nSleBreite    := 60
       LOCAL nSleHoehe     := 20
       LOCAL nStaticBreite := 90
       LOCAL nStaticHoehe  := 20
       LOCAL nX
       LOCAL nY
       LOCAL oVoInhalt
       LOCAL oVostammInhalt
       LOCAL oVostammTexte
       LOCAL oVoTexte
//                               Anzeigetext
       LOCAL aFelderVo      := {;
                                { "Datum Ankauf:"   ,{|| IF(! EMPTY(::datumak)   ,DTOC(::datumak)   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum verkauft:" ,{|| IF(! EMPTY(::datumvk)   ,DTOC(::datumvk)   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum erfasst:"  ,{|| IF(! EMPTY(::datumein)  ,DTOC(::datumein)  ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum geliehen:" ,{|| IF(! EMPTY(::datumleih) ,DTOC(::datumleih) ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum zurück:"   ,{|| IF(! EMPTY(::datumrueck),DTOC(::datumrueck),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum Verleih 1:",{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Datum Verleih L:",{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Lagertage:"      ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Leihmenge:"      ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Leihquote %:"    ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Umsatz Verleih:" ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Beilagen:"       ,{|| IF(::nBeilagen > 0,TRANSFORM(::nBeilagen,"99"),"")},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}};
                               }
       LOCAL aFelderVostamm
       LOCAL nDlgOben       := 525
       LOCAL nDlgUnten      := 85
       LOCAL nDlgLinks      := 635
       LOCAL nDlgRechts

       MEMVAR oBild
       MEMVAR oSysPara
       MEMVAR oVostamm

       aFelderVostamm       := {;
                                { "VO in Bestand:"   ,{|| IF(oVostamm:nStkBestand  > 0,TRANSFORM(oVostamm:nStkBestand ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VO in Reserve:"   ,{|| IF(oVostamm:nReserve     > 0,TRANSFORM(oVostamm:nReserve    ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Datum VÖ:"        ,{|| IF(! EMPTY(oVostamm:datumvoe) ,DTOC(oVostamm:datumvoe) ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum VK 1.:"     ,{|| IF(! EMPTY(oVostamm:dDatumVk1),DTOC(oVostamm:dDatumVk1),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum VK.L.:"     ,{|| IF(! EMPTY(oVostamm:dDatumVkl),DTOC(oVostamm:dDatumVkL),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum Ank.1.:"    ,{|| IF(! EMPTY(oVostamm:dDatumAk1),DTOC(oVostamm:dDatumAk1),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "Datum Ank.L.:"    ,{|| IF(! EMPTY(oVostamm:dDatumAkL),DTOC(oVostamm:dDatumAkL),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                                { "AnkaufpreisMin:"  ,{|| IF(oVostamm:nAKPreisMin    > 0,TRANSFORM(oVostamm:nAkPreisMin  ,"999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "AnkaufpreisMax:"  ,{|| IF(oVostamm:nAKpreisMax    > 0,TRANSFORM(oVostamm:nAkPreisMax  ,"999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Streichdatum:"    ,{|| IF(! EMPTY(oVostamm:datumgestr),DTOC(oVostamm:datumgestr),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VÖ-Tage:"         ,{|| IF(oVostamm:nLagertage     > 0,TRANSFORM(oVostamm:nLagertage   ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Streichtage:"     ,{|| IF(oVostamm:nStreichtage   > 0,TRANSFORM(oVostamm:nStreichtage ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VKStk.Gesamt:"    ,{|| IF(oVostamm:nInternetvk + oVostamm:nLadenvk > 0,TRANSFORM(oVostamm:nInternetvk + oVostamm:nLadenvk,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VO in Ankauf:"    ,{|| IF(oVostamm:nAkMenge       > 0,TRANSFORM(oVostamm:nAkMenge       ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VK.Preis.MaxGes:" ,{|| IF(oVostamm:nVkPreisMax    > 0,TRANSFORM(oVostamm:nVkPreisMax    ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VK.Preis.MinGes:" ,{|| IF(oVostamm:nVkPreisMin    > 0,TRANSFORM(oVostamm:nVkPreisMin    ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VK.Preis.MinIst:" ,{|| IF(oVostamm:nVkPreisMinIst > 0,TRANSFORM(oVostamm:nVkPreisMinIst ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VK.Preis.MaxIst:" ,{|| IF(oVostamm:nVkPreisMaxIst > 0,TRANSFORM(oVostamm:nVkPreisMaxIst ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "Umsatz Gesamt:"   ,{|| IF(oVostamm:nUmsatzGEsamt  > 0,TRANSFORM(oVostamm:nUmsatzGesamt  ,"9999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VKStk.Internet:"  ,{|| IF(oVostamm:nInternetvk    > 0,TRANSFORM(oVostamm:nInternetvk    ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                                { "VKStk.Filiale:"   ,{|| IF(oVostamm:nLadenvk       > 0,TRANSFORM(oVostamm:nLadenvk       ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}};
                               }

       nDlgRechts                       := oSysPara:aWSize[1]-nDlgLinks+20      // Rahmenparameter aus Systemdaten
       IF cModus == "erzeugen"
          ::oDlgMaskeVOStammdaten          := oBild:dialogFenster(SetAppWindow(),,{nDlgLinks,nDlgUnten},{nDlgRechts,nDlgOben},,,.F.)
          ::oDlgMaskeVOStammdaten:titleBar := .F.                               // damit nicht geschlossen werden kann, weil die Icons oben rechts nicht angebracht sins
          ::oDlgMaskeVOStammdaten:border   := XBPDLG_RAISEDBORDERTHIN_FIXED
          ::oDlgMaskeVOStammdaten:configure()
          ::oDlgMaskeVOStammdaten:setFontCompoundName("8.Helv.bold")           // Setzen der Schriftart (welche?)

          ::oFensterVostamm         := XbpStatic():new(::oDlgMaskeVOStammdaten,,{0,(nDlgOben-nDlgUnten)/2+16},{nDlgRechts-5,285})
          ::oFensterVostamm:type    := XBPSTATIC_TYPE_GROUPBOX
          ::oFensterVostamm:caption := " VOSTAMM "
          ::oFensterVostamm:create()

          ::oFensterVo         := XbpStatic():new(::oDlgMaskeVOStammdaten,,{0,0},{nDlgRechts-5,(nDlgOben-nDlgUnten)/2+15})
          ::oFensterVo:type    := XBPSTATIC_TYPE_GROUPBOX
          ::oFensterVo:caption := " VO "
          ::oFensterVo:create()

          ASort(aFelderVo,,,{|aX,aY| aX[1] < aY[1]})                            // jetzt wird der Anzeigetext sortiert
          ASort(aFelderVostamm,,,{|aX,aY| aX[1] < aY[1]})                       // jetzt wird der Anzeigetext sortiert

          nX := 5
          nY := 202
          nLen := LEN(aFelderVo)
          FOR nI := 1 TO nLen
              oVoTexte         := XbpStatic():new(::oFensterVo, , {nX,nY}, aFelderVo[nI,3])
              oVoTexte:caption := aFelderVo[nI,1]
              oVotexte:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
              oVoTexte:create()
              oVoTexte:setFontCompoundName("6.Helv")
              nY -= 20
              IF nI = 11                                                        // nächste Spalte einläuten
                 nY := 202                                                      // wieder oben anfangen
                 nX := 165
              ENDIF
          NEXT
          nX := 5                                                               // wurde oben evtl. die 2 Spalte gesetzt
          nY := 250
          nLen := LEN(aFelderVostamm)
          FOR nI := 1 TO nLen
              oVostammTexte         := XbpStatic():new(::oFensterVostamm, , {nX,nY}, aFelderVostamm[nI,3])
              oVostammTexte:caption := aFelderVostamm[nI,1]
              oVostammTexte:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
              oVostammTexte:create()
              oVostammTexte:setFontCompoundName("6.Helv")
              nY -= 20
              IF nI = 13
                 nY := 250
                 nX := 165
              ENDIF
          NEXT
       ELSE
          ASort(aFelderVo,,Len(aFelderVo),{|aX,aY| aX[1] < aY[1]})              // jetzt wird der Anzeigetext sortiert
          ASort(aFelderVostamm,,Len(aFelderVostamm),{|aX,aY| aX[1] < aY[1]})    // jetzt wird der Anzeigetext sortiert

          nX := 100
          nY := 202
          nLen := LEN(aFelderVo)
          FOR nI := 1 TO nLen
              oVoInhalt          := XbpSLE():new(::oFensterVo, , {nX,nY}, aFelderVo[nI,4])
              oVoInhalt:dataLink := aFelderVo[nI,2]
              oVoInhalt:editable := .F.
              oVoInhalt:align    := XBPSLE_RIGHT
              oVoInhalt:create()
              oVoInhalt:setData()
              oVoInhalt:setFontCompoundName("6.Helv")
              nY -= 20
              IF nI = 11
                 nX := 260
                 nY := 202
              ENDIF
          NEXT
          nX := 100
          nY := 250
          nLen := LEN(aFelderVostamm)
          FOR nI := 1 TO nLen
              oVostammInhalt          := XbpSLE():new(::oFensterVostamm, , {nX,nY}, aFelderVostamm[nI,4])
              oVostammInhalt:dataLink := aFelderVostamm[nI,2]
              oVostammInhalt:editable := .F.
              oVostammInhalt:align    := XBPSLE_RIGHT
              oVostammInhalt:create()
              oVostammInhalt:setData()
              oVostammInhalt:setFontCompoundName("6.Helv")
              nY -= 20
              IF nI = 13
                 nY := 250
                 nX := 260
              ENDIF
          NEXT
          oVostamm:VoStatistikVariablen:init()                                         // alle Daten wieder auf 0 setzen
       ENDIF
RETURN self
Das wäre nun der Anzeigeteil, in dem es wohl passiert.
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: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

was ist VO für eine Klasse ?
Das CRT Fenster ?

Was passiert nach dem Return self, also die Anzeigeschleife und das Ende des Fensters.
Gruß
Hubert
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

Beitrag von Manfred »

Hi Hubert,

VO ist die Klasse, in der die Struktur der DB steht, die Indexstruktur, alle Masken, alle GET Felder usw. Diese Klasse erbt von der Datenbank Klasse, in der die ganzen Methoden für DB öffnen und schließen, Index erzeugen, Strukturprüfung stehen.

Das CRT Fenster ist was ganz anderes.
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: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von brandelh »

Also mit der Methode erzeugst du neue Controls und zeigst sie an.
Aber wie beendest du diese nach der Eingabe ...
Gruß
Hubert
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

Beitrag von Manfred »

Das ist ja das Problem, innerhalb der Anzeigeroutine scheine ich die wohl nicht zu beenden. Die Methode wir jedesmal bei einem Fund aufgerufen. Ich dachte das würde sich alles über die Locals erledigen. Habe ich wohl falsch gedacht, wie?
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: 21211
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Wobei ich jetzt natürlich mit der Frage schwanger gehe, wie, wann und wo sollte ich die Local Objekte plätten? Das ginge doch nur in der Methode selbst, aber da habe ich die Erfahrung gemacht, dass dann bei den oVostammInhalt und oVoInhalt jeweils das letzte SLE auch wieder vom Bildschirm verschwinden, bei dieser Aktion und das ist nicht gewollt.
Oder ich müßte pauschal vorher jedesmal destroyen.
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!!
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Manfred,

mir fällt auf, dass du die SLEs bei jedem Aufruf immer wieder neu erzeugst.

Wie verhält es sich, wenn du in den "else"-Zweig, also für den Fall
! cModus == "erzeugen", folgendes einfügst:

Code: Alles auswählen

aeval( ::oFensterVo:childList(),;
          {|o|iif( o:className()=="XbpSLE", o:destroy(), NIL ) } )
aeval( ::oFensterVostamm:childList(),;
          {|o|iif( o:className()=="XbpSLE", o:destroy(), NIL ) } )

Viele Grüße,
Günter
Zuletzt geändert von Günter Beyes am Mo, 26. Mär 2007 22:02, insgesamt 1-mal geändert.
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

Beitrag von Manfred »

Hi Günter

da haben wir uns überschnitten. Das werde ich mal versuchen.
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!!
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Manfred,

oder du verlegst die Erzeugung der SLEs in den Zweig cModus == "erzeugen" und führt im "else"-Zeig nur :setData() für alle SLEs aus.
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:

Beitrag von Tom »

Nur am Rande, kleine Empfehlung: Statt "o:ClassName" "o:IsDerivedFrom" nutzen, damit spart man sich eine Menge Fehlersucharbeit, wenn man eigene Klassen erzeugt hat.
Herzlich,
Tom
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

Beitrag von Manfred »

Hi Günter,

nur so aus der Hüfte geschossen, geht dass denn überhaupt? Ich habe ja nur jeweils 1 Objekt, was aber immer wieder versetzt und angezeigt wird. Woher soll das Programm nachher wissen, was es wo hinein schreiben soll?
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: 21211
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

@Günter,

der Vorschlag erhöht trotzdem den Speicherverbrauch....
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!!
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Manfred,

das Wiederverwenden der SLEs, ohne sie bei jedem Durchlauf neu zu erzeugen, geht, weil sie beim :create() in der Childlist des jeweiligen Parent "verankert" werden. Deshalb spielt es auch keine Rolle, dass du ein- und dieselbe lokale Hilfsvariable beim Erzeugen mehrerer SLEs verwendest.

Und jedes SLE weiss ja durch seinen eigenen :dataLink, was es anzeigen soll.


@Tom:

Danke, das ist wichtig. Sollte man nicht vergessen...

Viele Grüße,
Günter
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

Beitrag von Manfred »

Hi Günter,

das verstehe ich noch nicht. Kannst Du mir ein paar Takte dazu erklären? Wie müßte ich denn dann vorgehen in meinem Fall?
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: 21211
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 210 Mal
Danksagung erhalten: 67 Mal

Beitrag von Manfred »

Ach so,

mir fiel gerade noch ein: Ich habe pauschal eine Frage an den Support gestellt. Das der Speicher schwindet ist durchaus normal, sollte aber nicht von Dauer sein. (Garbage Collector) Jetzt müßte ich mal testen, wie das bei mir aussieht.

Da dieser Programmabschnitt aber teilweise sehr intensiv genutzt wird, wird der GC wohl nicht so schnell nachkommen den Speicher aufzuräumen.
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: 12911
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben: Das der Speicher schwindet ist durchaus normal, sollte aber nicht von
Dauer sein. (Garbage Collector) Jetzt müßte ich mal testen, wie das bei
mir aussieht.

Da dieser Programmabschnitt aber teilweise sehr intensiv genutzt wird,
wird der GC wohl nicht so schnell nachkommen den Speicher aufzuräumen.
Ich verwende auch eine Menge GUI Elemente in meiner Hybrid Application
und kann das Problem "so" nicht bestätigen. Bis auf die activeX Module
wird der Speicher "sofort" wieder freigegeben d.h. ich kann in Task-
monitor "sehen" wie er von 281 -> 301 -> 280 geht.

Bei "viel" verwendeten GUI Modulen mache ich nur 1x "create" und kein
o:destroy sondern o:hide / o:show damit ich die "wiederverwenden" kann.

Allerdings verwende ich "keine" FOR/NEXT zum Aufbau von XbParts, denn
da hatte ich auch schon mal das Problem das er anfing "RAM" zu "fressen"
ohne den wieder hergeben zu wollen (ist das dass "detached local Problem ? )

gruss by OHR
Jimmy
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Manfred,

wenn du die folgende Zeile unmittelbar vor der RETURN-Anweisung in deine Methode einfügst und die dahinter stehende Prozedur auch irgendwo im .prg unterbringst, und das ganze dann ausführst, siehst du, dass die Prozedur "ZeigeStamm" sämtliche Xbps des Stamm-Fensters im Zugriff hat, die du weiter oben definiert hast, obwohl du der Prozedur nichts weiter übergibst als deren Parent.

Ohne das aeval( oParent:childlist(), {|o|o:destroy() ) wirst du feststellen, dass die in der Messagebox angezeigte Liste immer länger wird.

Bis es irgendwann kracht.

Code: Alles auswählen

ZeigeStammSLEs( ::oFensterVostamm )
und irgendwo anders:

Code: Alles auswählen

PROCEDURE ZeigeStammSLEs( oParent )

LOCAL aChildList := oParent:childList()
LOCAL nMax       := len( aChildlist )
LOCAL cInfo      := "SLEs im Stamm-Fenster " + chr(13) + chr(13)
LOCAL sleClass   := XbpSLE()
LOCAL i
LOCAL aPos

FOR i := 1 TO nMax
    IF aChildList[i]:isDerivedFrom( sleClass )
	   aPos  := aChildList[i]:currentPos()
	   cInfo += ltrim( str( aPos[1] ) ) + ", " + ltrim( str( aPos[2] ) ) + chr(9) + ;
	            '"'+alltrim( aChildList[i]:editBuffer() )+'"' + chr(13)
	ENDIF
NEXT

Im "else"-Zweig würde dies reichen, um die geänderten Daten anzuzeigen:

Code: Alles auswählen

aeval( ::oFensterVo:childList(),;
          {|o|iif( o:isDerivedFrom("XbpSLE"), o:setData(), NIL ) } )
aeval( ::oFensterVostamm:childList(),;
          {|o|iif( o:isDerivedFrom("XbpSLE"), o:setData(), NIL ) } )

Viele Grüße,
Günter
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

Beitrag von Manfred »

Hi,

also jetzt nochmal eine Verständnisfrage:

Genügt es nicht bei LOCALen Objekten, die Funktion zu verlassen und alle LOCALS sind danach weg? Müssen alle Objekte vorher noch destroyed und geNILlt werden?
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: 15699
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 68 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von brandelh »

Hallo Manfred,

nein es reicht nicht ! Xbase++ ist zwar sehr gnädig und oft geht es gut, aber einige Systemresourcen werden nicht automatisch freigegeben, wenn vorher kein destroy() kam. Das könnte zwar von Version zu Version besser geworden sein, aber warum dem Compiler soviel Arbeit machen wenn es nicht sein muss - und sich schwere Fehlersuche einhandeln.

Eine Local Variable die ein Object enthält, ist nichts anderes als eine Adresse (32 Bit Integer), die auf Speicher verweist. Dort stehen Infos zum Object (wie bei Strings der Text). Bei Texten weiß der Compiler meist wann die Verweise beendet sind und räumt auf. Bei Systemresourcen ist das nicht so ohne weiteres möglich. Fonts und Druckerverweise aus diesen Speicherstellen müssen zuerst mit destroy() aufgelöst werden, sonst bleiben sie bis zum richtigen Programmende (manchmal auch länger ;-) -> EXE kann nicht erzeugt werden ...).

Also nochmal bei ...

Code: Alles auswählen

function Test()
   local cTxt := "TXT"
return cTxt 
ist nach dem Retrun alles weg. Aber z.B. bei:

Code: Alles auswählen

...
oPRN := MyPrinter()
...
function MyPrinter()
   local oXbp := XbpPrinter():new():create()
return oXbp 
ist zwar die locale Variable oXbp wahrscheinlich gleich weg, eventuell ist das aber auch eine detached local (das habe ich nicht so genau im Kopf).
Auf jeden Fall aber ist der Rückgabewert (inkl. seinen Verweisen auf Systemresourcen), den man in oPRN speichert solange im Speicher, bis oPRN:destroy() die Systemresourcen freigibt.
Danach ist oPRN nur noch ein leeres ObjeKt-Gebilde wie nach new().

Am Besten einprägen, dass man alles wieder destroyed, was man nicht mehr braucht, wobei das destroy() des Fensters auch alle Childs automatisch destroyed().

Ein C/C++ Programmierer muss allen Speicher erst reservieren und danach wieder freigeben, wobei bei C++ da Klassen helfen sollen (ich kann es nicht, nur vom hören sagen ;-) )
Gruß
Hubert
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Beitrag von Günter Beyes »

Hallo Manfred,

wenn du in einer Funktion XBPs erzeugst und diese in lokalen Variablen ablegst, sind die XBPs nicht weg, wenn die Funktion verlassen wird.

Das liegt daran, dass der :create()-Aufruf beim Betriebssystem Arbeitsspeicher anfordert, und dieser sollte per :destroy() explizit wieder freigegeben werden, sobald das XBP nicht mehr benötigt wird. Wenn es sich um Fenster handelt (alles, was von XbpWindow abgeleitet ist), befindet sich außerdem eine Kopie in der :childList() des jeweiligen Parent und bleibt auch beim Verlassen der Funktion dort erhalten.

Ohne :destroy() wird der belegte Arbeitsspeicher erst bei Programmende freigegeben; darum kümmert sich das Betriebssystem.

Eine lokale Variable nach :destroy() zu NILen, kann nicht schaden, ist aber nach meiner Meinung überflüssig.

Viele Grüße,
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:

Beitrag von brandelh »

Günter Beyes hat geschrieben:Eine lokale Variable nach :destroy() zu NILen, kann nicht schaden, ist aber nach meiner Meinung überflüssig.
Ich setze Variabeln nur dann direkt zurück, wenn es wirklich große Texte waren und nach dem Gebrauch noch einige andere Dinge getan werden bis die Funktion verlassen wird.

z.B. lese ich regelmäßig 400 bis 600 MB Dateien in eine cVar ein und bearbeite Sie mit StrTran() ... sobald nun der neue Wert feststeht, speichere ich diesen in der Datei und setze den Buffer auf "" oder NIL, bevor die anderen Abschlussarbeiten erfolgen. Somit muss der GC nicht warten bis die Funktion zu ende ist. Ob es sich tatsächlich in Rechenzeit auszahlt, kann ich aber nicht wirklich sagen. Dieser Rechner hat 2 Gigabyte Hauptspeicher.
Gruß
Hubert
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

Beitrag von Manfred »

Hi,

besten Dank ihr beiden. Ich werde dann meinen Code ein wenig überarbeiten müssen. Im Nachhinein betrachtet klingt es auch verständlich.
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!!
Juergen
UDF-Programmierer
UDF-Programmierer
Beiträge: 92
Registriert: Di, 19. Dez 2006 19:37
Wohnort: Düsseldorf
Kontaktdaten:

Speierauslastung unter xBase

Beitrag von Juergen »

Hallo Manfred,

zur Speicherauslastung möchte ich folgendes sagen:

eine der großen Stärken von Alaska Xbase++ ist die Multiprozess-Fähigkeit.
Alle anderen Programmiersprachen, haben da so ihre Probleme.

Ich stand als alter Clipper-Hase vor dem Problem, dass die Datenbanken mehrfach
geöffnet werden mussten, Stichwort MDI-Anwendung.

Ich wollte aber meine alten Strukturen möglichst erhalten.

Also lasse ich z. B. die Kundenverwaltung, den Firmenstamm, die Artikelverwaltung
usw. in einem eigenen Prozess laufen.

Diese Vorgehensweise war eine unglaubliche Erleichterung, z. B. gegenüber einem
VO-Programmierer. Hier müssen die einzelnen Datenbanken streng in Klassen
gekapselt werden.

Außerdem konnte ich bedenkenlos meine geliebten Private-Variablen weiter verwenden.

Denn nach Schließen des Prozesses wird der gesamte Adressraum freigegeben.

Wichtig: Funktioniert nur mit Private und Local.

Aus diesem Grunde habe ich bis heute keinerlei Speicherprobleme mit meinen
Programmen. Ich habe auch keinerlei Klagen von meinen Kunden gehört.

Gruß

Jürgen
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

Beitrag von Manfred »

Hi,

nachdem Martin mir gestern auf dem XUG Osnabrück Treffen einen dicken fetten Tipp gab, habe ich oben angeführten Code um einiges geändert. Das Problem ist auch jetzt von mir mehr nachvollziehbar als noch vor ein paar Tagen, sprich ich verstehe was ich da falsch gemacht habe. Jetzt habe ich aber noch einen kleinen Haken an der Sache:

Code: Alles auswählen

METHOD vo:AnzeigeStatistikStammdaten(cModus)
       LOCAL nI            := 0
       LOCAL nLen          := 0
       LOCAL nSleBreite    := 60
       LOCAL nSleHoehe     := 20
       LOCAL nStaticBreite := 90
       LOCAL nStaticHoehe  := 20
       LOCAL nX
       LOCAL nY
       LOCAL nSleX
       LOCAL nSleY
       LOCAL nDlgOben       := 525
       LOCAL nDlgUnten      := 85
       LOCAL nDlgLinks      := 635
       LOCAL nDlgRechts

       MEMVAR oBild
       MEMVAR oSysPara
       MEMVAR oVostamm

       nDlgRechts := oSysPara:aWSize[1]-nDlgLinks+20                            // Rahmenparameter aus Systemdaten
       IF cModus == "erzeugen"
          ::aFelderVo   := {;
                            { "Datum Ankauf:"   ,{|| IF(! EMPTY(::datumak)   ,DTOC(::datumak)   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                            { "Datum verkauft:" ,{|| IF(! EMPTY(::datumvk)   ,DTOC(::datumvk)   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                            { "Datum erfasst:"  ,{|| IF(! EMPTY(::datumein)  ,DTOC(::datumein)  ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                            { "Datum geliehen:" ,{|| IF(! EMPTY(::datumleih) ,DTOC(::datumleih) ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                            { "Datum zurück:"   ,{|| IF(! EMPTY(::datumrueck),DTOC(::datumrueck),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                            { "Datum Verleih 1:",{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Datum Verleih L:",{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Lagertage:"      ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Leihmenge:"      ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Leihquote %:"    ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Umsatz Verleih:" ,{|| ""},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                            { "Beilagen:"       ,{|| IF(::nBeilagen > 0,TRANSFORM(::nBeilagen,"99"),"")},{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}};
                           }
          ::aFelderVostamm := {;
                               { "VO in Bestand:"   ,{|| IF(oVostamm:nStkBestand  > 0,TRANSFORM(oVostamm:nStkBestand ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VO in Reserve:"   ,{|| IF(oVostamm:nReserve     > 0,TRANSFORM(oVostamm:nReserve    ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "Datum VÖ:"        ,{|| IF(! EMPTY(oVostamm:datumvoe) ,DTOC(oVostamm:datumvoe) ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                               { "Datum VK 1.:"     ,{|| IF(! EMPTY(oVostamm:dDatumVk1),DTOC(oVostamm:dDatumVk1),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                               { "Datum VK.L.:"     ,{|| IF(! EMPTY(oVostamm:dDatumVkl),DTOC(oVostamm:dDatumVkL),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                               { "Datum Ank.1.:"    ,{|| IF(! EMPTY(oVostamm:dDatumAk1),DTOC(oVostamm:dDatumAk1),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                               { "Datum Ank.L.:"    ,{|| IF(! EMPTY(oVostamm:dDatumAkL),DTOC(oVostamm:dDatumAkL),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe} },;
                               { "AnkaufpreisMin:"  ,{|| IF(oVostamm:nAKPreisMin    > 0,TRANSFORM(oVostamm:nAkPreisMin  ,"999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "AnkaufpreisMax:"  ,{|| IF(oVostamm:nAKpreisMax    > 0,TRANSFORM(oVostamm:nAkPreisMax  ,"999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "Streichdatum:"    ,{|| IF(! EMPTY(oVostamm:datumgestr),DTOC(oVostamm:datumgestr),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VÖ-Tage:"         ,{|| IF(oVostamm:nLagertage     > 0,TRANSFORM(oVostamm:nLagertage   ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "Streichtage:"     ,{|| IF(oVostamm:nStreichtage   > 0,TRANSFORM(oVostamm:nStreichtage ,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VKStk.Gesamt:"    ,{|| IF(oVostamm:nInternetvk + oVostamm:nLadenvk > 0,TRANSFORM(oVostamm:nInternetvk + oVostamm:nLadenvk,"9999"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VO in Ankauf:"    ,{|| IF(oVostamm:nAkMenge       > 0,TRANSFORM(oVostamm:nAkMenge       ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VK.Preis.MaxGes:" ,{|| IF(oVostamm:nVkPreisMax    > 0,TRANSFORM(oVostamm:nVkPreisMax    ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VK.Preis.MinGes:" ,{|| IF(oVostamm:nVkPreisMin    > 0,TRANSFORM(oVostamm:nVkPreisMin    ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VK.Preis.MinIst:" ,{|| IF(oVostamm:nVkPreisMinIst > 0,TRANSFORM(oVostamm:nVkPreisMinIst ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VK.Preis.MaxIst:" ,{|| IF(oVostamm:nVkPreisMaxIst > 0,TRANSFORM(oVostamm:nVkPreisMaxIst ,"999.99") ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "Umsatz Gesamt:"   ,{|| IF(oVostamm:nUmsatzGEsamt  > 0,TRANSFORM(oVostamm:nUmsatzGesamt  ,"9999.99"),"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VKStk.Internet:"  ,{|| IF(oVostamm:nInternetvk    > 0,TRANSFORM(oVostamm:nInternetvk    ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}},;
                               { "VKStk.Filiale:"   ,{|| IF(oVostamm:nLadenvk       > 0,TRANSFORM(oVostamm:nLadenvk       ,"9999")   ,"") },{nStaticBreite,nStaticHoehe},{nSleBreite,nSleHoehe}};
                              }
          ::oDlgMaskeVOStammdaten          := oBild:dialogFenster(SetAppWindow(),,{nDlgLinks,nDlgUnten},{nDlgRechts,nDlgOben},,,.F.)
          ::oDlgMaskeVOStammdaten:titleBar := .F.   // damit nicht geschlossen werden kann, weil die Icons oben rechts nicht angebracht sins
          ::oDlgMaskeVOStammdaten:border   := XBPDLG_RAISEDBORDERTHIN_FIXED
          ::oDlgMaskeVOStammdaten:configure()
          ::oDlgMaskeVOStammdaten:setFontCompoundName("8.Helv.bold")           // Setzen der Schriftart (welche?)

          ::oFensterVostamm         := XbpStatic():new(::oDlgMaskeVOStammdaten,,{0,(nDlgOben-nDlgUnten)/2+16},{nDlgRechts-5,285})
          ::oFensterVostamm:type    := XBPSTATIC_TYPE_GROUPBOX
          ::oFensterVostamm:caption := " VOSTAMM "
          ::oFensterVostamm:create()

          ::oFensterVo         := XbpStatic():new(::oDlgMaskeVOStammdaten,,{0,0},{nDlgRechts-5,(nDlgOben-nDlgUnten)/2+15})
          ::oFensterVo:type    := XBPSTATIC_TYPE_GROUPBOX
          ::oFensterVo:caption := " VO "
          ::oFensterVo:create()

          ASort(::aFelderVo,,,{|aX,aY| aX[1] < aY[1]})     // jetzt wird der Anzeigetext sortiert
          ASort(::aFelderVostamm,,,{|aX,aY| aX[1] < aY[1]})     // jetzt wird der Anzeigetext sortiert

          nX    := 5
          nY    := 202
          nSleX := 100
          nSleY := 202
          nLen := LEN(::aFelderVo)
          FOR nI := 1 TO nLen
              ::oVoTexte           := XbpStatic():new(::oFensterVo, , {nX,nY}, ::aFelderVo[nI,3])
              ::oVoInhalt          := XbpSLE():new(::oFensterVo, , {nSleX,nSleY}, ::aFelderVo[nI,4])
              ::oVoInhalt:dataLink := {||::aFelderVo[nI,2]}
              ::oVoInhalt:editable := .F.
              ::oVoInhalt:align    := XBPSLE_RIGHT
              ::oVoTexte:caption := ::aFelderVo[nI,1]
              ::oVotexte:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
              ::oVoTexte:create()
              ::oVoInhalt:create()
              ::oVoTexte:setFontCompoundName("6.Helv")
              ::oVoInhalt:setFontCompoundName("6.Helv")
              nY -= 20
              nSleY -= 20
              IF nI = 11                                                        // nächste Spalte einläuten
                 nY    := 202                                                      // wieder oben anfangen
                 nSleY := 202
                 nSleX := 260
                 nX := 165
              ENDIF
          NEXT
          nSleX := 100
          nSleY := 250
          nX    := 5                                                   // wurde oben evtl. die 2 Spalte gesetzt
          nY    := 250
          nLen := LEN(::aFelderVostamm)
          FOR nI := 1 TO nLen
              ::oVostammTexte         := XbpStatic():new(::oFensterVostamm, , {nX,nY}, ::aFelderVostamm[nI,3])
              ::oVostammTexte:caption := ::aFelderVostamm[nI,1]
              ::oVostammTexte:options := XBPSTATIC_TEXT_VCENTER+XBPSTATIC_TEXT_RIGHT
              ::oVostammTexte:create()
              ::oVostammTexte:setFontCompoundName("6.Helv")
              ::oVostammInhalt          := XbpSLE():new(::oFensterVostamm, , {nSleX,nSleY}, ::aFelderVostamm[nI,4])
              ::oVostammInhalt:dataLink := {||::aFelderVostamm[nI,2]}
              ::oVostammInhalt:editable := .F.
              ::oVostammInhalt:align    := XBPSLE_RIGHT
              ::oVostammInhalt:create()
              ::oVostammInhalt:setFontCompoundName("6.Helv")
              nY -= 20
              nSleY -=20
              IF nI = 13
                 nY    := 250
                 nX    := 165
                 nSleY := 250
                 nSleX := 260
              ENDIF
          NEXT
       ELSE
          nLen := LEN(::aFelderVo)
          FOR nI := 1 TO nLen
              ::oVoInhalt:setData()
              ::oVoinhalt:configure()
              ::oVostammInhalt:setData()
              ::oVostammInhalt:configure()
          NEXT
          oVostamm:VoStatistikVariablen:init()            // alle Daten wieder auf 0 setzen
       ENDIF
RETURN self
innerhalb des Else bei ::oVoInhalt:setData() kommt eine Fehlermeldung:

Fehler bei der Arrayindizierung.

Ich habe keine Ahnung, was da verkehrt läuft.
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