PMS32
Online- Hilfereferenz
CSTRUCTURE.INDEX
Informationen über den Aufbau von C- Structure Dateien
C- Structure Dateien sind Dateien in ASCII Form, in denen ein strukturierter Objektaufbau gespeichert bzw. dargestellt werden kann. Dabei handelt es sich „fast“ immer um einen Objektaufbau, es können aber auch Script- bzw. Textdateien hinterlegt sein. Der Aufbau wurde von uns deshalb gewählt, weil man eine Änderung an einer Datei mit einem einfachen Editor vornehmen kann. BITTE SPEICHERN SIE KEINE C-STRUCTURE DATEIEN IM WORD (DOC/DOCX) FORMAT! Eine solche Datei würde vom C- Structure Interpreter garantiert nicht verstanden werden. C- Structure Dateien werden überall dort eingesetzt, wo „schnell“ mal eine Änderung vorgenommen werden muss ohne auf bestimmte Programme angewiesen zu sein. Sie können C- Structure Dateien mit jedem „normalen“ Texteditor, z.B. Notepad, bearbeiten bzw. ansehen.
Eine C- Structure Datei ist z.B. PMS32.PTH in der die Pfade von PMS hinterlegt sind. Wird diese Datei eingelesen, so wird aus der C- Structure zuerst eine O- Structure erstellt. Diese O- Structure ist in eine Objekt- Kette bzw. Collection- Kette und enthält die Werte der C- Structure im Maschinenformat. Collection = Sammlung. Wichtig ist, dass diese O- Structure im Speicher verbleibt und danach in eine A- Structure umgewandelt werden kann.
Zu den Begriffen:
Nun kann man mit Recht behaupten, was für ein Aufwand aber man kann mit diesen Dateien auch rechnen bzw. man kann ganze Teile der Umgebung anpassen in denen man derartige Objekte benötigt. Außerdem können Teile dieser Strukturen separat behandelt werden, was den Änderungsaufwand erheblich erleichtert. Die Menüs ab Version 1.0.04 basieren z.B. auf solchen Strukturen und sind im Netzwerkordner \SYS abgelegt. In diesem Ordner gibt es eine Menge Dateien mit verschiedenen Endungen, die alle eine definierte Bedeutung haben.
Dateinamen der C- Structure Dateien:
*.define, definiert eine Definitionsdatei, die „meistens“ die Ausgangswerte einer C- Structure Datei enthalten. Diese können allgemeine Informationen oder auch spezielle Informationen eines Moduls enthalten. So enthält z.B. b01.all.define alle Menüdefinitionen der B01 Masken wohingegen die Datei fibu.define die Scriptsammlung für die FIBU Schnittstelle enthält.
*.mpc, enthält den Aufbau von Menüs. Achtung! Die Menüdateien wurden in viele Einzelteile zerlegt um diese nur einmal definieren zu müssen. Die Datei menu.b01.mpc enthält z.B. den Menüaufbau für alle B01 Masken, wobei die Dateien menu.b01??.mpc die eigentlichen Aufrufdefinitionen der B01 Masken enthalten. Maskenname = Menüname.
*.npc, enthält den Aufbau der Navigationsbar und der Statusbar
*.tpc, enthält den Aufbau der Toolbars
*.usr, enthalten Scripte der verschiedenen neu übersetzten Module
Die oben genannten Dateien findet man im Hauptverzeichnis der C- Structure Dateien. Unterhalb von SYS\ wird das Verzeichnis MYSYS\ angelegt, in das der Benutzer seine eigenen Scripte anlegen kann. Bitte ändern Sie keine Scripte direkt im Verzeichnis SYS\! Diese Scripte werden bei Updates komplett von uns überschrieben. C- Structure Dateien bzw. Scripte die vom Benutzer angepasst wurden sollten auf jeden Fall unter MYSYS\ eingespielt werden. Bei der Umsetzung der Version 1.0.04 werden die *.INI Dateien des Verzeichnisses Menus in das Verzeichnis MYSYS übertragen. Dabei werden Menüdefinitionen und enthaltene Scripte in verschiedene Dateien aufgeteilt. Die „alten“ Menüdateien werden in *.old umbenannt und verbleiben im Ordner Menus. Ab Version 1.0.04 werden KEINE Benutzermenüs ausgeführt, die in INI Dateien des Menus Verzeichnisses liegen! Wenn Sie also Änderungen vornehmen möchten, so müssen diese nun im Verzeichnis MYSYS vorgenommen werden!
*.usc, Dateien liegen nur im Ordner MYSYS und enthalten die Scripte der Systemdateien SYSTEM??.INI.
Die entsprechenden Menüänderungen, die in den SYSTEM??.INI Dateien vorgenommen wurden, werden als menu.<bereich>.mpc gespeichert. Zusätzlich werden enthaltene Scripte in *.usr Dateien unter MYSYS gespeichert.
Die Speicherorte: SYS, MYSYS und andere.
Alle C- Structure Dateien „sollten“ ab dem Unterverzeichnis SYS\ im Netzwerkordner abgelegt werden. Damit ersparen Sie sich Pfadangaben zu Dateien, die nicht in dieser Ordnerstruktur liegen. Der C- Structure Interpreter geht beim Laden einer C- Structure Datei von folgender Verzeichnisfolge aus:
..\SYS\ - enthält die C- Structure Dateien, die vom PMS Compelec GmbH mitgegeben werden. Bitte in diesem Ordner keine eigenen Dateien speichern!
..\SYS\MYSYS\ - enthält die Benutzerdefinierten Dateien, gültig für alle Benutzer und alle Mandanten
..\SYS\MYSYS\<Mandant>\ - enthält die mandantenabhängigen Dateien für alle Benutzer
..\SYS\ <User>\ - enthält die benutzerabhängigen Dateien für alle Mandanten
..\SYS\MYSYS\<User>\ - enthält die benutzerabhängigen Dateien für alle Mandanten
..\SYS\MYSYS\<Mandant>\<User>\ - enthält die benutzer- und mandantenabhängigen Dateien
Die Suchreihenfolge beim Laden einer C- Structure Datei ist voreingestellt von oben nach unten. Dabei werden Dateien mit gleichem Namen „überladen“. Damit kann der Benutzer z.B. Sondermenüs an die von PMS definierten Menüs anhängen ohne deren Struktur zu kennen. Wird die umgekehrte Reihenfolge bevorzugt, so ist in der CS Datei cots.define die Eigenschaft lDirection = .T. zu setzen. Damit würde die Reihenfolge von (hier) unten nach oben laufen. Es ist auch möglich den Lesevorgang mit der Kennung: !!NODEFAULT!! abzubrechen. Je nachdem, wo Sie also eine CS Datei ablegen wird diese nur unter bestimmten Voraussetzungen geladen. „Mandant“ gibt die Mandanten- ID aus der Datei PMS32.PTH an. „User“ ist das Benutzerkürzel, mit dem sich der Benutzer am System anmeldet.
Definitionen einer C- Structure Datei
Wie schon erwähnt bilden CS Dateien eine Objektstruktur ab, die im System schneller verarbeitet werden kann. Dabei ist folgendes zu beachten! Bei der Umwandlung von C- Structure nach O- Structure werden „alle“ Anweisungen als Ausdruck bzw. Befehl verstanden. D.h., dass bei einer Zuweisung eines Strings zu einer Property (Eigenschaft) der String in Anführungszeichen stehen muss um vom Interpreter verstanden zu werden. Zahlen dürfen nicht mit einem Komma geschrieben werden sondern mit einem Punkt! Datumsangaben werden in geschweifte Klammern {} gesetzt! Ein paar Beispiele:
EineStringProperty = „Michael Bergner“
EineKomplexeStringProperty = „Michael „+CHR(34)+“Bergner“+CHR(34) */ Ergibt: Michael „Bergner“
EineIntegerZahl = 1000
EineFloatingPointZahl = 123.45 */ Nicht 123,45 schreiben!
EinDatum = {^2010-04-20} */ Datum in Internationaler Schreibweise
EineZeitangabe = {^2010-04-20T17:53:12} */ Datum und Uhrzeit in internationaler Schreibweise
EinLogischerWert = .T.
EinEmptyObject = CREATEOBJECT(„EMPTY“) */ Erstellt eine leere Objekthülle
Wie oben erwähnt werden die Ausdrücke nach dem Gleichheitszeichen bei der Umwandlung von C- Structure nach O- Structure als Ausdruck bzw. Befehl interpretiert. Möchte man dies vermeiden, so kann mit dem Operator § eine Umwandlung verhindert werden. An ein paar Beispielen:
EineStringProperty = §Michael Bergner
EineKomplexeStringProperty = §Michael „Bergner“
EineIntegerZahl = §1000 */ Hier steht jetzt ein STRING! „1000“
EineFloatingPointZahl = §123,45 */ Auch hier ein String! „123,45“, kann dann mit nZahl = VAL(oObject.EineFloatingPointZahl) umgewandelt werden
EinDatum = §^2010-04-20 */ Auch hier ein String „^2010-04-20“, kann mit dDatum = CTOD(oObject.EinDatum) umgewandelt werden
Ein § verhindert, dass der Interpreter die Zeichen nach dem Gleichheitszeichen als Ausdruck betrachtet. In der O- Structure werden alle Zeichen hinter dem § als String gespeichert. Noch eine Information zum Einleiten eines Kommentars. Kommentare werden mit */ eingeleitet und gehen bis zum Zeilenende. Enthält ein String eine Kommentaranweisung, so muss dieser entsprechend umgewandelt werden:
EinePropertyMitKommentar = „Michael*“+“/Bergner“ */ Ergibt: „Michael*/Bergner“
EinFehler = „Michael*/Bergner“ */ Führt zu einem Fehler und bricht die Interpretation ab.
Objekte einer C- Structure
Wie eine Property (Eigenschaft) erstellt wird haben wir jetzt gelernt. Kommen wir also zu den Objekten und deren Definition. Grundsätzlich werden bei der Umwandlung von C- Structure nach O- Structure keine weiteren Definitionen für ein Objekt benötigt, jedoch bei der Umwandlung von O- Structure nach A- Structure muss der Interpreter wissen, um welches Objekt es sich handelt. Dazu werden Klasse und Library benötigt, aus der dann das Objekt für die A- Structure instanziiert wird. Bei der Erstellung der Menüstrukturen kann darauf verzichtet werden, da diese nur aus ca. drei verschiedenen Klassen bestehen und der Master immer weiß, welche Klasse geadded werden muss. Ein paar Beispiele:
<Objekt> */ Einleitung eines Objektes EineStringProperty = „Michael Bergner“<> */ Ende des Objektes*/ Zugriff auf das Objekt im Programmcode nach der Umwandlung von C nach OcString = oScript.Objekt.EineStringProperty
<Objekt:§Custom> */ Angabe eines Objektes incl. Der Klasse (Hier Grundklasse CUSTOM von VFP)
EineZahl = 1000 <> <Objekt:$mForm:§pmsguiapps.vcx> */ Objekt mit Angabe der Klasse und der Library EineZahl = 2000<> <Object:“mForm“:“pmsguiapps.vcx“> */ Gleiches wie oben, jedoch werden die Ausdrücke umgewandelt<>
Die Angaben der Klasse und eventuell der Library nach dem Objektnamen werden mit Doppelpunkt vorgenommen. Der Klassenname und der Name der Library werden aber als Ausdruck gewertet, was den Einsatz des Operators § bedingt oder man schreibt die Definition wie im vierten Beispiel angegeben. Bei der Umwandlung von O- Structure nach A- Structure kann aber auch eine Methode angegeben werden, die den Zeiger auf ein Objekt zurück gibt. Dies ist beim Aufbau der Menüdateien so. Deshalb findet man dort „meistens“ nur folgenden Ausdruck:
<_precord:§&poChild.AddItem(m.pcName)><>
Wie wird nun der obige Ausdruck ausgewertet? Bei der Umsetzung von C nach O wird ein Objekt erstellt, das die Klassendefinition „&poChild.AddItem(m.pcName)“ als String enthält. Der & Operator sagt dem Interpreter, dass bei der Übersetzung von O nach A, alles nach dem & Zeichen als Ausdruck zu interpretieren ist. Damit wird genau das ausgeführt, was bei der Umwandlung von C nach O verhindert wurde. poChild ist ein Zeiger auf die Applikations- Struktur und verweist auf das aktuelle Objekt in der Objektstruktur. AddItem ist eine Methode der Menüklasse, die den Namen „_precord“ mitgegeben bekommt. Da die Klasse im Fall der Menüstrukturen genau weiß, welche weiteren Klassen geadded werden müssen benötigt dieser nur den Namen des neuen Objekts. Nun kann eine Objektdefinition aber auch nachgeladen werden. Dies wird in den Menüdateien sehr oft benötigt, um Differenzen bei „gleichen“ Menüpunkten zu vermeiden. Nachladen lassen sich alle Informationen von Objektstrukturen, C- Structure Dateien, Scripten, Texten, etc. Aber gehen wir zuerst noch auf Scripte, Texte und Arrays ein, die auch in eine C- Structure eingebettet werden können.
Scripte
Ein paar Beispiele mit Script- Definitionen:
>MeinScript */ Einleitung eines Scripts* Hier kann jetzt gewöhnlicher VFP Code stehen.. Der Kommentar ist korrekt! VFP benötigt nur einen * am Zeilenanfang!LOCAL liFarbe
DO CASECASE INLIST(DOW(DATE()),2,3,4,5,6)
liFarbe = RGB(0,0,0) && Schwarz
CASE DOW(DATE())=7
liFarbe = RGB(0,255,0) && Grün
OTHERWISE
liFarbe = RGB(255,0,0) && Rot
ENDCASERETURN m.liFarbe
< */ ACHTUNG! VFP duldet einen Kommentar nach einer Programmzeile nur mit && Kommentar…*/ Ein Kommentar mit */ nach einer Programmzeile würde zu einer Fehlermeldung führen */ Im Programm würde dann der Code in etwa so aussehen…liFarbe = EXECSCRIPT(oScript.MeinScript)
Obiges Script muss mit EXECSCRIPT(cScript) ausgeführt werden. Es gibt aber auch Eigenschaften an Objekten, bei denen wird ein Script oder ein Ausdruck vorausgesetzt. Bei Menüs kann ein Script Click_BF bzw. Click_AF definiert werden. Ebenso gibt es die ClickCommand Eigenschaft, die sowohl Scripte als auch Ausdrücke aufnehmen kann. Von unserer Seite aus wird die Property ClickCommand gefüttert. Ein Benutzer hat nun die Möglichkeit vor „Click_BF“ bzw. nach „Click_AF“ dem ClickCommand ein eigenes Script oder eine Anweisung ausführen zu können. Dem Menü- Interpreter muss dazu mitgeteilt werden, ob er ein Script oder eine Anweisung ausführen muss. Eine Anweisung wird immer mit vorangestelltem = Zeichen angegeben. Scripte haben dieses Zeichen nicht.
*/ Erweiterung eines Menübefehls>Click_BFRETURN NOT INLIST(DOW(DATE(),1,7)
< */ Dieser Befehl würde .F. zurückliefern, wenn der Wochentag Sonntag oder Samstag ist.*/ Damit würde das interne ClickCommand nicht ausgeführt */ Es ginge aber auch anders… (wie immer)Click_BF = §=NOT INLIST(DOW(DATE(),1,7)
*/ Würde wie oben das interne ClickCommand nicht ausführen, wenn der aktuelle Tag ein Sonntag oder Samstag ist*/ Jedoch würde die Angabe nicht als Script sondern als Ausdruck interpretiert…
Scripte machen nur dort Sinn, wo mehr als eine Codezeile zu verarbeiten ist! Wichtig ist, dass der Rückgabewert des Scriptes oder des Ausdrucks immer dem entspricht, was die nachfolgende Methode erwartet. Ist dies nicht der Fall, so werden Fehler aufgezeichnet und das Ergebnis sieht meistens anders aus als man es erwartet hätte. Scripte werden also mit >Scriptname eingeleitet und mit einem < in der letzten Zeile beendet.
Textblöcke
Fast gleich verhält es sich mit Texten (laaaangen Texten…)
MeinText =>
Hier kann jetzt ein beliebig langer Text stehen. Der Text kann TAB’s und auchZeilenumbrüche enthalten. Was nicht geht sind Bilder, die in den Text eingebunden werden…< */ Kennzeichnet das Textende
Textblöcke werden durch die Einleitung des > Zeichens direkt hinter dem Gleichheitszeichen eingeleitet und gehen bis zum Endkennzeichen <. Alles innerhalb des Blockes wird als Text behandelt und in die angegebene Property (Eigenschaft) gespeichert.
Arrays
Als Besonderheit können Arrays angesehen werden. In Arrays kann „fast“ alles gespeichert werden, dabei muss der Benutzer nur ein paar Kleinigkeiten beachten damit es auch mit Arrays klappt. Zunächst sollte man wissen, dass VFP nur maximal zweidimensionale Arrays zulässt. aArray[ Z , S ]. Wobei der Zählindex für den Zeilen- bzw. den Spaltenvektor immer bei 1 beginnt. Die Inhalte des Arrays werden bei der Übertragung von C nach O in einzelnen Elementen der Collection gespeichert und erst bei der Umwandlung von O nach A in ein Array der Applikations- Struktur übertragen. Array Elemente müssen immer mit ihrem Zeilen- und Spaltenvektor angegeben werden. Sollte das Array mal nur eine Spalte enthalten könnte das Array auch „nur“ mit dem Zeilenvektor angegeben werden. Besser aber ist die Angabe von Zeilen- und Spaltenvektor, in diesem Fall: aArray[ Z , 1 ]. Nun kann in jedem Element des Arrays ein anderer Wert und auch ein anderer Typ stehen. Es ist nicht zwingend notwendig das Array nur mit Zahlenwerten oder Stringwerten zu füllen. An ein paar Beispielen:
MeinArray[9,1] = „Dies ist ein String“ */ String
MeinArray[8,1] = 123.45 */ Float
MeinArray[7,1] = DATE() */ Date - Aktuelles Datum
MeinArray[6,1] = DATETIME() */ DateTime – Datum / Uhrzeit
MeinArray[5,1] = .T. */ Logical – Logischer Wert
MeinArray[4,1] = CREATEOBJECT(„EMPTY“) */ Object – Leeres Objekt
>MeinArray[3,1]* Es gehen auch Scripte in ein Array..LOCAL liFarbe
DO CASECASE INLIST(DOW(DATE()),2,3,4,5,6)
liFarbe = RGB(0,0,0) && Schwarz
CASE DOW(DATE())=7
liFarbe = RGB(0,255,0) && Grün
OTHERWISE
liFarbe = RGB(255,0,0) && Rot
ENDCASERETURN m.liFarbe
< MeinArray[2,1] =>
Oder ganz, ganz lange Texte…< <MeinArray[1,1]:§mForm:$pmsguiapps.vcx> EineProperty = „Michael Bergner“ */ Jetzt Kommt’s… EinVorhandenesDatum = oParent.MeinArray[7,1] */ Enthält DATE()… EineKopie = oThis.EineProperty */ Enthält „Michael Bergner“<>
Wie oben zu sehen, kann ein Array in jedem Element mit einem anderen Typ gefüllt werden. Selbst Textblöcke, Scripte und Objektstrukturen lassen sich in Arrays unterbringen. In wie weit dies allerdings Sinn macht muss der Problemstellung vorbehalten bleiben. Was man auf jeden Fall beachten muss ist, dass das „Größte“ Element des Arrays „zuerst“ angegeben wird, da dies die Komplette Größe des Arrays angibt. Elemente eines Arrays, die nicht gesetzt werden enthalten den logischen Wert .F.. An einem Beispiel:
MeinArray[10,10] = .F. */ Maximale Größe des Arrays festlegen
MeinArray[8,8] = „Michael Bergner“
MeinArray[3,2] = DATE()
MeinArray[12,1] = DATETIME() */ Produziert einen Array Fehler bei der Umwandlung von O nach A!
Obiges Array wurde mit 10 Zeilen zu 10 Spalten vorbelegt. Dass sind 100 Elemente. Alle nicht zugewiesenen Elemente haben den Wert .F. (Logisch). Bei der Umsetzung von C nach O würde der Interpreter keine Fehler feststellen, da das Array ja eigentlich noch nicht aufgebaut wird. Erst bei der Umsetzung von O nach A würde der Interpreter auf einen Fehler laufen, da es das Element MeinArray[12,1] nicht gibt!
Bekannte Variablen
Was wir bei der ganzen Sache noch festgestellt haben, sind diverse Variablen, die bei der Umsetzung von C nach O und von O nach A vorhanden sind, und auf die wir zugreifen können. Widmen wir uns zunächst der Umsetzung von C nach O. Hier wird eine ASCII Datei in eine Objektstruktur umgewandelt. Bei dieser Umwandlung können wir auf folgende Variablen zugreifen:
Bei der Umsetzung von O nach A Structure sind auch Variablen vorhanden, auf die während der Umsetzung zugegriffen werden kann. Zunächst gibt es wieder die Zeiger oRoot, oParent und oThis, die auf die O- Structure verweisen. Zusätzlich gibt es aber auch Zeiger auf die momentan im Aufbau befindliche A- Structure:
Nachladen von Informationen
Um doppelte Anweisungen, Scripte, Texte und Objektdefinitionen zu vermeiden können diese bei Bedarf nachgeladen werden. Diese Anweisungen werden bei der Umsetzung von C- Structure nach O- Structure ausgeführt. So können z.B. aus einer einzigen Zeile größere Objektbäume entstehen, die dann umgesetzt werden. An einem Beispiel der Menüdatei MENU.B0101.MPC…
*/ Menü der Maske B0101#§menu.b01.mpc
Obige Codezeile veranlasst der Interpreter die Datei „menu.b01.mpc“ nachzuladen. Sie werden in „fast“ allen B01 Menüdefinitionen diese zwei Zeilen finden, somit werden doppelte Definitionen vermieden und die Menüs der B01- Masken sehen alle identisch aus. Das Zeichen „#“ teilt dem Interpreter mit, dass die nachfolgende Datei geladen werden soll. Dabei geht der Interpreter von einer weiteren C- Structure Datei aus. Dieses Verhalten ist bei Scripten und Texten identisch, jedoch werden bei diesen keine CS Dateien vorausgesetzt. An einem größeren Beispiel:
*/ Größeres Beispiel für das Nachladen von Informationen*/ Nachladen einer CS Datei. Die Datei muss als C- Structure Datei ableget werden…#§MeineErsteCStructure.txt*/ Definition eines Textes, der nachgeladen wird… KurzschreibweiseInfoText =>#§InfoText.txt<
*/ Definition eines Scrptes, das nachgeladen wird… Kurzschreibweise>InfoScript#§InfoScript.txt<*/ Definition eines Objektes Kurzschreibweise, da „>>“ gleichzeitig das Ende der Objektdefinition enthält<Info1:§Custom;#Info1Objekt.txt>> */ Der folgende Code Abschnitt sollte in der Datei „MeineErsteCStructure.txt“ gespeichert werden…Vorname = „Michael“Nachname = „Bergner“Vorgestern = DTOC(DATE()-2) */ Wird als Zeichenwert gespeichert
*/ Jetzt folgt die Textinformation, die in der Textdatei „InfoText.txt“ gespeichert werden sollte…Unser Freund ~VN~ ~NN~ hat am ~VG~ die erwarteten Ziele erreicht. */ Das nachfolgende Script wird in der Datei „InfoScript.txt“ gespeichert…% * Anweisung an den Interpreter, das fertiggeladene Script auszuführen…* In diesem Script wird der Text mit den Platzhaltern erweitert.LOCAL lcText
lcText = oRoot.InfoText && Holen des Textes
lcText = STRTRAN(m.lcText,“~VN~“,oRoot.GetDefItem(„Vorname“,““)) && Austauschen des Platzhalters für den Vornamen
lcText = STRTRAN(m.lcText,“~NN~“,oRoot.GetDefItem(„Nachname“,““)) && Austauschen des Platzhalters für den Nachnamen
lcText = STRTRAN(m.lcText,“~VG~“,oRoot.GetDefItem(„Vorgestern“,““)) && Austauschen des Platzhalters für das Datum
RETURN m.lcText
*/ Die nachfolgenden Informationen sollten in der Datei „Info1Objekt.txt“ gespeichert werdenVorname = oRoot.VornameNachname = oRoot.NachnameInfoText = oRoot.InfoScript */ Enthält den Umgewandelten Text!
Wie oben zu sehen, besteht unser Beispiel aus 5 Dateien, wobei der erste Abschnitt als separate Datei betrachtet werden sollte. Bei der Umsetzung von C nach O werden dann die einzelnen Dateien nachgeladen und umgesetzt. Das „$“ Zeichen am Anfang des Scripts weist den Interpreter daraufhin, den nachfolgenden Text als Script bei der Umwandlung von C nach O zu betrachten. Die Methode GetDefItem(<cItemName>,<vDefault>) ermittelt das Item „<cItemName>“ in der angegebenen Struktur. Wird dieses nicht gefunden wird der Standardwert „<vDefault>“ zurückgegeben. Damit haben wir wieder mehrere Sonderzeichen bei der Umwandlung von C nach O kennen gelernt. Die vollständige Liste für Sonderzeichen bei der Umwandlung von C nach O ist…
§ - Die folgenden Zeichen werden nicht als Ausdruck betrachtet, sondern direkt übernommen. Bei der Umwandlung von C nach O wird jede Anweisung als Ausdruck betrachtet und mit EVALUATE() umgewandelt. Dies kann mit vorangestelltem „§“ Zeichen verhindert werden. Dieses gilt für Klassennamen, Klassenbibliotheken, Dateinamen und Inhalten von Eigenschaften.
% -Das fertiggeladene Script wird direkt bei der Umwandlung von C nach O ausgeführt. Das Erste Zeichen des Scripts muss dann „%“ sein!
# - Nachladen der folgenden Datei. Hier wird unterschieden, welche Art von Datei nachgeladen wird!
Objekte – Es wird eine C- Structure Datei erwartet
Scripte – Es wird eine „reine“ Scriptdatei erwartet
Texte – Es wird eine Textdatei erwartet
! – Versuche den folgenden Ausdruck mit EVALUATE() umzuwandeln und gib einen Leerstring zurück falls dies nicht klappt.
Anmerkung: Wie wir wissen, werden alle Informationen bei der Umwandlung von C nach O als Ausdruck ausgewertet. Kann ein Ausdruck nicht umgewandelt werden, so wird .NULL. zurückgegeben! Dies kann mit vorangestelltem: !<Ausdruck> verhindert werden. Hier wird zumindest ein Leerstring statt .NULL. zurückgegeben.
Kurzschreibweise und Nachladen von Informationen in der Ende- Markierung „/“
Wie in obigem Beispiel erwähnt, können Dateien nachgeladen und Definitionen in Kurzschreibweise angegeben werden. Dazu müssen Objekte, Texte und Scripte unterschieden werden.
*/ Verschiedene Möglichkeiten Objekte zu definieren…<Objekt> */ Einleitung eines Objekts Class = §MyCustom */ Definition des Klasse ClassLibrary = §vcx\MyClassLib.vcx */ KlassenbibliothekNurDieseInfo = DATETIME()
#§MeineObjektDefinition.txt */ Nachladen einer weiteren C- Structure Datei<> */ Endedefinition eines Objektes*/ Es geht auch so…<Objekt:§MyCustom:§vcx\MyClassLib.vcx>NurDieseInfo = DATETIME()
</#§MeineObjektDefinition.txt>*/ Wäre die Property „NurDieseInfo“ nicht vorhanden könnte man es auch so schreiben…<Objekt:§MyCustom:§vcx\MyClassLib.vcx></#§MeineObjektDefinition.txt>*/ Oder so… (ganz kurz)<Objekt:§MyCustom:§vcx\MyClassLib.vcx;#§MeineObjektDefinition.txt>> */ Wenn das Objekt aus mehreren Dateien definiert wird…<Objekt:§MyCustom:§vcx\MyClassLib.vcx;#§Definition1.txt;#§Definition2.txt;#§Definition3.txt;…>>
Für die Trennung der Objektdefinition und der eventuell zu ladenden C- Structure Dateien wird das Semikolon benötigt! Mehrere zu ladende Dateien müssen wie im letzten Beispiel immer durch Semikolon getrennt werden. Die Dateien werden in der Reihenfolge von Links nach Rechts geladen! Gleiche Objekte bzw. Properties, Scripte und Texte werden wenn nicht anders angegeben überladen d.h., das eine vorhandene Information überschrieben wird. Dies kann mit dem „+“ Zeichen verhindert werden…
Verhindern des Überladens von Informationen „+“
Normalerweise werden Informationen, die schon in der Objektstruktur vorhanden sind überschrieben. Um dies zu vermeiden kann der „+“ Operator vor der Information definiert werden was dieses Verhalten abschaltet. An ein paar Beispielen…
*/ Überladen von Informationen…MeineProperty = „Michael “
*/ Weitere Definitionen…MeineProperty = „Bergner“
*/ Würde ergeben: MeineProperty = „Bergner“ */ Die erste Definition würde überschrieben */ Nicht jedoch wenn…MeineProperty = „Michael “
*/ Weitere Definitionen…+MeineProperty = „Bergner“*/ Würde ergeben: MeineProperty = „Michael Bergner“ */ Die Strings würden addiert! */ Das gleiche funktioniert auch mit Zahlen…Zahl1 = 100*/ Weitere Definitionen…+Zahl1 = 200*/ Würde ergeben: Zahl1 = 300 */ Objekte verhalten sich ähnlich…<Objekt> Zahl1 = 100<> */ Weitere Definitionen…<Objekt> Zahl2 = 200<> */ Hier würde die erste Objektdefinition überschrieben… übrig bleibt: Objekt.Zahl2 <Objekt> Zahl1 = 100<> */ Weitere Definitionen…<+Objekt> Zahl2 = 200<> */ Würde ergeben: Objekt.Zahl1 und Objekt.Zahl2
Gleiches Verhalten gilt für Scripte und Texte. Es können auch Textproperties mit Scripten und Texten addiert werden!
Zusammenfassung (CS nach OS)
Bei der Umwandlung von C nach O Strukturen können komplexe Objektstrukturen definiert werden, die dann in Form einer Collection (Sammlung) als O- Structure bestehen. Diese Sammlung kann dann in eine A- Structure (Applikations- Struktur) umgesetzt werden. Beachten Sie bitte die Reihenfolge, in der die Zeilen einer CS Datei umgesetzt werden!
*/ Zusammenfassung anhand einiger Beispiele…RootCProperty = „Michael Bergner“ */ Ein String
RootNProperty = 123.45 */ Eine Zahl
<Objekt:§Custom> Name = oRoot.RootCProperty */ Ein String der aus Root kopiert wird <SubObject:§Custom;#ObjektDatei.txt> Zahl = oRoot.RootNProperty */ Die Zahl aus Root String = oParent.Name */ Der Text aus Parent </#§WeitereObjektDefinitionen.txt> #§WeitereObjektDefinitionen.txt */ Nachladen von Informationen</#§ObjektFooter.txt> */ Ein einfaches Script>MeinScript* Dies ist ein VFP Script…RETURN DATE()
< */ Ein komplexes Script…>MeinZweitesScript#§ScriptHeader.txt*/ Nach dem Header werden noch Variablen definiert…LOCAL lcName
lcName = oRoot.RootCProperty
</#§ScriptFooter.txt EinLangerText =>#§TextHeader.txt
Diese Zeile würde an den Text angehängt werden… Ohne Zeilenumbruch!
</#§TextFooter.txt */ Anhängen von Scripten…>+MeinZweitesScript*/ Funktioniert nur dann, wenn in ScriptFooter.txt kein RETURN vorkommt…IF m.lcName = „Michael Bergner“
WAIT WINDOW „Guten Morgen „ + m.lcName
ELSE lcName = „“ENDIFRETURN m.lcName
<
Umwandeln von OS nach AS (Applikation Structure)
Da eine O- Structure nur einen Zwischenwert bzw. eine Zwischenstruktur darstellt muss diese in eine Applikations- Struktur umgewandelt werden. Dies wird jetzt schon mit allen Menüs der Masken gemacht. Dabei verbleiben einmal gelesene O- Structure Dateien im Speicher des Rechners erhalten d.h., einmal gelesene O- Structure Informationen werden nicht mehr von der Festplatte gelesen sondern direkt aus dem Speicher ausgeführt. Eine O- Structure verbleibt während einer Programmsitzung im Speicher und wird erst bei Verlassen des Programms entfernt. Bei der Übertragung von OS nach AS wird die O- Structure Zeilenweise gelesen und in eine A- Structure umgesetzt. Da bei dieser Umwandlung die Klassen bekannt sein müssen ist entweder die Klasse angegeben oder das Root- Applikation- Objekt besitzt eine Methode, die die Klassen der Objekte bestimmt. Dies ist bei den Menüs der Fall. Jedes Menüobjekt hat die Methode AddItem(), das weitere Objekte added. Deshalb sieht man in den Menüstrukturen keine Klassendefinitionen sondern lediglich die Befehle poChild.AddItem(m.pcName). Diese Methode gibt den Zeiger auf ein Objekt zurück, was bei der Umwandlung von OS nach AS ausreichend ist. Wie oben schon erwähnt werden bei dieser Umwandlung keine Ausdrücke erwartet. Möchte man trotzdem einen Ausdruck angeben so ist dieser mit einem vorangestelltem „&“ zu versehen. Ein paar Beispiele sollen dies verdeutlichen:
*/ C- Structure mit Umwandlung…*/ Mit einem Ausdruck…Heute = §&DATE() */ §-Kein Ausdruck bei der Umwandlung von CS nach OS, &-Nachfolgende Zeichen mit EVALUATE() umwandeln bei OS nach AS
*/ Mit einem Script…>Gestern$RETURN DATE()-1
< Morgen = §$RETURN DATE()+1
Bei der Umwandlung von CS nach OS enthalten alle drei Properties einen String, der entweder einen Ausdruck oder ein Script angibt. Erst bei der Umwandlung von OS nach AS werden aus den Properties Datumswerte. Eine Tabelle soll dies verdeutlichen:
|
C- Structure |
O- Element |
O- Inhalt |
A- Element |
A- Inhalt |
|
Heute = §&DATE() |
Heute [C] |
&DATE() |
Heute [D] |
24.12.2010 |
|
>Gestern $RETURN DATE()-1 < |
Gestern [C} |
$RETURN DATE()-1 |
Gestern [D] |
23.12.2010 |
|
Morgen = §$RETURN DATE()+1 |
Morgen [C] |
$RETURN DATE()+1 |
Morgen [D] |
25.12.2010 |
Wie aus der Tabelle zu ersehen, werden die Elemente der O- Structure im Format [C] gespeichert. Die Angaben & und $ am Anfang teilen dem Interpreter mit, ob ein Ausdruck oder ein Script ausgeführt werden soll. Hier kann also bei der Umwandlung von OS nach AS nochmals gerechnet werden, was hinsichtlich verschiedener Datenumgebungen und Programminformationen nützlich sein kann. Dabei werden wieder zwei Varianten unterschieden:
& - Nachfolgende Zeichen sind als Ausdruck zu interpretieren
$ - Nachfolgende Zeichen sind als Script zu interpretieren. Vergessen Sie nicht den Rückgabewert an die Property mit RETURN zurückzugeben, da sonst die Property ein logisches .T. enthält.
Eine weitere Option ist die Ausführung von Scripten bzw. die Auswertung eines Ausdrucks, wenn das A- Objekt vollständig erstellt wurde…
Endecode oder Exitcode Option „|“
Mit dem Pipezeichen „|“ kann eine Exit bzw. Ende Funktion ausgeführt werden, wenn das A- Objekt komplett erstellt wurde. Dies ist nützlich, wenn nach dem Erstellen des A- Objekts eine Methode ein Ausdruck oder ein Script ausgeführt werden soll. Ein Beispiel…
*/ Exitcode. Angenommen, wir möchten ein Objekt in einem Container beeinflussen..>SetTheObjekts* Dieses Script wird nach der Erstellung eines A- Objekts ausgeführt..* Bekannte Variablen:* poMaster => A- RootObjekt poParent => A- ParentObjekt poChild => A- Aktives ObjektLOCAL lnLeft,lnTop* Die Form in die linke obere Ecke setzen… MOVE(nLeft,nTop,nWidth,nHeight)
poMaster.MOVE(0,0,400,200)
* Den Container über die Form platzieren…poParent.MOVE(0,0,poMaster.WIDTH,poMaster.HEIGHT)
* Die Editbox platzieren..lnLeft = poMaster.WIDTH/4
lnTop = poMaster.HEIGHT/4
poChild.MOVE(m.lnLeft,m.lnTop,poMaster.WIDTH/2,poMaster.HEIGHT/2)
* Alle Objekte VISIBLE=.T. schalten…poChild.VISIBLE = .T.
poParent.VISIBLE = .T.
poMaster.VISIBLE = .T.
< */ Jetzt die Struktur…<oForm:§Form> Caption = „Textform mit einer Editbox“ <oCnt:§Container> <oEditBox:§EditBox> Value = „“ ToolTipText = „Hier kann ein Text eingegeben werden…“ </|“$“+oRoot.SetTheObjects> <><>
Wie aus obiger C- Structure zu ersehen, wird eine Script- Property „SetTheObjects“ in der O- Structure erstellt, die Steuerbefehle für die erstellen Objekte enthält. In der Struktur wird zuerst eine Form erstellt in der ein Container mit einer Editbox liegt. Bei der Umwandlung von OS nach AS werden alle Elemente bis auf die OS Property „SetTheObjects“ in eine A- Structure umgewandelt. Nach dem Erstellen der Editbox wird das Script im ExitCode ausgeführt. Dieses wurde aus der Root kopiert. Das Script platziert die einzelnen Objekte und schaltet diese dann VISIBLE (sichtbar).
In den Menüdateien ist oftmals die ExitCode- Anweisung §&poOTS.CopyItems(m.pcName) zu sehen. Diese Kopiert die Basicdefinitionen der Datei pms32.all.define an das jeweilige Objekt. Damit müssen die Definitionen für Beschreibung, Bilddatei und Informationstext nur einmal angelegt werden. Die Basic- Informationen stehen in den Dateien mit der Endung „define“. Sowohl die Klasse für die Steuerung der Structure Elemente, My.CStructs.cOTS als auch die Collection der O- Structure haben Methoden und Properties, die die Bearbeitung von CS Dateien vereinfachen.
My.CStructs.cOTS bzw. My.CStructs.NewCStruct
Genaue Informationen der obigen Klasse entnehmen Sie bitte der Struktur Informationsdatei PMS32M.EXE. Die Klasse dient zur Steuerung von CS Dateien, Menüscripten, Maskenscripten und dergleichen. Wie oben erwähnt, wird die O- Structure in Form einer Collection abgelegt. Auch diese Information kann über PMS32M.EXE abgerufen werden. Es bestehen Möglichkeiten Collections in Objektstrukturen umzuwandeln und Umgekehrt, jedoch geht dabei die Reihenfolge der Informationen verloren!
Übersicht über alle Operatoren bzw. Definitionsmöglichkeiten
|
Definitionsbeispiel |
Was ? |
Bemerkung |
|
Property = DATE() |
Property |
Hier wurde eine Property mit dem Typ Datum definiert. |
|
<Objekt[:cKlasse[:cBibliothek]]|[;#cStructureFile]> |
Objekt |
Einleitung der Definition eines Objekts. |
|
<> |
Objekt |
Ende- Definition eines Objektes ohne weitere Angaben. |
|
<[/#cStructureFile1[;#cStructureFile2[;…]]][;|cAusdruck|cScript]> |
Objekt |
Ende- Definition mit weiteren Anweisungen |
|
<Objekt[:cKlasse[:cBibliothek]]|[;#cStructureFile]>> |
Objekt |
Definition eines Objektes incl. Endekennung. Kurzschreibweise. |
|
>Script[#cHeaderScript1[;#cHeaderScript2[;#...]]] * VFP Code… <[/#cFooterScript1[;#FooterScript2[;#...]]] |
Script |
Definition eines Scripts incl. Nachladen von Scriptdateien |
|
Text =>[#cHeaderText1[;#cHeaderText2[;#...]]] Ein langer Text… <[/#cFooterText1[;#cFooterText2[;#...]]] |
Text |
Definitionen eines Textes incl. Nachladen von Textdateien. ACHTUNG! Bei Textblöcken wird KEIN Zeilenumbruch zwischen den Einzeltextblöcken vorgenommen! |
|
Array[Z,S] = … |
Array |
Bei der Definition eines Arrays muss der größte Index für Zeilen- und Spaltenvektor als erstes Element kommen! |
|
Property = §Michael Bergner |
§ |
Das Paragraph- Zeichen verhindert die Umwandlung als Ausdruck bei der Umwandlung von CS nach OS. |
|
>Script %* Ab hier kann ein Script folgen… < |
% |
Das „%“ Zeichen gibt an, das die folgenden Zeichen bei der Umwandlung von CS nach OS als Script zu betrachten sind. |
|
Property = #§TextDatei.txt |
# |
Nachladen einer Datei ohne Angabe des Pfades. Wird ein Pfad angegeben, so wird die Textdatei NICHT zwischengespeichert sondern immer von der Festplatte oder dem angegebenen Laufwerk geladen. |
|
Property = !oRoot.NachName |
! |
Versuche den Ausdruck umzuwandeln. Geht dies nicht, so gib einen Leerstring zurück. Wird nur bei der Umsetzung von CS nach OS ausgeführt. |
|
|
|
|
|
Property = „&DATE()“ |
& |
Bei der Umwandlung von OS nach AS werden die Zeichen nach „&“ als Ausdruck umgewandelt. |
|
Property = „$RETURN DATE()“ |
$ |
Bei der Umwandlung von OS nach AS werden die Zeichen nach „$“ als Script umgewandelt. |
|
</|ExitCode> |
| |
Bei der Umwandlung von OS nach AS wird eine Codesequence nach dem kompletten Erstellen eines Objektes ausgeführt. |
Siehe auch : Hauptmenü / Hauptindex; / Dictionary Module / Programm- Module / Tabellen Index
/ Masken Index
Lokale
Benutzerhilfe : Meine eigene Hilfe / Zurück zur
PMS32 - Hilfe
Dateiversion:1.0.00.09.00
- H.U.DD.V1.V2
Senden
Sie Ihren Kommentar zu diesem Thema an das Entwicklungsteam von PMS32
Weitere Informationen finden Sie unter der aktuellen PMS32 WEB-Hilfe
. © PMS Compelec GmbH 2006 ® el-Projekt