Addcolumn() und codeblöcke

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

Moderator: Moderatoren

saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Hallo,
gestern habe ich groß geschrieben, dass ich es verstanden habe, heute kommt der Niederschlag.
Bei den Buttons funktioniert dieser Code

Code: Alles auswählen

For I = 1 to len(::abuttons)
  ::oButton1:= XbpPushButton():new(::drawingArea , , {46,3}, )
  ::oButton1:caption := "   "+::abuttons[i,1]+"   "
***  ::oButton1:activate := {|| PostAppEvent(nEvent, ASC(aElems[nI, 2]))}  // gab Array Fehler
  ::oButton1:activate := Blockify(xbeP_Keyboard, ::abuttons, i)                // hier wird in der Funktion der Codeblock gebildet
next

STATIC FUNCTION Blockify(nEvent, aElems, nI)
  Local bBlock
  bBlock := {|| PostAppEvent(nEvent, ASC(aElems[nI, 2]))}     // in Variable damit es später im Debugger sehen kann
RETURN (bBlock)
Es werden so viele Buttons erzeugt wie aButtons Inhalte hat. Also ich nicht faul und habe die Spaltenbildung des Array Browse in For next umgeschrieben. Funktionierende Zeilen bisher

Code: Alles auswählen

::ABrowse:AddColumn ( {|| ::aData[::nRecno,1] }, ::aSpaltendaten[1,2] , ::aSpaltendaten[1,1]  )
::ABrowse:AddColumn ( {|| ::aData[::nRecno,2] }, ::aSpaltendaten[2,2] , ::aSpaltendaten[2,1]  )
::ABrowse:AddColumn ( {|| ::aData[::nRecno,3] }, ::aSpaltendaten[3,2] , ::aSpaltendaten[3,1]  )
::ABrowse:AddColumn ( {|| ::aData[::nRecno,4] }, ::aSpaltendaten[4,2] , ::aSpaltendaten[4,1]  )
erzeugte 4 Spalten umgeschrieben in

Code: Alles auswählen

For I = 1 to 4
** ::ABrowse:AddColumn ( {|| ::aData[::nRecno,i] }, ::aSpaltendaten[i,2]+2  , ::aSpaltendaten[i,1] )  
   // funktioniert nicht, gab einen Arrayfehler, was wegen dem gelernten zu vermuten war

  ::ABrowse:AddColumn ( Blockifyarray(::aData, ::nRecno, i) , ::aSpaltendaten[i,2]+2 , ::aSpaltendaten[i,1]  )  
  // funktioniert auch nicht, Spalten richtig, aber jede Zeile enthält die Daten der 1. Arrayzeile. Da stimmt was mit ::nRecno 
  // nicht oder?
next

STATIC FUNCTION Blockifyarray(aDaten, nrecnr, nI)
  Local bBlock
  bBlock := {|| aDaten[nRecnr,nI] }
return (bBlock)
Zumindest meine ich das das gelernte umgesetzt zu haben.
Warum funtioniert das mit der Funktion hier nicht?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2826
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Addcolumn() und codeblöcke

Beitrag von georg »

Hallo, Wolfgang -


Du solltest ::nRecno nicht an Blockify übergeben, da der Browser auf den aktuellen Wert zugreifen soll.

Blockify sollte nur solche Werte empfangen, die "eingefroren" sind, wie die "2" für die zweite Spalte.

Code: Alles auswählen

STATIC FUNCTION Blockifyarray(aDaten, self, nI)
  Local bBlock
  bBlock := {|| aDaten[self:nRecno,nI] }
return (bBlock)
Das könnte funktionieren (Du musst auch das AddColumn anpassen, was die Parameter angeht).

Faustregel: Schleifenvariablen (wie I in diesem Fall) müssen über eine Blockify Function detached werden (aus ihrem Kontext gelöst). Variablen, die sich ändern sollen (wie self:nRecno) dürften nicht detached werden, da dann ihr Wert "eingefroren" wird.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Hallo,
ich habe folgendes zusammengebaut.

Code: Alles auswählen

::ABrowse:AddColumn ( Blockifyarray(::aData, self, i) , ::aSpaltendaten[i,2]+2 , ::aSpaltendaten[i,1]  )

STATIC FUNCTION Blockifyarray(aDaten, self, nI)
  Local bBlock
  bBlock := {|| aDaten[self:nRecnr,nI] }
return (bBlock)
Diese Variante funktioniert. Über self habe ich nicht viel in Erfahrung gebracht. Es taucht in der Hilfe überall auf aber meistens ohne Erklärung. Nur beim Operator :: bin ich fündig geworden.
self
Der Sende-Operator :: sendet nur Nachrichten an das Objekt, das in der Variable namens self innerhalb des Programmcodes von Methoden referenziert ist.
Verstanden habe ich das aber nicht. Die Variable self habe ich in meinem Programm nie belegt.

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2826
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Addcolumn() und codeblöcke

Beitrag von georg »

Hallo, Wolfgang -


wenn Du eine Klasse erstellst, gibt es implizit in jeder Methode eine automatisch generierte Variable self, die für Bezugnahmen auf das Objekt selbst (= self) ermöglicht.

Stell Dir vor, Du schreibst den Code für eine Methode. Nun musst Du auf die Instanzvariable aData zugreifen. Wie machst Du das? Entweder über ::aData, oder self:aData. :: ist eine Verkürzung, die meines Wissens von Class(y) herkommt und von Alaska aus Kompatibilitätsgründen übernommen wurde.

Code: Alles auswählen

:: == self:
Ich schreibe mir die Finger wund, und es gibt Programmierer, die einfach keinen Debugger benutzen wollen, aber wenn Du die Erstellung Deiner Klasse im Debugger verfolgst und unter Monitor LOCAL aktivierst, wirst Du vielleicht das ein oder andere besser verstehen. Ich habe mir vieles über den Debugger erarbeitet, was ich heute bei der Programmierung einsetze. Versuche es einfach mal!


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Alles wieder zurück

Code: Alles auswählen

::ABrowse:AddColumn ( Blockifyarray(::aData, self, i) , ::aSpaltendaten[i,2]+2 , ::aSpaltendaten[i,1]  )

STATIC FUNCTION Blockifyarray(aDaten, self, nI)
  Local bBlock
  bBlock := {|| aDaten[self:nRecno,nI] }     // gibt Fehlermeldung Parameter hat falschen Typ,
return (bBlock)
Funktioniert doch nicht, ich war im falschen Objekt. Die Fehlermeldung verstehe ich nicht ganz, da ja Self:nRecno bereits in der Methode, von der ich Blockifyarray aufrufe, definiert wurde.

Das mit dem Debugger stimmt bestimmt, aber da arbeite ich mich erst noch ein. Aber Variable, die ich falsch erstelle/belege kann ich ja auch nicht sehen oder?

Code: Alles auswählen

[PROJECT]
    COMPILE       = xpp
    COMPILE_FLAGS = /b /n /q
    DEBUG         = yes
    GUI           = yes
    LINKER        = alink
    LINK_FLAGS    = /DE
    RC_COMPILE    = arc
    RC_FLAGS      = /v
    OBJ_DIR       = \fueralle
    PROJECT.XPJ

[PROJECT.XPJ]
    F:\LFZZEIT\EDFC19\LFZZEITW.EXE
Rufe ich xppdbg auf fragt mit der Debugger nach dem Programmnamen dann tut sich nix auf dem Bildschirm, nur der Bildschirm des Debuggers steht dort und reagiert auf nix. Gemäß Hilfe muß mit /b compeliert werden und /DE gelinkt werden. Beide meine ich gemacht zu haben.

mfg
Wolfgang
Dateianhänge
Unbenannt - 1.jpg
Unbenannt - 1.jpg (79.75 KiB) 7563 mal betrachtet
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2826
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Addcolumn() und codeblöcke

Beitrag von georg »

Hallo, Wolfgang -


so sehen die Einstellung bei mir normalerweise aus:

Code: Alles auswählen

[PROJECT]
    COMPILE       = xpp
    COMPILE_FLAGS = /p /q /w /wl /wu
    DEBUG         = yes
    GUI           = yes
    LINKER        = alink
    LINK_FLAGS    = /PM:PM
    RC_COMPILE    = arc
    RC_FLAGS      = /v
    PROJECT.XPJ
Ansonsten starte ich den Debugger mit

Code: Alles auswählen

xppdbg programm
in dem Verzeichnis, in dem sich das Programm befindet.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Habe Deine Einstellungen übernommen. da tut sich nix. Kann das was mit dem CRT Fenster zu tun haben in dem ich starte?

mfg
Wolfgang
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Habe mal schnell ein anderes Programm mit meiner project.xpi und 3-4 Variableneingaben gemacht. Damit funktioniert der Debugger. Gibt es das, dass der Debugger bestimmten Programmcode nicht akzeptiert und sich dann aufhängt?
Vielleicht sind meine Programme so schlecht, dass er sich deshalb aufhängt? Kann ein Debugger suizidgefährdet sein?

Hättest Du wenigstens einen kleinen Tipp bezüglich meines For next Problems? Sonst kann ich ich garnicht schlafen.

mfg
Wolfgang
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von UliTs »

Hallo Wolfgang,

ich würde "self" grundsätzlich nicht als Parameternamen verwenden, auch wenn es Alaska ursprünglich (leider) oft in der Dokumentation gemacht hat:

Code: Alles auswählen

STATIC FUNCTION Blockifyarray(aDaten, self, nI)
  Local bBlock
  bBlock := {|| aDaten[self:nRecno,nI] }     // gibt Fehlermeldung Parameter hat falschen Typ,
return (bBlock)
Wenn Deine Klasse z.B. MeineKlasse() heißt, würde ich den Parameter oMeineKlasse nennen:

Code: Alles auswählen

STATIC FUNCTION Blockifyarray(aDaten, oMeineKlasse, nI)
  Local bBlock
  bBlock := {|| aDaten[oMeineKlasse:nRecno,nI] }     // gibt Fehlermeldung Parameter hat falschen Typ,
return (bBlock)
Wie lautet denn die genaue Fehlermeldung? Kann es sein, dass oMeineKlasse den Wert NIL hat?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Guten Morgen,
die Klasse heißt ArrayBrowse. Dies habe jetzt eingesetzt als ::ArrayBrowse eingesetzt

Code: Alles auswählen

For I = 1 to len(::aSpaltendaten)
  ::ABrowse:AddColumn ( Blockifyarray(::aData, ::ArrayBrowse, i) , ::aSpaltendaten[i,2]+2 , ::aSpaltendaten[i,1]  )
next

STATIC FUNCTION Blockifyarray(aDaten, ArrayBrowse, nI)
  Local bBlock
  bBlock := {|| aDaten[ArrayBrowse:nRecno,nI] }
return (bBlock)
Funktioniert. Das war scheinbar das Problem, warum auch immer.
Aber der Debugger funktioniert immer noch nicht. Gibt es Code mit dem der Debugger nicht läuft?

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2826
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Addcolumn() und codeblöcke

Beitrag von georg »

Guten Morgen, Wolfgang -


in Sachen Debugger:

versuche mal ein

pbuild /a
xppdbg program


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Gleicher Effekt beim Debugger.

mfg
Wolfgang
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2826
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Addcolumn() und codeblöcke

Beitrag von georg »

Hallo, Wolfgang -


welche Version von Xbase setzt Du ein? Falls Du VX hast, da ist auch ein Debugger mit integriert, es eventuell mal damit versucht?


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Ich glaube das habe ich. War zumindest auf einer CD drauf. Muß ich aber noch isntallieren oder so ähnlich.

mfg
Wolfgang
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von UliTs »

saul hat geschrieben:...die Klasse heißt ArrayBrowse. Dies habe jetzt eingesetzt als ::ArrayBrowse eingesetzt

Code: Alles auswählen

...[/quote]
Ich würde den Parameter oArrayBrowse statt ArrayBrowse nennen. Dann sieht man auf einen Blick, dass es sich um eine Klasse handelt und auf den zweiten, dass eine Klasse ArrayBrowse bzw. eine davon abgeleitete Klasse erwartet wird  :) .

Zu Deinem "Warum auch immer":
Wie Georg schon mehrfach sagte, entspricht self==:: .
Ich vermute, der Präprozessor von xBase++ kommt innerhalb Funktionen durcheinander, wenn man einen Parameter als "self" bezeichnet und wandelt self in :: um. Und dann muß es zu einer Compilerfehlermeldung kommen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von brandelh »

Hi,

die Codeblocks sind eine feine Sache, aber man sollte es mit code darin nicht übertreiben.
Insbesondere Verweise auf SELF haben das Problem, dass das Objekt das SELF einmal
erzeugt hat im konkreten Ausführungsfall des Codeblocks nicht unbedingt mehr existieren muss.

Ich rufe in Codeblocks für allgemeingültige Arbeiten Funktionen auf, dort kann man dann wieder debuggen.
Bei Fenstern und Funktionenen die sich auf diese beziehen, rufe ich METHODEN dieses Fensters auf und man spart sich all
die üblen Parameter Sachen. Eine Methode KENNT :: (self), da sie selbst ja auch zu dem Fenster gehört.
Sie kennt auch die Controls dieses Fensters !

Darum auch immer mein Hinweis mit dem XppFD CLASS-CODE zu erzeugen.

Der Function-Code geht meist auch, aber schon wenn man nachträglich einen Button ändern will, hat man ein Problem.
Gruß
Hubert
saul
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 284
Registriert: So, 26. Mär 2006 12:23

Re: Addcolumn() und codeblöcke

Beitrag von saul »

Da bin ich dabei die Notation zu berücksichtigen.

mfg
Wolfgang
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von Martin Altmann »

Wolfgang, hast Du denn den /DEBUG-Schalter beim Compilieren mit angegeben? Ohne dem wird der Debugger nicht gehen!
Viele Grüße,
Martin.
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von brandelh »

oder besser gleich lernen wie man PBUILD nutzt ;-)

1. Alle INCLUDE "?.PRG" Zeilen löschen
2. "SET PROCEDURE TO [<cProgFile>]" Zeilen löschen.
3. Alle PRG in ein Verzeichnis, sonst ist er aktuell überfordert.
4. dir /b *.PRG > NameMeinerExe.TXT
5. pbuild @NameMeinerExe.TXT
6. pbuild /g ( bei Fehlern, diese beseitigen ! )
7. Jetzt kann man ganz einfach DEBUG = YES setzen in der PROJECT.XBP ... und er compiliert nur noch geänderte bzw. abhängige Dateien.
8. PBUILD bzw. PBUILD /A
9. Wenn man die Fehler einfacher lesen will: PBUILD /A > Fehler.txt
Gruß
Hubert
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von UliTs »

brandelh hat geschrieben:3. Alle PRG in ein Verzeichnis, sonst ist er aktuell überfordert.
Hubert, was meinst Du denn damit?
Ich habe meine Prg's in verschiedenen Verzeichnissen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von brandelh »

Ich meinte alle PRG eines Programmes / Projektes.
Aber eventuell kommt er heute auch damit zurecht wenn diese wo anders liegen,
früher hat er die OBJ immer zu den PRG kompiliert und beim linken gesucht.

Zeig doch mal eine XBP Datei mit verschiedenen Verzeichnissen ...
Gruß
Hubert
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von UliTs »

[PROJECT]
COMPILE = xpp
COMPILE_FLAGS = /q /m /n /w
DEBUG = yes
GUI = no
LINKER = alink
RC_COMPILE = arc
RC_FLAGS = -v
OBJ_DIR = .\OBJ
LINK_FLAGS = /PM:PM /OUT:.\Exe\MyProgram.exe /STACK:10000000,5000000
PROJECT.XPJ

[PROJECT.XPJ]
MyProgram.exe

[MyProgram.exe]
// $START-AUTODEPEND
COLLAT.CH
.\..\..\Global\Res\UTs.ch
.\Source\Lagerort\_Dlg1.prg
.\Source\Dialoge\_Dlg2.prg
...
// $STOP-AUTODEPEND
.\..\..\Global\Res\XPPPDF1.lib

.\Source\Lager\cAuswert.prg
.\Source\Lager\cLagvzw.prg

.\Source\LAG_LAB\ETIKETTE.prg

.\Source\ARTIKEL\artikel.prg

.\Source\ANGEBOT\ANHAUPT.prg
.\Source\ANGEBOT\ANHAUPT2.prg
.\Source\ANGEBOT\ANHAUPT3.prg

.\Source\Lagerort\Dlg1.prg
.\Source\Dialoge\Dlg2.prg

.\Source\Drucken\LfDrucken.prg

.\..\..\Global\Fkt.prg
Ein kleiner Ausschnitt :-) . Tatsächlich sind es 340 Zeilen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 265
Registriert: Do, 22. Nov 2007 9:02
Wohnort: Leipzig
Hat sich bedankt: 66 Mal
Danksagung erhalten: 22 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von dtmackenzie »

Tom hat geschrieben: Mo, 10. Sep 2012 12:10 Vielleicht noch zum Verständnis.

Ein Codeblock ist verdichteter Code, repräsentiert durch einen eigenen Datentypen (ValType liefert "B"). An und für sich macht ein Codeblock erst einmal überhaupt nichts, etwa im Moment der Erzeugung oder Zuweisung:

Code: Alles auswählen

bBlock := {||MachWas()}
Hier geschieht nicht viel - es wird eine Variable "bBlock" vom Datentyp "B" (Codeblock) erzeugt, die Code enthält. Mehr passiert nicht. Der Code in einem Codeblock kann sehr (beliebig) komplex sein, er darf nur keine Anweisungen enthalten, etwa "DELETE" oder auch "FOR ... NEXT". Dafür gibt es Funktionen (DbDelete) oder entsprechende Repräsentationen (aEval), schlussendlich kann ein Codeblock aber auch auf eine Funktion verweisen, in der alles mögliche passiert. Nichtsdestotrotz: Im Moment seiner "Herstellung" macht der Codeblock überhaupt nichts. Er wird lediglich einer Variablen zugewiesen, was natürlich auch die Instanzvariable eines Objekts oder ein sog. "Slot" sein kann, also die iVar einer Klasse, die mit Codeblöcken bestückt werden kann oder sollte. Mache ich aber das hier:

Eval(bBlock)

wird der Code in "bBlock" ausgeführt. Genau das geschieht auch mit den Slots, wie "Datalink", "ColorBlock", "ItemMarked" usw. in der XbpBrowse-Klasse. Ein Event wird ausgelöst oder ein bestimmter Zustand tritt ein, und der Code im Slot wird abgerufen und ausgeführt. Hierfür stehen ggf. noch Parameter zur Verfügung (siehe Doku), die der Codeblock-Code verwenden kann, beispielsweise Referenzen auf das Klassenobjekt, um mit diesem arbeiten zu können.

Wichtig und entscheidend ist also, dass der Code im Codeblock quasi "losgelöst" ist. Was im Moment der Herstellung noch richtig und relevant war, muss im Moment der Ausführung/Evaluierung nicht mehr der Fall sein, denn der Code im Block ist hiervon unabhängig. Ich kann ihn auch ganz woanders ausführen. Deshalb muss dieser Code immer für sich funktionieren, und an dieser Stelle wird es dann eben schwierig, wenn man Codeblöcke in Iterationen erzeugen will. Alle Referenzen, die innerhalb der Iteration gültig waren, sind es im Moment der Codeblock-Evaluierung sehr wahrscheinlich nicht mehr, weshalb schon ein simpler Schleifenzähler im Block nahezu zwangsweise zu Fehlverhalten führt. Man kann ihn aber beispielsweise bei der Erzeugung von Browsespalten auch im Cargo-Slot der Column platzieren, um dann im Codeblock-Code darauf zugreifen zu können. Wichtig ist, dass man sich dieser Tatsache bewusst ist: Der Code im Block wird nicht im Moment der Herstellung ausgeführt, sondern später - und übrigens auch beliebig oft.
Hallo Tom,

in 2 Monaten gehe ich in Rente, dies ist vielleicht mein letzter Post...

Ich hatte das gleiche Problem wie der OP, konnte es aber nicht mit :cargo lösen weil SELF nicht ging im Browser.
Man kann es aber anders lösen in dem man alles "links" dreht und der gesamte Codeblock mit einem Makro erzeugt, anstatt zu versuchen, ein Makro innerhalb des Codeblocks zu nutzen.
Also, etwa so:

Code: Alles auswählen

FOR i := 1 TO LEN(aColumns)
    cColumn := aColumns[i]
    browse:addColumn(TBColumnNew(UPPER(cColumn),;
                                 &("{|| " + cColumn + "}") ))
NEXT
Gefällt mir ehrlich gesagt besser als :cargo.
Viele Grüße,
David
Benutzeravatar
Marcus Herz
1000 working lines a day
1000 working lines a day
Beiträge: 852
Registriert: Mo, 16. Jan 2006 8:13
Wohnort: Allgäu
Hat sich bedankt: 39 Mal
Danksagung erhalten: 192 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von Marcus Herz »

oder "detached funktion"

Code: Alles auswählen

FOR i := 1 TO LEN(aColumns)
    cColumn := aColumns[i]
    browse:addColumn(crtBlock(cColumn))
NEXT
// hier wird Schleifen Wert cColumn wieder lokal
STATIC FUNC crtBlock(cColumn)
RETURN TBColumnNew(UPPER(cColumn),  {||  cColumn })
Gruß Marcus

Erkenne, was du findest, dann weißt du, wonach du gesucht hast
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 265
Registriert: Do, 22. Nov 2007 9:02
Wohnort: Leipzig
Hat sich bedankt: 66 Mal
Danksagung erhalten: 22 Mal
Kontaktdaten:

Re: Addcolumn() und codeblöcke

Beitrag von dtmackenzie »

Hallo Markus,

habe gerade Deine Lösung probiert weil ich es nicht verstanden habe...
Ergibt den Namen und nicht den Inhalt....
Es fehlte aber nur ein "&", dann ging es doch.
Also auch eine Möglichkeit.

Code: Alles auswählen

FOR i := 1 TO LEN(aColumns)
    cColumn := aColumns[i]
    browse:addColumn(crtBlock(cColumn))
NEXT
// hier wird Schleifen Wert cColumn wieder lokal
STATIC FUNC crtBlock(cColumn)
RETURN TBColumnNew(UPPER(cColumn),  {|| &cColumn })
Viele Grüße,
David
Antworten