OCL

Einführung
Verwendung von OCL
Session

Member
Listen (derived ObjectList)
Klassenlisten

Vergleiche
String-Vergleiche
Bedingungen

Operatoren

Listenoperatoren
Konvertierungsoperatoren

Zahlenoperatoren
Stringbearbeitungsoperatoren
Bearbeiteroperatoren
Operatoren für die Ressourcenplanung
Operatoren für die Berechtigungsprüfung

Operatoren für Projekteinträge
Operatoren für Projektphasen

Operatoren für Links
Leistungssummenoperatoren
Datumsoperatoren
Typ Operatoren (oclIsTypeOf, oclIsKindOf, oclAsType)

Einführung

Die Navigation und Abfrage im Vertec Objektmodell erfolgt über eine objektorientierte Abfragesprache namens OCL. Eine komplette Sprachdefinition können Sie als PDF-File über folgenden Link downloaden: OCL Manual.

OCL steht für object constraint language und wurde ursprünglich im Rahmen des UML Standards entwickelt, um Gültigkeitsbedingungen für Objektmodelle zu formulieren. Aufgrund seiner objektorientierten Möglichkeiten lässt sich OCL aber auch als Abfragesprache einsetzen.

Der Vertec Kern beinhaltet einen OCL Interpreter, der OCL Ausdrücke als Text verarbeitet und die Ergebnisdaten aus den Vertec Objekten zurückliefert. Der OCL Interpreter benutzt zur Überprüfung und Auswertung von Ausdrücken Informationen aus dem Vertec Modell.

Verwendungen von OCL

OCL wird in Vertec an verschiedensten Orten verwendet:

Eine OCL-Expression wird immer aufgrund eines bestimmten Objekts ausgewertet und liefert ein Ergebnis eines bestimmten Typs. Mögliche Typen von Ergebnissen sind:

  • Zahl
  • String (Zeichenkette)
  • Boolean (logischer bzw. Ja / Nein Wert)
  • Objekt
  • Liste von Zahlen, Strings, Booleans oder Objekten

Für die Anzeige von Ergebnissen, z.B. in Listenspalten, wird das Ergebnis automatisch in einen String verwandelt. Bei Zahlen und Strings ist diese Umwandlung einfach. Booleans werden als "Y" (yes) oder "N" (no) dargestellt. Bei Objekten erscheint die Standard-Stringdarstellung, welche von der Objektklasse abhängig ist (bei Projekten z.B. der Code). Die Darstellung von Listen als String zeigt die Grösse der Liste an.

Bei Expressions in Expression-Ordnern muss der Ergebnistyp zwingend eine Liste von Objekten sein.

Session

Auf die laufende Vertec-Session kann in OCL via

TimSession.allInstances->first

zugegriffen werden. Eine Vertec Session hat folgende Attribute:

.login

Liefert aktuell eingeloggten Bearbeiter zurück. Siehe dazu auch den Artikel Login / aktueller Benutzer.

.hasGui

Ab Vertec 5.6. Der Operator hasGui bietet die Möglichkeit, aus OCL Expressions oder Scripts zu bestimmen, ob es sich um einen normalen Vertec-Client handelt oder um einen Webserver (Classic Weberfassung oder XML Server). Bei Webserver gibt HasGui False zurück, bei einem normalen Client True.

TimSession.allInstances->first.hasGui

Hintergrund: Im Vertec Webserver dürfen Scripts keine Dialoge anzeigen, sonst bleibt der Webserver hängen. Damit via Script herausgefunden werden kann, ob es auf dem Server läuft, gibt es das HasGui Attribut.

.appType

Ab Version 6.0. Der Operator AppType bietet die Möglichkeit, aus OCL Expressions oder Scripts zu bestimmen, in welcher App man sich befindet.

TimSession.allInstances->first.appType

Liefert einen String zurück mit folgenden möglichen Werten:

ResultatApp
"Desktop" Desktop App
"Cloud" Cloud App
"Classic" Classic App
"ClassicServer" Classic Web oder XML Server
"Web" Web App

Member

Ein Member ist eine Eigenschaft eines Objekts. Das ist entweder eine Verknüpfung (association) zu einem oder mehreren anderen Objekten oder ein Datenfeld (attribute) des Objekts.

Ausgehend von einem Objekt kann ein Membername für den Zugriff auf ein Member angegeben werden. Falls eine solche Member-Referenz nicht am Anfang einer Expression steht, muss sie durch einen Punkt abgetrennt werden. Membernamen müssen immer klein geschrieben werden. Beispiele: code in einer Listenexpression einer Projektliste zeigt den Projektcode in der entsprechenden Spalte an; kunde.name, ebenfalls in einer Projektliste, zeigt jeweils den Namen des Kunden an. Hier handelt es sich um eine Verknüpfungsreferenz (kunde) mit anschliessender Attribut Referenz (Attribute name der Klasse Adresseintrag).

Durch Aneinanderreihen von Member-Referenzen in einer OCL-Expression können beliebige Verknüpfungen im Vertec Objektmodell abgefragt werden.

Listen (derived ObjectList)

Eine etwas spezielle Art von Members in Vertec sind berechnete Listen Attribute. Im OCL Editor werden diese als Typ ObjectList dargestellt. Eine sogenannte Derived ObjectList berechnet ihren Wert zu Laufzeit. Sie enthalten im Gegensatz zu Derived Attributes keine einzelnen Werte, sondern geben eine Liste zurück.

Ein Beispiel ist die Liste leistungen auf einem Projekt. Im Modell gibt es auf dem Projekt eigentlich nur zwei Listen: offeneLeistungen und verrechneteLeistungen. Die Liste der leistungen, also alle offenen und verrechneten zusammen, wird zu Laufzeiten berechnet.

In Versionen vor 5.8 kann mit dem .list Operator und einem entsprechenden Cast auf den richtigen Typ wie folgt damit gearbeitet werden:

<Proj>.leistungen.list->oclAsType(Leistung).wertext->sum

Mit der Version 5.8 wurden diese Listen so implementiert, damit sie Typinformationen in OCL liefern können und der .list Operator überflüssig wird. Es genügt, die Liste aufzurufen:

<Proj>.leistungen.wertext->sum

Klassenlisten

Eine Klassenliste ist die Liste aller Objekte eines bestimmten Typs (Klasse), z.B. alle Projekte oder alle Bearbeiter einer Vertec Installation.

OCL unterscheidet zwischen Gross- und Kleinschreibung. Alles Grossgeschriebene versucht der OCL Interpreter als Klassennamen (Metatyp) zu verstehen. Auf einer Klasse kennt OCL den Operator allInstances, welcher eine Liste aller Instanzen der Klasse ergibt. Projekt->allInstances liefert z.B. eine Liste aller Projekte.

Da Klassenlisten ziemlich häufig Verwendung finden, gibt es in Vertec eine Abkürzung dafür. Wird ein Klassenname klein geschrieben, dann wird dies direkt als Klassenliste interpretiert. projekt bedeutet daher ebenfalls die Liste aller Projekte.

Klassenlisten werden vor allem als Ausgangspunkt für Expressions von Expression Ordnern verwendet. Die meisten vordefinierten Expressionordner in Vertec (z.B. Stammdaten \ Bearbeiter) enthalten eine simple Klassenliste als OCL-Expression.

Achtung: Bei Klassenlisten ist etwas Vorsicht geboten, denn es gibt in Vertec Klassen, welche sehr viele Objekte umfassen können. Bei Angabe einer Klassenliste in OCL werden alle Objekte der betreffenden Klasse in den Arbeitsspeicher geladen. Insbesondere bei den Klassen OffeneLeistung oder VerrechneteLeistung kann dies zu hohem Speicherbedarf und schlechter Performance führen.

Operatoren

Operatoren führen gewisse Transformationen auf OCL Werten durch. Ein Operator wird innerhalb einer Expression durch einen vorangestellten Pfeil (->) abgetrennt. Falls keine Verwechslungsgefahr mit einem Member besteht, wird auch ein Punkt als Trennzeichen akzeptiert.

Listenoperatoren

Basierend auf einer Liste existieren in OCL verschiedene Operatoren, welche die Liste modifizieren. Weitere, hier nicht erwähnte Operatoren erscheinen jeweils in "verfügbare Felder" im OCL-Expression-Editor.

->size Der size Operator liefert die Grösse (Anzahl Einträge) einer Liste, zum Beispiel als Listen-spalte in einer Liste von Adresseinträgen gibt projekte->size die Anzahl Projekte eines jeden Kunden an.
->select Der select Operator erlaubt es, den Inhalt einer Liste aufgrund einer Bedingung zu filtern. adresseintrag->select(projekte->size > 0) als Expression eines Expressionordners liefert alle Adressen, die Projekte zugeordnet haben (d.h. Kunden sind). Das Argument des select Operators muss einen logischen (Wahr/Falsch) Wert ergeben.
->reject Der Operator reject ist sozusagen das Gegenteil des select Operators. Es werden damit alle Einträge aus der Liste ausgeschlossen, die der Expression entsprechen. So gibt beispielsweise die Expression
projektbearbeiter->reject(name='Administrator')
eine Liste zurück, die alle Projektbearbeiter ausser dem Administrator enthält.
->first

Der first Operator liefert aus einer Liste den ersten Eintrag. Am häufigsten kommt der first Operator zur Anwendung, wenn aufgrund einer Selektion ein Objekt als Ergebnis verwendet werden soll. Da der ->select Operator eine Liste als Ergebnis liefert, muss darauf noch ->first angewendet werden, damit das Ergebnis ein einzelnes Objekt ist. Beispiel:

phasen->select(code= 'OFFERTE')->first.offeneleistungen->size

zeigt in einer Liste von Projekten die Anzahl offener Leistungen der Phase "OFFERTE" an.

->orderby Mit dem orderby Operator können Listen sortiert werden. adresseintrag->orderby(projekte->size) ordnet die Liste der Adresseinträge nach der Anzahl der Projekte, bei denen sie Kunden sind.
->orderdescending

Mit dem orderdescending Operator können Listen absteigend sortiert werden (sonst gleich wie ->orderby):

adresseintrag->orderdescending(projekte->size)

Anmerkung: Als Expression in einem Expression-Ordner verwendet haben diese Operatoren keine Bedeutung, da die Liste die Sortierung selber vornimmt.

->orderMulti

Der Operator oderMulti erlaubt das Sortieren einer Liste nach verschiedenen Sortierkriterien. Er kann in einer OCL-Expression auf einer Liste angewandt werden und erwartet einen String als Argument. Dieser String enthält die verschiedenen Sortierkriterien als einzelne OCL-Expressions, getrennt durch Semikolons:

projekt->ordermulti('projektleiter.name;code.asstring')

als Expression eines Expressionordners liefert sie eine Liste aller Projekte, sortiert in erster Linie nach dem Namen des Projektleiters, in zweiter Linie nach dem Projektcode. Diese Sortierung wird in der Listenanzeige allerdings nur sichtbar, wenn Sie die Sortierung auf Listenspalten entfernen. Doppelklicken Sie auf eine sortierte Listenspalte, bis diese keinen Sortierpfeil mehr anzeigt.

ordermulti mit Zusatzfeldern

Will man nach Zusatzfeldern sortieren, hat man das Problem, dass man in der Expression keine Hochkommas verwenden kann. Bei den Zusatzfeldern erfordert das einen Umweg über die interne ID des Zusatzfelds (Einstellungen > Zusatzfelder > rechte Maustaste > Eigenschaften > interne ID):

projekt->ordermulti('projektleiter.name;zusatzfelder
->select(metaZusatzfeld.boldID=<interne ID>)->first.wert')

Je nach Feld-Typ können Sie den Wert wie folgt abfragen:

.wert
.wertBlob
.wertBoolean
.wertInteger
.wertCurrency
.wertDatum
.wertObject

->asSet Ausgehend von einer Liste kann auch eine Member-Referenz angegeben werden. Die Member-Referenz wird dann auf jedem Objekt der Liste angewendet. So ist das Erbebnis eine Liste mit Elementen des Member-Typs. Beispiel projekt.kunde liefert in einem Expressionordner eine Liste aller Kunden. Der Nachteil dieser Liste ist, dass die Kunden zum Teil doppelt erscheinen, da die Expression projektweise alle Kunden zusammenträgt. Dies lässt sich durch die Anwendung des asSet Operators beheben, welcher eine Liste in eine Menge (im Sinne der Mengelehre) umwandelt: projekt.kunde->asSet liefert eine eindeutige Liste aller Kunden.
->asBag Liefert die Liste mit allen Einträgen, also auch die Doppelten (im Gegensatz zu asSet, siehe oben). Da der Aufruf einer Liste im Vertec sowieso eine Collection mit allen Einträgen zurückliefert, ist die explizite Angabe von asBag unnötig.
->union

Der union-Operator erlaubt die Zusammenfassung zweier Listen in einer. Er kann in einer OCL-Expression auf einer Liste angewandt werden und erwartet eine weitere Liste (Collection) als Argument:

offeneLeistungen->union(verrechneteLeistungen)

als Expression auf einem Projekt liefert alle offenen und verrechneten Leistungen des Projekts. Mit dieser Liste kann normal weitergearbeitet werden. Als Typ wird immer die gemeinsame Basisklasse verwendet, dessen Attribute zur Verfügung stehen. Das obige Beispiel liefert also eine Liste mit Einträgen vom Typ Leistung. Bei einer Expression projekt->union(adresseintrag) wäre die gemeinsame Basisklasse z.B. UserEintrag.

->collect Der Collect-Operator erlaubt es, mittels Variable einen komplexen Teilausdruck nur einmal zu formulieren, aber mehrfach zu verwenden.

Zum Beispiel will man die Summe der Honorarnoten (netto) des jeweils letzten Jahres anzeigen:

rechnungen->select(datum.year=date.year-1)->collect(umsatz+vorschussbetrag-vorschusseffektiv)->sum

ohne den Collect-Operator müsste man die ganze '->select'-Expression für jeden Wert (umsatz, vorschussbetrag etc) wiederholen.

Man kann auch noch einen Schritt weitergehn, indem man den Wert, der aus dem collect resultiert, einer Variable zuweist und damit weiterarbeitet.

Als Beispiel nehmen wir eine Liste von Projekten. Jedes Projekt befindet sich (in diesem Beispiel) entweder in einem Ordner "Kundenprojekte" oder in einem Ordner "Interne Projekte" oder in einem Ordner "Auftragsprojekte". Diese Ordner sind jeweils Unterordner des Ordners "Projektkategorie". In der Liste möchten wir nun entweder 1, 2, oder 3 anzeigen, je nachdem, in welchem Ordner sich das Projekt in der Liste befindet:

ordner->select(parentordner.bezeichnung='Projektkategorie')
->first.bezeichnung.substring(1,1)->asSet->collect(x|if x ='K'then
'1'else if x='I'then'2'else if x='A'then'3'
else'Keine Angabe'endif endif endif)->first

Die Expression geht von einem Projekt aus (jedes Projekt in der Liste). ordner bedeutet also die Ordner, in denen sich das Projekt befindet. Wir suchen zuerst den Unterordner des Ordners Projektkategorie. Von diesem nehmen wir den ersten Buchstaben (bezeichnung.substring(1,1)). Das ist nun ein einzelner Buchstabe, entweder "K" oder "I" oder "A". Da der Collect-Operator nur auf einer Liste ausgeführt werden kann, fügen wir ein ->asSet an. Nun kommte der ->collect Operator dran: Anstatt für jede if Abfrage den ganzen ordner->select(...) Abschnitt zu wiederholen, kann einfach die Variable x mehrfach eingesetzt werden. Das x in der Klammer bezieht sich auf den aktuellen Wert. Das ist ja im Moment unser einzelner Buchstabe. Nun können wir über das x diesen Buchstaben abfragen und je nachdem den gewünschten Wert einsetzen. Das Ganze ist nun noch immer eine Liste. Wir möchten aber den einzelnen Wert im Feld anzeigen. Deshalb fügen wir wieder ein ->first an.

->append(obj) Gibt die Liste zurück, die das obj am Schluss noch angehängt hat
->at(i) Gibt das Objekt an der Stelle i zurück. Der Index i beginnt mit 1.
->count(obj) Gibt an, wieviele Male obj in der Liste enthalten ist.
->difference(list2) Gibt die Liste zurück, die der ursprünglichen Liste ohne die Elemente von list2 entspricht.
->excluding(obj)
Gibt die Liste zurück, aus der das obj entfernt wurde.
->includes(obj)
Gibt an, ob obj in der Liste enthalten ist
->includesAll(list2)
Gibt an, ob alle Objekte in list2 in der Liste enthalten sind.
->including(obj)
Dasselbe wie ->append
->intersection(list2)
Gibt die Schnittmenge der beiden Listen zurück, das heisst eine Liste aller Objekte, die in beiden Listen enthalten sind.
->isEmpty
True, wenn keine Liste oder Länge der liste=0, sonst False.
->prepend(obj)
Gibt die Liste zurück, bei der das obj am Anfang eingesetzt ist.
->subsequence(start, stop)
Gibt eine Liste von Index start bis und mit Index stop zurück. Die Indizes sind 1 basiert und werden automatisch auf gültige Werte korrigiert (d.h. stop kann auch grösser als die Listenlänge sein, ohne dass es Fehler gibt).
->symmetricDifference(list2)
Gibt eine Liste mit allen Elementen der Liste, welche nicht in liste2 sind, sowie alle Elemente von liste2, welche nicht in der Liste sind, zurück.
->sum Summiert die Zahlenwerte einer Liste und gibt die Summe zurück.

Die Listenoperatoren ->exists und ->forAll funktionieren nicht.

Konvertierungsoperatoren

Häufig stellt sich die Aufgabe, eine Zeichenfolge in einen Datumswert umzuwandeln, eine Zahl in eine Zeichenfolge umzuwandeln, etc. Nachfolgend eine Liste der verfügbaren Konvertierungsoperatoren:

->asString (auch .asString) wandelt eine Zahl oder Datumswert in eine Zeichenfolge (String) um.
->dateToFloat wandelt einen Datumswert in eine Zahl um (die Zahl sagt Ihnen wenig: (Anzahl Tage seit 1.1.1900). Diese Operation wird vor allem für das Rechnen mit Datumswerten verwendet (z.B. 30 Tage zum heutigen Datum dazuzählen, siehe Beispiel weiter unten).
->floatToDate

wandelt eine Zahl in ein Datum um. Die folgenden Expression zählt zum datum des Eintrags (z.B. einer Leistung) 31 Tage dazu:

(datum->dateToFloat+31)->floatToDate

->strToDate wandelt einen String in ein Datum um. Dieser Operator ist dann nützlich, wenn man mit einem Datum arbeiten muss, das vorher nicht bekannt oder nur als String vorhanden ist (z.B. in Scripts, wenn vom Benutzer ein Datum abgefragt wird). Ansonsten sollte der Operator encodeDate verwendet werden, der weiter unten beschrieben wird (also nicht '01.09.2010'->strToDate, sondern encodeDate(2010,09,01))
->stringToFloat wandelt eine Zeichenfolge in ein Zahl um. Ist die Zeichenfolge keine Zahl, wird 0 ausgegeben.
->stringToList

Stellt einen String als Liste dar. Einzelne Wörter werden getrennt bei der Wortgrenze oder bei einem Delimeter. Wörter innerhalb doppelter Anführungszeichen gelten als ein Wort.

TimSession.allinstances->first.login.name.stringToList

Gibt den Namen des eingeloggten Bearbeiters als Liste zurück. So kann beispielsweise über

TimSession.allinstances->first.login.name.stringToList->last

nur der Nachname angezeigt werden.

->isEmpty Der Operator ->isEmpty gibt zurück, ob ein Linkmember leer ist. So gibt die Expression projektleiter->isEmpty, ausgeführt auf einem Projekt, mit einem boolschen Wert (wahr, falsch) zurück, ob ein Projektleiter zugeordnet ist (falsch) oder nicht (wahr).
.isNull/.notNull Oft ist es nützlich, einen Nullwert zu erkennen. Ab Version 5.5 muss das nicht mehr über einen String-Vergleich geschehen, sondern kann über die OCL Operatoren isNull und notNull abgefragt werden.

Beispiel: statt

projekt->select(betreffend.asstring='') (alle Projekte ohne Betreffend)

kann man nun

projekt->select(betreffend.isNull)

ausführen.

Anmerkung: Diese Operatoren sind nicht zu verwechseln mit dem isEmpty-Operatoren, welcher eine Verknüpfung abfragt. Um beispielsweise zu wissen, ob ein Projekt einen Kunden zugeordnet hat, kann nicht mit isNull abgefragt werden, sondern mit kunde->isEmpty.
->listToString

Durch diesen Operator können Listen in Strings dargestellt werden. So liefert die Expression:

phasen.code->listToString(',')

ausgeführt auf einem Projekt (z.B. via Listeneinstellungen) die Liste der Phasen-Codes, mit "," getrennt.

.toLower/.toUpper Sehr häufig ist das Resultat einer Expression ein string (Zeichenfolge). Mit dem Operator .toLower wird die Zeichenfolge in Kleinbuchstaben verwandelt, mit dem Operator .toUpper in Grossbuchstaben.
.asHMString Interpretiert eine Zahl als Anzahl Minuten und formatiert sie als Stunden:Minuten. Es werden auch negative Zeitwerte unterstützt.
.asTimeString Interpretiert eine Zahl als Anzahl Minuten und formatiert sie als Tageszeit. Negative Werte werden nicht dargstellt.
.asMinuteString Verfügbar ab Version 5.2.0.23. Interpretiert eine Zahl als Anzahl Minuten und formatiert sie gemäss Format in den Systemeinstellungen. Es werden auch negative Zeitwerte unterstützt.
.asStringBy
Language(<Sprache>)

Fragt die entsprechende Sprachversion eines Members ab. Dies gilt für alle MLStrings, das sind Werte, die für die verschiedenen Sprachen jeweils ein eigenes Feld haben (Beispiele sind Tätigkeiten, Spesen- und Auslagetypen). Zum Beispiel bei Auslagetypen auf einer Rechnung: Wenn man die französische Bezeichnung des Typs haben möchte, kann dies mit folgender Expression geschehen:

text.asStringByLanguage('FR')

Mögliche Sprachen / Parameter sind standardmässig 'DE', 'FR', 'IT', 'EN'. Wenn unter Einstellungen > Sprachen weitere Sprachen hinzugefügt wurden, wird davon jeweils die interne Bezeichnung verwendet.

.pad(Anzahl,Platzhalter)

Der .pad-Operator füllt einen Integer-Wert bis zur Anzahl angegebenen Zeichen mit dem als Platzhalter angegebenen Zeichen auf. Das Ergebnis ist ein String.

Dies ist zum Beispiel dann nützlich, wenn man für eine alphanumerische Sortierung führende Nullen braucht.

6.pad(2,'0') ergibt 06
6.pad(3,'0') ergibt 006
...

Zahlenoperatoren

abs

Dieser Operator gibt den absoluten Wert einer Zahl zurück.

(-2.8).abs = 2.8
(2.8).abs = 2.8

floor

Abrundungsfunktion. Gibt von einer reellen Zahl die nächstliegende kleinere Ganzzahl zurück.

(-2.8).floor = -3
(2.8).floor = 2
2.floor = 2

round

Rundet einen Zahlenwert auf die nächste Ganzzahl und gibt diese als Resultat zurück.

(-2.8).round = -3
(2.3).round = 2
(2.5).round = 3

Auf fünf Rappen runden:

  (wert * 20)->round / 20

Runden auf zwei Nachkommastellen:

  (wert * 100)->round / 100

Siehe zu diesem Thema auch Runden in Scripts.

Stringbearbeitungsoperatoren

->length

Dieser Operator gibt die Anzahl Zeichen einer Zeichenfolge zurück. Zum Beispiel gibt die Expression adresseintrag->select(standardplz.length=4) alle Adressen mit einer vierstelligen PLZ zurück.

->substring(Anfang, Ende) Dieser Operator schneidet aus einer Zeichenfolge die Zeichen zwischen "Anfang" und "Ende" aus. So liefert die Expression code->substring(1,1), ausgeführt auf einem Projekt, den ersten Buchstaben des Projektcodes. Ein anderes Beispiel: Sie möchten das Erfassungsjahr des aktuellen Eintrags anzeigen. Vertec speichert das Erfassungsdatum im Member "creationdatetime" ab. Die folgende Expression nimmt das "creationdatetime", wandelt es in einen string um und setzt die hintersten 4 Zeichen: creationdatetime->asstring->substring(7,10). Diese Methode kann natürlich auch für das aktuelle Systemdatum benutzt werden (Expression now, kann z.B. im Zusammenhang mit Speicherpfaden bei Word-Reports wertvoll sein, siehe entsprechende Artikel)
replaceString

Die Syntax lautet wie folgt:

<string>->replaceString(substring, replacement)

Sie geben darin den Teil an, den Sie ersetzen möchten (substring) sowie den Teil, durch den er ersetzt werden soll (replacement). Rückgabewert ist wieder ein String.

Sie möchten beispielsweise in einem Text alle Meyer durch Maier ersetzen:

<text>->replaceString('Meyer', 'Maier')

Der Replace-String ist Case-Sensitiv, das heisst, er beachtet die Gross/Klein-Schreibung.

replaceRegex

Die Syntax lautet wie folgt:

<string>->replaceRegex(template, replacement)

Hier kann ein regulärer Ausdruck, eine sogenannte Regular Expression, angegeben werden, sowohl für den Teil, den Sie ersetzen möchten (template) wie auch für den Teil, der ersetzt werden soll (replacement). Rückgabewert ist wieder ein String.

Ein kleines Beispiel, was damit möglich ist:

In einem Text sind Bezeichnung der Art <Abschnitt>:<Kapitel> vorhanden, z.B. 2:15 oder 3:10. Diese Bezeichnungen sollen getauscht werden, sodass sie als 15:2 bzw. 10:3 dargestellt werden. Dies kann mit folgender Expression geschehen:

<text>->replaceRegex('([0-9]*):([0-9]*)', '$2:$1')

    Bearbeiteroperatoren

    Speziell für die Klasse Projektbearbeiter gibt es folgende Operatoren:

    OperatorBeschreibungab Version

    ->getSollzeit(von, bis)

    Sollzeit in der Periode (minuten)

    ->getArbeitszeit(von, bis)

    Arbeitszeit in der Periode (minuten). Berechnet aus der Summe aller vorhandenen Leistungen plus der Ferien, die als Abwesenheiten erfasst wurden.

    ->getUeberzeitvortrag(datum)

    liefert den Ueberzeitsaldo per Datum-1, ausser auf Datum ist ein Vortrag erfasst, dann wird dieser Vortrag geliefert.

    ->getUeberzeitvortragDatum(datum)

    liefert Datum des letzten Ueberzeitvortrags vor Datum

    5.4

    ->getUeberzeitsaldo(datum)

    liefert Ueberzeitsaldo per Datum

    5.4

    ->getFerienVorgabe(von,bis)

    Ferienguthaben innerhalb Periode

    ->getFerienBezug(von,bis)

    Ferienbezug, sowohl Abwesenheiten als auch Ferienleistungen

    5.4

    ->getFerienVortrag(datum)

    liefert den Feriensaldo per Datum-1, ausser auf Datum ist ein Vortrag erfasst, dann wird dieser Vortrag geliefert.

    ->getFerienVortragdatum(datum):

    liefert Datum des letzten Ferienvortrags vor Datum

    5.4

    ->getFerienStart(datum)

    liefert Startdatum für Berechnung des Ferienguthabens. Ist der nächste Ferien-Stichtag nach dem letzen Vortrag

    5.4

    ->getFerienEnd(datum)

    liefert Enddatum für Berechnung des Ferienguthabens. Ist das nächst Ferienperiode-Ende

    5.4

    ->getFerienSaldo(datum)

    liefert FerienSaldo per Datum

    5.4

    ->getFeriensaldoAbgegrenzt(datum)

    Berechnet den abgegrenzten Feriensaldo per Datum unter Berücksichtigung des Ferienguthabens bis zum Datum. Beispiel:

    Gegeben ist ein Ferienguthaben von 200 Stunden pro Jahr, vorgegeben von der Gruppe. Der Ferienstichtag ist der 01.01. Auf diesen Stichtag wurde dem Mitarbeiter ein Ferienvortrag von 20 Stunden gutgeschrieben. Das bedeutet: Der Mitarbeiter hat ein gesamtes Ferienguthaben für das Jahr 2013 von 220 Stunden.

    Nun möchte ich den Feriensaldo dieses Mitarbeiters berechnen per 31. März 2013. Es gibt folgende Varianten:

    • getFeriensaldo(encodeDate(2013,3,31)): Nimmt den Ferienvortrag (20 Stunden) plus das Ferienguthaben (200 Stunden) und zählt die in im Zeitraum bis zum 31.03.2013 bezogenen Ferien ab. Resultat: 204:00 Stunden. So viele Ferien hat der Mitarbeiter noch zugut.
    • getFeriensaldoAbgegrenzt(encodeDate(2013,3,31)): Nimmt den Ferienvortrag (20 Stunden) plus den Anteil des Ferienguthabens bis zum 31.03.2013 (49:19) und zählt die im Zeitraum bis zum 31.03.2013 bezogenen Ferien ab. Resultat: 53:19 Stunden. So viele Ferien hätte der Mitarbeiter am 31. März 2013 noch zugut gehabt.
    5.8

    ->getLohn(von,bis)

    Lohn innerhalb der angegebenen Periode

    5.4

    ->getGemeinkosten(von,bis)

    Gemeinkosten innerhalb der angegebenen Periode

    5.4

    ->getSollzeitVorgabe(von, bis) Berechnet die Sollzeit von, bis nur aufgrund der Vorgaben, ohne Berücksichtigung von Feiertagen. Eintritt / Austritt wird berücksichtigt. 5.4.0.21
    ->getSollzeitGroupVorgabe(von, bis) Berechnet die Sollzeit von, bis aufgrund der Gruppen-Vorgaben des Bearbeiters. Das ergibt die Sollzeit, wenn der Mitarbeiter 100% arbeiten würde. 5.4.0.21
    ->getSollzeitOnlyGroupAbw(von, bis)

    Berechnet die Sollzeit eines Mitarbeiters unter Berücksichtigung nur der gruppenbasierten Abwesenheiten (Feiertage etc.).

    Abwesenheiten werden im Unterschied zum GetSollzeit Operator nur von den Gruppen berücksichtigt. Auf dem Mitarbeiter erfasste Abwesenheiten werden nicht berücksichtigt. Der Beschäftigungsgrad des Mitarbeiters wird berücksichtigt.

    5.8
    ->getBeschaeftigungsgrad(datum) Liefert den Beschäftigungsgrad des Mitarbeiters zu einem bestimmten Datum.
    Die Berechnung des Beschäftigungsgrads erfolgt unabhängig davon, ob der Mitarbeiter am Stichdatum Sollzeit hat oder nicht. Ausschlaggebend ist das Verhältnis der Wochensollzeiten von Bearbeiter und Gruppe.
    5.4.0.21
    ->getAbwesenheitFrei(Abwesenheitstyp, von, bis)

    Operator zum Bestimmen der Frei-Zeit eines bestimmten Abwesenheitstyps. Beispiel:

    Bearbeiter->getAbwesenheitFrei('Feiertag', encodedate(2013, 1, 1), encodedate(2013, 1, 31))

    Die Berechnung geschieht wie folgt:

    1. Berechnung der Sollzeit für die angegebene Periode ohne Berücksichtigung von Abwesenheiten.
    2. Berechnung der Sollzeit unter Berücksichtigung nur der Frei-Abwesenheiten des angegebenen Typs.
    3. Das Resultat ist die Differenz der beiden Werte in Minuten (Integer).

    Wird ein nicht existierender oder ein falscher (nicht Frei) Abwesenheitstyp angegeben, ist das Resultat 0.

    Versionen vor 5.8

    Zur Abfrage des Abwesenheitstyps wird in Versionen vor 5.8 die (sprachabhängige) Bezeichnung verwendet.

    Werden am gleichen Tag mehrere Abwesenheiten erfasst, kann Vertec den Einfluss der einzelnen Abwesenheit nicht eindeutig bestimmen, da die Abwesenheitstypen keine Sortierung bezüglich Wichtigkeit kennen. Wenn man also am Ostermontag ("Feiertag") auch noch krank ist ("Krankheit"), dann stimmt zwar die Sollzeit, aber dieser Operator gibt sowohl bei "Feiertag" als auch bei "Krankheit" jeweils 0 an, da der andere Abwesenheitstyp auch den ganzen Tag belegt.

    Versionen ab 5.8

    Zur Abfrage des Abwesenheitstyps wird in Versionen ab 5.8 der (sprachunabhängige) Code verwendet.

    Ab dieser Version haben Abwesenheitstypen ein Attribut Priorität. Dieses wird im Falle von überlappenden Abwesenheiten beachtet. Es werden beliebig viele überlappende Einträge berücksichtigt und die "Sichtbarkeit" der in Frage kommenden Abwesenheiten bestimmt sich durch den Prioritätswert auf ihrem Typ.

    Falls die Prioritäten gleich sind, werden die folgenden Prioritätsregeln angewendet:

    1. Bei Minutenabwesenheiten mit unterschiedlichen Typen gewinnt die Abwesenheit mit dem grösseren Minutenwert.
    2. Bei Minuten- und ganztägiger Abwesenheit gewinnt die ganztägige.
    3. Falls eine Abwesenheit auf dem Bearbeiter und eine auf der Benutzer-gruppe definiert ist, gewinnt die auf dem Bearbeiter.
    4. In allen anderen Fällen gewinnt die Abwesenheit mit der höheren ID, also die, welche später erfasst wurde.
    5.7
    ->getFerienbezugAbw(von, bis)

    Operator für die Berechnung des Ferienbezugs unter Berücksichtigung von nur als Abwesenheiten erfassten Ferien. Beispiel:

    Bearbeiter->getFerienbezugAbw(encodedate(2012, 1, 1), encodedate(2012, 1, 31))

    Als Resultat werden die Abwesenheiten der Art Ferien in der entsprechenden Periode zurückgeliefert, in Minuten (Integer).

    Für die normale Ferienberechnung kann der Operator
    ->getFerienBezug(von,bis) verwendet werden.

    5.7
    ->getSollzeitGroup(von, bis)

    Dieser Operator liefert die Sollzeit für die Gruppe (100%), unter Berücksichtigung von Abwesenheiten auf der Gruppe. Beispiel:

    Bearbeiter->getSollzeitGroup(encodedate(2012, 1, 1), encodedate(2012, 1, 31))

    Als Resultat wird die entsprechende Sollzeit zurückgeliefert, in Minuten (Integer).

    5.7
    ->currentAbwesenheiten(datum)

    Dieser Operator liefert eine Liste von Abwesenheiten, die für den angegebenen Tag zur Anwendung kommen. Beispiel:

    Bearbeiter->currentAbwesenheiten(encodedate
    (2012,6,11))

    liefert eine Liste der für diesen Bearbeiter für den 11.06.2012 erfassten Abwesenheiten.

    5.7
    ->getTrackingUsers

    Der Operator getTrackingUsers liefert für einen Bearbeiter eine Liste aller Bearbeiter, für die er Leistungen, Spesen und Auslagen erfassen darf.

    Das wird im Bearbeiter-Auswahlfeld auf Leistungen, Spesen und Auslagen verwendet und kann auch über OCL abgefragt werden.

    Beispiel:

    TimSession.allinstances->first.login->getTrackingUsers

    Liefert für den aktuell eingeloggten Bearbeiter die Liste aller Bearbeiter, für die er erfassen darf.

    6.0

    OCL Operatoren für Ressourcenplanung

    .getResPlanMinuten(von, bis) Gibt die verplante Zeit für den Bearbeiter für die angegebene Periode (von, bis Datum) in Minuten zurück.
    .getResRsrcMinuten(von, bis)

    Gibt die Ressourcenzeit für den Bearbeiter für die angegebene Periode (von, bis Datum) in Minuten zurück. Das ist nicht die noch verfügbare Zeit, sondern die gesamte Ressourcenplan-relevante Sollzeit. Der Unterschied zur Sollzeit ist, dass nur Abwesenheiten vom Typ "Frei" die Sollzeit beeinflussen, von der Ressourcenzeit hingegen werden alle Arten von Abwesenheiten (Frei, Ferien, Kompensation) abgezogen (siehe dazu auch die Tabelle über die Arbeitszeit-Ausnahmen im Artikel Abwesenheiten).

    Ab der Vertec Version 5.7 werden zusätzlich auch die als Ferien erfassten Leistungen abgezogen.

    Berechnung der Kompensationszeit für einen Zeitraum

    Sollen die effektiven Kompensationsabwesenheiten pro Bearbeiter für einen bestimmten Zeitraum ermittelt werden, kann dies wie folgt geschehen:

    getSollzeit(von, bis) - getResRsrcMinuten(von, bis) - getferienbezug(von, bis)

    So werden die arbeitsfreien Tage (Samstag, Sonntag, Feiertage etc.) automatisch mitberücksichtigt.

    Beispiel

    Beispiel für die Ermittlung der Kompensationszeit für den Monat Juli:

    self.getSollzeit(encodeDate(2013,07,01),encodeDate(2013,07,31))
    - self.getResRsrcMinuten(encodeDate(2013,07,01),encodeDate(2013,07,31))
    - self.getFerienbezug(encodeDate(2013,07,01),encodeDate(2013,07,31))

    Erklärung

    Abwesenheiten vom Typ Frei beeinflussen die Sollzeit (Minus).

    Abwesenheiten vom Typ Frei, Ferien und Kompensation sowie die als Leistungen erfassten Ferien beeinflussen die Ressourcenzeit (Minus).

    Die Abwesenheiten vom Typ Frei heben sich somit auf. Es bleiben Ferien und Kompensation übrig. Darum müssen noch die Ferien abgezogen werden. Der Zeitunterschied ist die Kompensationszeit.

    OCL Operatoren für die Berechtigungsprüfung

    Es gibt ab Version 6.0 OCL Operatoren für die Abfrage von Berechtigungen. Grundsätzlich gibt es 3 Arten von Berechtigungen:

    • Member-Rechte (read, write), können für ein einzelnes Member abgefragt werden.
    • Klassen- bzw. Objekt-Rechte (create, delete, execute, view), können für einen Klassentyp oder für ein Objekt abgefragt werden.
    • User-Rechte (Standard Benutzerrechte) können auf einem Abstractuser (Benutzergruppe oder Projektbearbeiter) abgefragt werden.

    Die folgenden Operatoren für Berechtigungsabfragen liefern einen Boolean (Wahr/Falsch) Wert zurück.

    Member-Rechte

    Die Rechte auf einzelnen Members werden auf dem Objekt abgefragt und der Name des Members als Argument übergeben:

    OperatorRechtname
    Object->isMemberReadable(memberName) rtRead
    Object->isMemberWritable(memberName) rtWrite

    Klassen- bzw. Objekt-Rechte

    OperatorRechtname
    Class->isCreatable rtCreate
    Object->isDeletable rtDelete
    Object->isExecutable rtExecute (Reports und Scripts)
    Object->isViewable rtSingleForm (darf das Objekt in eigenem Fenster gezeigt werden?)

    User-Rechte

    Bei der Abfrage der User-Rechte muss der Name des entsprechenden Rechts übergeben werden:

    User->hasRight(rightname)
    Rechtnamen für hasRightStandard Benutzerrecht
    'admin', Super
    'supervisor' Projekt Administrator
    'manager' Projekt Leiter
    'selftracking' Projekt Zeiterfasser
    'folderlinks_admin' Ordner-Links Administrator
    'folderlinks_user' Ordner-Links User
    'address_admin' Adress Administrator
    'address_user' Adress User
    'benchmarking' Benchmarking
    'treeview' Baumansicht
    'systemproperties' Systemeinstellungen
    'trackingcontroller' Projekt Fremderfasser
    'book' Rechnungen buchen
    'book_creditor' Kreditoren buchen
    'benchmarking_no_users' Benchmarking ohne Bearbeiterzahlen
    'teamleader' Teamleiter
    'export' Exportieren

    Falls ein unbekannter Recht-Namen angegeben wird, gibt der hasRight-Operator False zurück.

    OCL Operatoren für Projekteinträge

    Projekteinträge ist der Sammelbegriff für Leistungen, Spesen und Auslagen. Diese wiederum teilen sich auf in offen und verrechnet. Die Zuordnungen zu Projekten, Phasen und Bearbeitern ist im Modell jeweils auf der untersten Ebene definiert, also auf den offenen oder verrechneten Leistungen bzw. Spesen oder Auslagen.

    Für den einfachen Zugriff auf Projekt, Phase und Bearbeiter gibt es ab Version 5.7 deshalb folgende Operatoren:

    OperatorBeschreibung
    getProjekt Liefert das Projekt zurück, auf welches die Leistung, Spese oder Auslage erfasst wurde.
    getPhase Liefert die Projektphase zurück, der die Leistung, Spese oder Auslage zugeordnet ist.
    getBearbeiter Liefert den Projektbearbeiter zurück, welcher die Leistung, Spese oder Auslage erfasst hat.

    Beispielsweise eine Liste von Bearbeitern aufgrund von Leistungen einer Rechnung:

    leistungen.getBearbeiter->asSet

    Bei Vertec Versionen vor 5.7 sind beim Zugriff auf eine Liste mit allgemeinerem Typ (Leistung, Spesen, Auslagen) Casts notwendig. Beispielsweise eine Liste von Bearbeitern aufgrund von Leistungen einer Rechnung:

    leistungen->collect(if oclIsTypeOf (VerrechneteLeistung) then oclAsType
    (VerrechneteLeistung).bearbeiter else oclAsType(OffeneLeistung).bearbeiter endif)->asSet

    OCL Operatoren für Projektphasen

    phaseGetProjekt

    Ab Version 6.0. Subphasen einer Projektphase haben keine direkte Verbindung zum Projekt, dem sie zugehören. Der OCL-Operator phaseGetProjekt liefert für eine beliebige Phase oder Subphase das Projekt.

    OCL-Beispiel auf einer Subphase:

    self.phaseGetProjekt

    liefert als Resultat das Projekt der obersten Phase.

    Operatoren für Links

    usereintrag->getLinks(rolle) Gibt eine Liste von Objekten zurück, die unter dieser Rolle mit dem Eintrag verlinkt sind.

    Projektbearbeiter->getLinks('archiveintraege')

    Leistungssummenoperatoren

    Für die Optimierung von kundenspezifischen Auswertungen mit Expressionordnern und Listenspalten oder zur Verwendung in benutzerdefinierten Berichten steht die beschleunigte Summierung und Gruppierung in Form eines OCL Operators groupLeistungen zu Verfügung. Die Summierung via OCL ist nur in Zusammenhang mit der Lizenzoption Benchmarking verfügbar. Alle Informationen zu den Leistungssummen-Operatoren finden Sie im Artikel über Leistungssummen.

    Datumsoperatoren

    date der date Operator liefert das aktuelle Datum.
    dateToFloat verwandelt einen Datum/Zeit Wert in eine Fliesskommazahl. Der ganzzahlige Anteil ist die Anzahl Tage seit dem 30.12.1899. Der Bruchteil gibt die Uhrzeit an.
    floatToDate verwandelt eine Zahl in einen Datum/Zeit Wert.
    year berechnet das Jahr eines Datumswertes.
    month berechnet den Monat (1-12) eines Datumswertes.
    day berechnet den Tag des Monats eines Datumswertes.
    hours gibt die Stunden des Zeitwertes als integer zurück.
    minutes gibt die Minuten des Zeitwertes als integer zurück.
    seconds gibt die Sekunden des Zeitwertes als integer zurück.
    milliseconds gibt die Milisekunden des Zeitwertes als integer zurück.
    incMonth(anzahl) zählt Anzahl Monate zu einem Datum hinzu. Man kann damit auch retour zählen: date.incMonth(-1) zählt zum Beispiel vom aktuellen Datum einen Monat zurück.
    incDay(anzahl) zählt Anzahl Tage zu einem Datum hinzu. Man kann damit auch retour zählen: date.incDay(-10) zählt zum Beispiel vom aktuellen Datum zehn Tage zurück.
    firstOfYear berechnet für ein Datum das Datum des ersten Tag des Jahres (1. Januar).
    lastOfYear berechnet für ein Datum das Datum des letzten Tag des Jahres (31. Dezember).
    firstOfQuarter berechnet den ersten Tag des Quartals.
    lastOfQuarter

    berechnet den letzten Tag des Quartals. Beispiel:

    self->groupleistungenP(date.firstOfQuarter.asstring,
    date.lastOfQuarter.asstring, '')->collect(minutenintoffen+
    minutenintverrechnet)->sum

    als Spaltenexpression in einer Projektliste zeigt den erfassten Aufwand (offen) im aktuellen Quartal an.
    firstOfMonth berechnet den ersten Tag des Monats.
    lastOfMonth berechnet den letzten Tag des Monats.
    mondayOfWeek berechnet das Datum des Montags einer Woche.
    encodeDate
    (year, month, day)

    berechnet ein Datum aufgrund von Zahlenwerten für Jahr, Monat und Tag. Beispiel: Ordner mit allen Rechnungen, die im Jahr 2012 erstellt wurden:

    rechnung->select((datum >= encodeDate(2012,01,01)) and (datum <= encodeDate(2012,12,31)))

    formatdatetime
    (formatstring)
    Formatiert Datum und Zeit gemäss Formatstring (ab Version 5.2.0.15).

    Beispiel:

    creationdatetime.formatdatetime('c')-> '16.10.2010 15:24:31'

    Der Formatstring kann folgendes enthalten:

    • c: Zeigt das Datum im globalen Format Kurzes Datum (ShortDateFormat), gefolgt von der Zeit im globalen Format Lange Uhrzeit (LongTimeFormat). Wenn es keinen Zeitwert hat, erscheint nur das Datum.
    • d: Tag als Zahl ohne vorangestellte 0 (1-31).
    • dd: Tag als zweistellige Zahl (01-31).
    • ddd: Tag als Abkürzung (Mo-So) gemäss globalen Einstellungen (ShortDayNames).
    • dddd: Tag als Wort (Montag-Sonntag) gemäss globalen Einstellungen (LongDayNames).
    • m: Monat als Zahl ohne vorangestellte 0 (1-12). Wenn m direkt auf h oder hh folgt, wird es als Platzhalter für Minuten statt für den Monat interpretiert, und es werden die Minuten angezeigt.
    • mm: Monat als zweistellige Zahl (01-12). Wenn mm direkt auf h oder hh folgt, wird es als Platzhalter für Minuten statt für den Monat interpretiert, und es werden die Minuten angezeigt.
    • mmm: Monat als Abkürzung (Jan-Dez) gemäss globalen Einstellungen (ShortMonthNames).
    • mmmm: Monat als Wort (Januar-Dezember) gemäss globalen Einstellungen (LongMonthNames).
    • yy: Jahr als zweistellige Zahl (00-99).
    • yyyy: Jahr als vierstellige Zahl (0000-9999).
    • h: Stunden ohne vorangestellte 0 (0-23).
    • hh: Stunden als zweistellige Zahl (00-23).
    • n: Minuten ohne vorangestellte 0 (0-59).
    • nn: Minuten als zweistellige Zahl (00-59).
    • s: Sekunden ohne vorangestellte 0 (0-59).
    • ss: Sekunden als zweistellige Zahl (00-59).
    • z: Milisekunden ohne vorangestellte 0 (0-999).
    • zz: Milisekunden als dreistellige Zahl (000-999).
    • t: Zeitwert im Format der kurzen Uhrzeit (ShortTimeFormat), z.B. 11:37.
    • tt: Zeitwert im Format der langen Uhrzeit(LongTimeFormat), z.B. 11:37:40.
    • /: Datumstrennzeichen gemäss globalen Einstellungen (DateSeparator).
    • :: Zeittrennzeichen gemäss globalen Einstellungen (TimeSeparator).
    • xx: Andere Buchstaben und Zeichen werden nicht formatiert, sondern so dargestellt wie eingegeben, z.B. hh...mm ergibt 11...37. Ausnahme: e, g.

    Vergleiche

    Vergleiche von 2 Werten (meist eine Member-Referenz und eine Konstante) kommen in OCL-Expressions häufig vor, meist als Bedingung in einem select Operator.

    Die einfachste Form eines Vergleichs ist der Identitätsvergleich in Form eines "=" Zeichens:

    projekt->select(code='ABC')

    liefert eine Liste aller Projekte, deren Code genau dem String ABC entspricht. Normalerweise sollte diese Liste nur ein Projekt umfassen.

    Weitere Möglichkeiten für Vergleiche bieten die bekannten Operatoren für grösser, kleiner oder ungleich (<, >, <>). Vergleiche lassen sich mit Strings und mit Zahlen durchführen. Für Booleans sind Vergleiche nicht sinnvoll, da ein Boolean Wert an und für sich schon in einer Bedingung angegeben werden kann:

    projekt->select(aktiv.asstring='Y')

    funktioniert zwar, ist aber umständlicher als die einfachere Formulierung projekt->select(aktiv).

    String-Vergleiche

    Für Stringvergleiche (oder auch: Zeichenketten-Vergleiche) gibt es zusätzlich die Möglichkeit, Teilstrings zu berücksichtigen. Zu diesem Zweck gibt es die folgenden Vergleichs-Operatoren:

    sqlLike Er hat eigentlich nichts mit SQL zu tun, ausser dass das Format des Musterstrings der Konvention im SQL Standard entspricht. sqllike verwendet für den Vergleich einen Musterstring, der Platzhalterzeichen umfassen kann. Das folgende Beispiel liefert alle Projekte, deren Code mit "AB" beginnt:

    projekt->select(code->sqllike('AB%'))

    sqlLikeCaseInsensitive Ist gleich wie der vorherige sqllike, jedoch ohne die Gross-/Kleinschreibung zu beachten.

    Als Platzhalter können folgende Zeichen verwendet werden:

    • '%': Ersetzt einen beliebig langen String. Z.B. AA% beschreibt alle Strings, die mit AA beginnen.
    • '_': Ersetzt einen einzelnen Buchstaben. Z.B. AA_ beschreibt alle Strings, die mit AA beginnen und danach genau einen beliebigen Buchstaben enthalten.
    regExpMatch Ist der universellste Operator der drei. Er erwartet eine sogenannte Regular Expression (Regulärer Ausdruck). In Vertec können die folgenden grundlegenden Elemente verwendet werden, Gross-/Kleinschreibung wird dabei nicht beachtet:

    ., *, +, [, ], ^, $, -, \

    Bedingungen

    Eine OCL-Expression kann auch Bedingungen enthalten. Da eine Expression aber immer einen bestimmten Wert haben muss, sind im Gegensatz zu Programmiersprachen nur if ... then ... else ... endif Konstruktionen möglich. Ein Beispiel für eine if Bedingung folgt im nächsten Abschnitt über Typ Operatoren.

    Typ Operatoren (oclIsTypeOf, oclIsKindOf, oclAsType)

    Eine ganze Reihe von Operatoren in OCL dient zur Konvertierung von Objekttypen. Natürlich kann der Typ eines Objekts nicht wirklich verändert werden, OCL ist ausschliesslich eine Abfragesprache. Es kann jedoch sein, dass eine Typkonvertierung angegeben werden muss, damit eine OCL-Expression gültig ist.

    Ein Beispiel dafür sind Listen von Adresseinträgen. Die Klasse Adresseintrag ist die Basisklasse für die Klassen Person, Paar, Firma, Kontakt, EinfacheAdresse. In den meisten Fällen sind Listen von Adresseinträge vom Typ Collection(Adresseintrag). Nun soll in einer Adressliste das Vornamen-Attribut eines Personen Objekts dargestellt werden. Die OCL-Expression vorname in den Spalteneinstellungen einer Adressliste führt zur Fehlermeldung "vorname is not a member of Adresseintrag".

    Um die gewünschte Information (allerdings nur bei Personen) trotzdem anzuzeigen, könnte folgende Expression angegeben werden:

    if oclIsTypeOf(Person) then oclAsType(Person).vorname else '' endif

    Die Expression bezieht sich auf das jeweilige Objekt in der Liste und enthält gleich zwei Typoperatoren. oclIsTypeOf prüft, ob das Objekt von einem bestimmten Typ ist, und oclAsType bringt den OCL Interpreter dazu, diesen Adresseintrag als Person zu betrachten und das Member vorname zu akzeptieren.

    Möchte man wissen, ob ein Objekt ein Adresseintrag ist (egal, ob Person, Firma etc.), dann kann man das abfragen mit oclIsKindOf. Zum Beispiel möchte man in einer Liste mit gemischten Objekten den Namen anzeigen, wenn es eine Adresse ist:

    if oclIsKindOf(Adresseintrag) then name.asstring else '' endif

    20.06.2003 | 18.04.2016: Artikel ergänzt: getSollzeitOnlyGroupAbw berücksichtigt den Beschäftigungsgrad.
    Produktlinien: Standard, Expert
    Module: Leistung & CRM