Seite 1 von 2

DCBROWSCOL dynamisch erzeugen [ERLEDIGT]

Verfasst: Di, 09. Feb 2010 20:09
von Manfred
Hi,

wo liegt hier mein Denkfehler?

Code: Alles auswählen


FOR nI := 1 TO nMengeSpalten
              cNi     := Alltrim(Str(nI))
              cHeader := IF( ! Empty((oVarianten&cNi:nArea)->tagesart),(oVarianten&cNi:nArea)->tagesart,"Sp" + cNi)
              DCBROWSECOL FIELD (oVarianten&cNi:nArea)->abfahrt;
                   HEADER cHeader;
                   PARENT oBrowse;
                  PICTURE "@R 99:99";
                    VALID {|| validcol(oBrowse) };
                    WIDTH 60
          NEXT
es wird zwar alles erzeugt, aber es wird immer nur die letzte Spalte übergeben egal in welcher Spalte der Cursor steht und dann wird alles in die davorliegenden Spalten geschrieben, bzw. die ganze Zeile wird mit dem gleichen Wert ausgefüllt, den man in irgendeine Spalte schreibt. Es sind x-Datenbanken, die je in eine Spalte geschrieben werden.
Ich bastel jetzt schon mehrere Stunden herum, komme aber auf keine Lösungsweg. Ist sicherlich mal wieder zu einfach für mich. :roll:

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 20:31
von Martin Altmann
Detached local :!:

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 20:34
von Manfred
Hm,

gib mir einen Tipp. Da ist nichts mit localen Variablen. Die Instanzen werden mit Private Vars erzeugt.

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 20:37
von Martin Altmann
Und :?:
Schau mal in Deinen Forenindex - Du hast das ja - glaube ich - vor nicht allzu lange Zeit aufgenommen.
Inklusive div. Lösungswege!
Dein Problem liegt in der Art, wie Du cNi verwendest.

Viele Grüße,
Martin

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 21:24
von Manfred
Bin gerade dabei, aber irgendwie habe ich das Gefühl es ist schon wieder zu spät für heute. Ich blicke nicht so richtig durch. das mit den detached locals kostet immer wieder Nerven.

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 21:30
von Martin Altmann
Hmhm - kenne ich mit dem "zu spät" :-)
Versuche mal statt

Code: Alles auswählen

(oVarianten&cNi:nArea)
etwas in der Art

Code: Alles auswählen

(&("oVarianten"+cNi+":nArea"))
Viele Grüße,
Martin

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 21:38
von Manfred
Nein,

klappt auch nicht. Kommt schon eine Fehlermeldung beim Compilieren. Ich denke mal, ich lasse es für heute gut sein. Wer weiß was ich da wieder übersehe und falsch tippe.

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Di, 09. Feb 2010 21:46
von Martin Altmann
Und jetzt?
Habe oben noch mal ein wenig editiert...

Viele Grüße,
Martin

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 8:38
von Manfred
Moin,

nein, der Effekt ist der gleiche. Zwar keine Fehlermeldung, aber immer in allen Spalten der Wert der letzten Spalte.

Tja, wie sang die Gruppe Zoff Anfang der 80er?

"Und es wär so schön gewesen"

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:00
von Martin Altmann
Und Du hast das an allen drei Stellen geändert?
Und auch den Teil "Sp" + cNi angepasst?

Viele Grüße,
Martin

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:02
von Manfred
Ach so,

öh. Nö. Sorry, tut mir leid. Habe ich nicht dran gedacht. :doubt:

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:06
von Martin Altmann
Woran? Die drei Stellen? Wichtig!
Das mit dem "Sp" + cNi ? Eher unwichtig. Ist ja nur eine Ausgabe in der Überschrift.

Viele Grüße,
Martin

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:31
von Manfred
Die 3 Stellen. Bin ja schon zerknirscht. Teste es aber sofort

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:40
von Manfred
Martin,

jetzt hast Du mich verwirrt. Wieso 3 Stellen? Die mit dem Header ist außen vor. Welche Stelle aus dem Field wäre da noch?

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:44
von Manfred
Ich habe es mal hier drauf reduziert

Code: Alles auswählen

          FOR nI := 1 TO nMengeSpalten
              cNi := Alltrim(Str(nI))
              DCBROWSECOL DATA {|| (&("oVarianten"+cNi+":nArea"))->abfahrt};
                   HEADER "1";
                   PARENT oBrowse;
                  PICTURE "@R 99:99";
                    VALID {|| validcol(oBrowse) };
                    WIDTH 60
          NEXT
es klappt nicht. Immer das letzte Feld bestimmt den Inhalt für ALLE Spalten.

das hier klappt auch nicht.

Code: Alles auswählen

          FOR nI := 1 TO nMengeSpalten
              cNi := Alltrim(Str(nI))
              DCBROWSECOL FIELD  (&("oVarianten"+cNi+":nArea"))->abfahrt;
                   HEADER "1";
                   PARENT oBrowse;
                  PICTURE "@R 99:99";
                    VALID {|| validcol(oBrowse) };
                    WIDTH 60
          NEXT
es wird schon beim Aufbau des Browses der Inhalt aus der letzten DB genommen und auf die x vorhergehenden Spalten verteilt.

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:46
von Tom

Code: Alles auswählen

bColData := &("{||oVarianten"+cNi+":nArea->abfahrt}")

DCBROWSECOL DATA bColData HEADER cHeader

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:51
von AUGE_OHR
Manfred hat geschrieben:

Code: Alles auswählen

   DCBROWSECOL DATA {|| (&("oVarianten"+cNi+":nArea"))->abfahrt};

Code: Alles auswählen

   DCBROWSECOL FIELD  (&("oVarianten"+cNi+":nArea"))->abfahrt;
hm ... wie wäre

Code: Alles auswählen

   DCBROWSECOL FIELD  {|| &( ("oVarianten"+cNi+":nArea")->abfahrt );

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:53
von Manfred
Hi Tom,

ich wäre jetzt auch schwer gefrustet gewesen, wenn Du wieder die Taktik "eksus" angewendet hättest.

Fehlermeldung BASE/2300 Syntax Fehler in Makro.

Operation &<{||oVari...>

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:56
von Manfred
Hi Jimmy,

sowas ähnliches hatte ich schon probiert, aber FIELD scheint mit einem Codeblock keine Ehe haben zu wollen. Compiler meckert schon direkt.

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 9:57
von Tom
Schulljung. So müsste es richtig sein:

Code: Alles auswählen

bColData := &("{||(oVarianten"+cNi+":nArea)->abfahrt}")

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 10:18
von Manfred
OK,

alles klar. Er kam sah und siegte....

Jetzt habe ich aber das gleiche Problem wie in dem anderen Thread mit dem Array und den leeren Zellen, wenn diese trotz Eingabe verlassen werden.

Also habe ich wie gehabt folgendes gemacht:

Code: Alles auswählen

FOR nI := 1 TO nMengeSpalten
              cNi      := Alltrim(Str(nI))
              bColData := &("{||(oVarianten"+cNi+":nArea)->abfahrt}")
              DCBROWSECOL DATA bColData;
                   HEADER "1";
                   PARENT oBrowse;
                  PICTURE "@R 99:99";
                    VALID {|c,o| validcol(oBrowse,o) };
                    WIDTH 60
          NEXT
********************************************************************************
STATIC FUNCTION validcol(oBrowse,oGet)
                LOCAL cZeit   := oGet:editBuffer()  <-- hier steht noch alles drin
                LOCAL lErfolg := .T.

                oGet:SetData(cZeit)
                RETURN(lErfolg)
aber danach ist alles wieder weg. Wo liegt der Unterschied zu der Sache mit dem Array?

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 10:23
von Tom
Wo liegt der Unterschied zu der Sache mit dem Array?
Die Datenquelle ist eine Tabelle. :wink:

Aber der Code von "ValidCol" ist nicht vollständig, oder?

Re: DCBROWSCOL dynamisch erzeugen

Verfasst: Mi, 10. Feb 2010 10:29
von Manfred
Hi Tom,

doch, vollständig im Moment ja. Ich dachte mir, och baue mal was zur Prüfung, kann ja nicht so schwer sein. Ich wollte nur schrittweise testen, was denn wo falsch läuft im Ursprungscode. Nachdem ich nun Deine Variante eingebaut habe, wollte ich nur erstmal prüfen, was denn jetzt im Valid passieren müßte, bzw. könnte. Die Eingabe ist nur eine Uhrzeit und die würde nur geprüft werden, ob sie innerhalb der erlaubten 24 Stunden liegen würde mehr nicht. Deshalb ist sie noch ein wenig mager. Theoretisch das gleiche wie bei dem Array. Nur habe ich mich davon wieder verabschiedet, weil das Endergebnis nicht so war, wie ich es haben muß. Also Array weg, und x-Datenbanken her. Wobei das Array ja eigentlich wieder aufgelöst wurde in eine Datenbank. Aber das Konzept jetzt scheint für meine Ziele besser zu sein.

Re: DCBROWSCOL dynamisch erzeugen [ERLEDIGT]

Verfasst: Mi, 10. Feb 2010 11:34
von Manfred
Problem erstmal gelöst. Da ich die Werte in der ValidCol direkt in die Datenbank schreibe werden sie auch angezeigt direkt danach.

Dank an alle die mitgewirkt haben.

Detached Locals, wäre ich nie drauf gekommen. Wie auch......

Das das Makro so aufgebaut werden muß... mal sehen, wann ich das verstehe.

Re: DCBROWSCOL dynamisch erzeugen [ERLEDIGT]

Verfasst: Mi, 10. Feb 2010 11:48
von Tom
Hallo, Manfred.
Das das Makro so aufgebaut werden muß... mal sehen, wann ich das verstehe.
Du baust in einer Schleife Objekte. Das ist im Prinzip eine feine Angelegenheit, weil es den Code sehr viel kompakter und flexibler macht, ist aber mit Problemen behaftet. Eines davon besteht darin, dass bestimmte Codeblöcke, die man Objekten zuweist, erst zur Laufzeit evaluiert werden, wohingegen andere bereits im Moment der Erzeugung ausgewertet werden. Zu den erstgenannten gehört der DATA-Codeblock (Datalink) der Spalte. Weil der Zähler, mit dem Du die Objekte erzeugst, aber nach Beendigung der Schleife auf Endbedingung+1 steht, bekämst Du dann in allen Spalten denselben Wert (weil alle Spalten in ihrem Data-Codeblock auf irgendwas + 1 verweisen) - oder totalen Murks. Du musst also den Codeblock so bauen, dass er auf einen Zähler zeigt, den es im Moment der Evaluierung schon nicht mehr gibt. Gleichzeitig kannst Du den Vorteil nutzen, dass der Wert (Inhalt) des Codeblocks in den Data-Slot wandert und nicht dessen Variable (deshalb brauchst Du nur eine Codeblock-Variable, aber im Prinzip könnte man sogar darauf verzichten).

Die Lösung besteht darin, per Makro einen Codeblock zu basteln, der im Moment der Entstehung den richtigen Wert enthält.

Diese Codezeile:

Code: Alles auswählen

&("{||(oVarianten"+cNi+":nArea)->abfahrt}")
sagt ja: Hier ist ein Makro (deshalb das "&" am Anfang). Es folgt also (Klammer auf, Anführungszeichen) ein Text, der zur Laufzeit (also in dem Moment, in dem das Ergebnis der Makrooperation der Variablen zugewiesen wird) als Code interpretiert werden soll. Dann folgt (ab "{||") der eigentliche Codeblock. Der Trick besteht darin, diesen Codeblock so zu gestalten, dass die iterierende Variable ("cNi") im Moment der Makroexpansion (!) "richtig" ist. Das ist sie dadurch, dass man im Makro ihren Wert in den Makro-Text einbaut. Wären da nicht die Anführungs- und Pluszeichen um "cNi" herum, hätte man dasselbe Problem wie zuvor. Aber Du baust in den Text an dieser Stelle ihren Wert. Der Makroexpander setzt also nicht oVarianten+cNi+:nArea usw. um, sondern oVarianten1:nArea, oVarianten2:nArea und so weiter. Wenn man das verstanden hat, liest sich dieser Code sehr viel einfacher, und man kann mit diesem mächtigen Mittel tatsächlich alles mögliche bauen. Komplexe data-driven-Anwendungen werden erst so möglich.

Kapiert? 8)