OCL Expressions für alle Einträge
OCL Expressions für Adresseinträge
OCL Expressions für Bearbeiter
OCL Expressions für Projekte / Phasen
OCL Expressions für Rechnungen
OCL Expressions für Rechnungsberichte
OCL Expressions für Vorschüsse
OCL Expressions mit Datumsoperatoren
OCL Expressions für alle Einträge
- Aktuell angemeldeter Benutzer:
Timsession.allInstances->first.login
. Gibt den aktuell eingeloggten Projektbearbeiter zurück.
- Zugriff auf eindeutige Objekt-ID:
objid
(bis Vertec 6.2.0.6 boldid
). Liefert die eindeutige Id-Nummer des Objekts. Diese Nummer wird bei neu erzeugten Objekten fortlaufend vergeben und kann daher auch für Sortierungen nach Erzeugungsreihenfolge nützlich sein.
- Erzeuger eines Eintrags:
creator
- Modifizierer eines Eintrags:
modifier
- Erzeugungsdatum eines Eintrags:
creationDateTime
- Änderungdatum:
modifiedDateTime
OCL Expressions für Adresseinträge
- Alle Adressen:
adresseintrag
.
- Alle Personen:
person
.
- Alle Firmen:
firma
.
- Alle Kontakte:
kontakt
.
- Alle Paare:
paar
.
- Alle einfachen Adressen:
einfacheAdresse
.
- Kunden (Adresseinträge, die eines oder mehrere Projekte haben):
adresseintrag->select(projekte->size>0)
- Adresseinträge, die im Feld "Stellung" den Eintrag CEO haben:
adresseintrag->select(stellung.asstring='CEO')
- Adresseinträge, die keinen Eintrag im Feld "Stellung" haben:
adresseintrag->select(stellung.asstring='')
- Adresseinträge, die einen Eintrag im Feld "Stellung" haben:
adresseintrag->select(stellung.asstring<>'')
- Adresseinträge, die im Feld "Kanton/State" den Eintrag ZH haben:
adresseintrag->select(standardkanton='ZH')
- Personen, die keine Kontaktverknüpfung zu einer Firma haben:
person->select(kontakte->size=0)
- Adresseinträge, die im Namen "wald" enthalten oder deren Namen mit "Treu" beginnt:
adresseintrag->select(name.sqlLike('%wald%') or name.sqlLike('Treu%'))
Die Variante sqlLikeCaseInsensitive
macht denselben Vergleich, achtet aber nicht auf Gross/Kleinschreibung; "and
", "or
" und "not
" sind erlaubt (Klammersetzung beachten, immer kleinschreiben).
- Vornamen von Personen: In Listen können verschiedene Adressarten gleichzeitig angezeigt werden (Personen, Firmen, Kontakte, Paare). Will man in einer solchen Liste den Vornamen der Person anzeigen, muss man eine Fallunterscheidung machen:
if self.oclistypeof(Person) then self.oclastype(Person).vorname else if self.oclistypeof(Kontakt) then
if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.vorname
else self.oclastype(Kontakt).vorname endif else '' endif endif
- Namen von Personen:In der Liste können verschiedene Adressarten gleichzeitig angezeigt werden (Personen, Firmen, Kontakte). Will man in einer solchen Liste den Namen der Person anzeigen, muss man eine Fallunterscheidung machen:
if self.oclistypeof(Person) then self.oclastype(Person).name else if self.oclistypeof(Kontakt) then
if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.name
else self.oclastype(Kontakt).name endif else '' endif endif
- Namen aller Adresseinträge (Firmen, Kontakte, Personen, Paare):
if self.oclistypeof(Paar) then if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then if self.oclastype(Paar).personA.name.asstring = self.oclastype(Paar).personB.name.asstring then self.oclastype(Paar).personA.name else self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).personB.name endif else if self.oclastype(Paar).personA->notempty then if self.oclastype(Paar).personA.name.asstring = self.oclastype(Paar).nameb.asstring then self.oclastype(Paar).personA.name else self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).nameb endif else if self.oclastype(Paar).personB->notempty then if self.oclastype(Paar).namea.asstring = self.oclastype(Paar).personB.name.asstring then self.oclastype(Paar).namea else self.oclastype(Paar).namea + ' & ' + self.oclastype(Paar).personB.name endif else if self.oclastype(Paar).namea.asstring = self.oclastype(Paar).nameb.asstring then self.oclastype(Paar).namea else self.oclastype(Paar).namea + ' & ' + self.oclastype(Paar).nameb endif endif endif endif else if self.oclistypeof(Kontakt) then if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.name else self.oclastype(Kontakt).name endif else name endif endif
- Vornamen von Paaren: Es werden beide Vornamen angezeigt, getrennt durch '&':
if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then self.oclastype(Paar).personA.vorname + ' & ' + self.oclastype(Paar).personB.vorname else if self.oclastype(Paar).personA->notempty then self.oclastype(Paar).personA.vorname + ' & ' + self.oclastype(Paar).vornameb else if self.oclastype(Paar).personB->notempty then self.oclastype(Paar).vornameA + ' & ' + self.oclastype(Paar).personB.vorname else self.oclastype(Paar).vornameA + ' & ' + self.oclastype(Paar).vornameb endif endif endif
- Nachnamen von Paaren: Es werden beide Namen angezeigt, getrennt durch '&':
-
if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).personB.name else if self.oclastype(Paar).personA->notempty then self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).nameb else if self.oclastype(Paar).personB->notempty then self.oclastype(Paar).nameA + ' & ' + self.oclastype(Paar).personB.name else self.oclastype(Paar).nameA + ' & ' + self.oclastype(Paar).nameb endif endif endif
- Geburtstage von (aktiven) Personen in den nächsten 30 Tagen:
person->select(aktiv)->select(geburtsdatum.asstring<>'')->select(((date<=encodedate(date.year,geburtsdatum.month,geburtsdatum.day))
and(date>=encodedate(date.year,geburtsdatum.month,geburtsdatum.day).incday(-30)))or((date<=encodedate(date.year+1,geburtsdatum.month,geburtsdatum.day))
and (date>=encodedate(date.year+1, geburtsdatum.month,geburtsdatum.day).incday(-30))))
- Geschlecht der Person: Die Expression funktioniert auf beliebigen Adresslisten und gibt im Falle einer Firma oder eines Paars einen Leerstring zurück.
if ocliskindof(Kontakt) then self->oclastype(Kontakt)->asset->collect(x| if x.person->size>0 then
if x.person.ismale then 'Male' else 'Female' endif else if x.ismale then 'Male' else 'Female' endif endif)->first
else if ocliskindof(Person) then if oclastype(Person).ismale then 'Male' else 'Female' endif else '' endif endif
OCL Expressions für Bearbeiter
- Alle Bearbeiter:
projektbearbeiter
- Alle aktiven Bearbeiter:
projektbearbeiter->select(aktiv)
- Angemeldeter (aktuell eingeloggter) Bearbeiter:
Timsession.allInstances->first.login
- Projektleiter eines oder mehrerer Projekte sind:
projektbearbeiter->select(eigprojekte->size>0)
- der Bearbeiterstufe "Secretary" zugeordnet sind:
projektbearbeiter->select(stufe.asstring='Secretary')
- keinen Eintrag im Feld "Kürzel" haben:
projektbearbeiter->select(kuerzel.asstring='')
- einen Eintrag im Feld "Kürzel" haben:
projektbearbeiter->select(kuerzel.asstring<>'')
- Alle Leistungen eines Bearbeiters während eines Jahres:
projektbearbeiter->groupleistungenb('01.01.2011', '31.12.2011','')
->collect(minutenintoffen + minutenintverrechnet)->sum
- Anteil der verrechenbaren Leistungen eines Bearbeiters während eines Jahres:
self->groupleistungenB('1.1.2011', '31.12.2011', '')
->collect(s | (s.minutenextOffen-s.minutenextOffenUnprod+s.minutenextVerrechnet-s.minutenextVerrechnetUnprod)
/ (s.minutenIntVerrechnet+s.minutenIntOffen) *100)->sum
OCL Expressions für Projekte / Phasen
- Alle Projekte:
projekt
oder Projekt.allInstances
(Gross-/Kleinschreibung beachten)
- Alle Projektphasen:
projektphase
oder Projektphase.allInstances
(Gross-/Kleinschreibung beachten)
- Alle Phasen und Subphasen eines Projekts: Ab Vertec 6.3. <projekt>
.allePhasen
- Projekt einer Phase oder Subphase: Ab Vertec 6.3. <projektphase>
.owningProjekt
- keine Projektphasen haben:
projekt->select(phasen->size=0)
- mindestens eine Projektphase haben:
projekt->select(phasen->size>0)
- einem produktiven Projekttypen zugeordnet sind:
projekt->select(typ.produktiv)
- in französischer Sprache geführt werden:
projekt->select(sprache.asstring='FR')
- aktiv sind:
projekt->select(aktiv)
- inaktiv sind:
projekt->select(not aktiv)
- Projekte mit doppelten Codes auflisten:
projekt->select(code->asset->collect(x|Projekt.allinstances->select(code=x)->size)->sum>1)
Als Ergebnis werden alle Projekte aufgelistet, deren Code doppelt vorkommt.
- Pauschalphasen sind:
projektphase->select(pauschal)
- nicht verrechenbar sind:
projektphase->select(not verrechenbar)
- Die Oberphase einer Projektphase:
parentphase
- Die erste Ebene der Subphasen einer Projektphase:
subphasen
- Alle Oberphasen einer Projektphase:
parentlist
Reihenfolge ist zuerst oberste Parentphase, zuletzt die unmittelbare Parentphase. Mit parentlist->first
kann also auf die oberste Ebene im Baum zugegriffen werden.
- Alle Subphasen einer Projektphase:
sublist
Durchläuft den ganzen Baum der Subphasen und beinhaltet auch die Subphasen der Subphasen.
- Datum offeriert:
offertDatum
- Datum erteilt:
erteiltDatum
- Datum abgeschlossen:
abschlussDatum
- Datum abgelehnt:
abgelehntDatum
Den einzelnen Status kann man über eine Nummer abfragen (bsp. phasen->select(status=1)
). Die Nummern der einzelnen Status lautet wie folgt:
0: Im Angebot
1: Erteilt
2: Abgeschlossen
3: Abgelehnt
Budgetwerte auf Projekten
- Aufwand geplant:
planMinutenInt
- Aufwand effektiv:
sumMinutenInt
- Honorar geplant:
planWertExt
- Honorar effektiv:
sumWertExt
- Honorar intern geplant:
planWertInt
- Honorar intern effektiv:
sumLeistungWertInt
- Kosten geplant:
planKostenLeistung
- Kosten effektiv:
sumLeistungWertKosten
- Betrag geplant:
planSpesenWert
- Betrag effektiv:
sumSpesenWert
- Kosten geplant:
planKostenSpesen
- Kosten effektiv:
sumKostenSpesen
- Betrag geplant:
planAuslagenWert
- Betrag effektiv:
sumAuslagenWert
- Kosten geplant:
planKostenAuslagen
- Kosten effektiv:
sumKostenAuslagen
Budgetwerte auf Projektphasen
- Aufwand geplant:
planMinutenInt
- Aufwand effektiv:
sumMinutenInt
- Honorar geplant:
planWertExt
- Honorar effektiv:
sumWertExt
- Honorar intern geplant:
planWertInt
- Honorar intern effektiv:
sumWertInt
- Kosten geplant:
planKostenLeistung
- Kosten effektiv:
sumKostenLeistung
- Betrag geplant:
planSpesenWert
- Betrag effektiv:
sumSpesenWert
- Kosten geplant:
planKostenSpesen
- Kosten effektiv:
sumKostenSpesen
- Betrag geplant:
planAuslagenWert
- Betrag effektiv:
sumAuslagenWert
- Kosten geplant:
planKostenAuslagen
- Kosten effektiv:
sumKostenAuslagen
Werte auf Phasenzuordnungen
Auf Phasenzuordnungen sind ausser der oben gelisteten Budgetwerte zusätzlich folgende Werte verfügbar:
Bearbeiter-Zuordnung | - aktiv
- ansatzBearbeiter
- ansatzExt
- ansatzKosten
- tagespauschaleExt
|
Tätigkeitszuordnung | - aktiv
- bearbeiter
- startDatum
- endDatum
- ansatzExt
- ansatzKosten
- ansatzBearbeiter
- tagespauschaleExt
- stueckwert
- name (nur über OCL)
- offertText
- bezeichnung
|
Spesentyp-Zuordnung | - bearbeiter
- wertProEinheitInt
- wertProEinheitExt
- wertProEinheitKosten
- name (nur über OCL)
- offertText
- bezeichnung
|
Auslagentyp-Zuordnung | - bearbeiter
- wertProEinheitInt
- wertProEinheitExt
- wertProEinheitKosten
- name (nur über OCL)
- offertText
- bezeichnung
|
OCL Expressions für Rechnungen
Zugriff auf Buchungszeile der Rechnung und Buchungen auswerten
- Buchungszeile aufrufen:
buchungsbeleg->oclAsType(Beleg).buchungen
Von hier aus kann mann nun auf die verschiedenen Werte zugreifen wie z.B.die
- Nettobeträge der Haben Buchungen einer Rechnung:
buchungsbeleg->oclastype(Beleg).buchungen->select(isthaben).betrag->sum
Vorschüsse auf Rechnungen
- Welche Vorschüsse werden mit welchen Beträgen auf der Rechnung in Abzug gebracht:
rechnungvorschusslink->select(betragnetto<>0)->collect
(vorschuesse.bezeichnung + ': ' + betragnetto.asstring)->listtostring(' / ')
Zeigt die Bezeichnung der Vorschüsse und den jeweiligen Betrag an, z.B. in einer Listenspalte.
- Vorschüsse, die auf der Rechnung verrechnet werden:
vorschuesseAufRechnung
- Vorschüsse, die auf der Rechnung in Abzug gebracht werden:
vorschuesse
OCL Expressions für Rechnungsberichte
Wie Sie Word-Berichte aufbauen, finden Sie im Artikel Word-Berichte. Was die einzelnen Felder auf der Rechnung bedeuten, finden Sie im Artikel Die Rechnung in OCL.
Expressions, die eine Bedingung abfragen, also JA oder NEIN zurückgeben. Normalerweise Band Expressions für 'Cond'-Bands (siehe Artikel Word-Berichte).
- Hat Rechnungsperiode:
von.asstring <> '' or bis.asstring <> ''
- Hat Leistungen (und ist keine Pauschalrechnung):
(not pauschal) and (leistwertext <> 0)
- Hat Rabatt:
rabatt
- Rabatt ist als Betrag:
rabattBetrag > 0
- Rabatt ist in Prozent:
rabattProzent > 0
- Hat MWST auf Leistungen:
leistmwst > 0
- Hat Spesenpauschale:
pauschalspesen
- Spesenpauschale als Betrag:
pauschalspesenbetrag > 0
- Spesenpauschale in Prozent:
pauschalspesenprozent > 0
- Speseneinträge?:
usespesen
- Hat Spesen:
spesenext > 0
- Es hat Spesen und sie sollen verwendet werden:
(spesenext > 0) and usespesen
- Hat MWST auf Spesen:
spesenmwst > 0
- Hat Auslagen:
auslagenext > 0
- Hat MWST auf Auslagen:
auslagenmwst > 0
- Hat Spesen oder Auslagen:
((spesenext > 0) and usespesen) or (auslagenext > 0)
- Hat zu verrechnende Vorschüsse:
vorschussbetrag > 0
- Hat geleistete Vorschüsse:
vorschusseffektiv > 0
- Geleistete Vorschüsse ist inkl. MWST:
vorschusseffektivmwst > 0
- MWSTBetrag geleistete Vorschüsse:
vorschusseffektivmwst
- Leistungen nach Ansatz:
leistungen->orderby(boldid)->select(x|x.boldid=self.leistungen
->orderby(boldid)->select(ansatzext=x.ansatzext)->first.boldid)
Technisch gesehen macht die Expression eine Liste von Leistungen, bei der jede einzelne einen anderen Ansatz hat.
Innerhalb eines solchen Bands kann man die Leistungen dann filtern, z.B. mit:
leistungen->select(bndAnsatz.ansatz=ansatz).wertext->sum
- Leistungen nach Taetigkeit UND Ansatz:
leistungen->orderby(boldid)->select(x|x.boldid=self.leistungen
->orderby(boldid)->select((ansatzext=x.ansatzext) and (typ=x.typ))
->first.boldid)
Filtern mit:
leistungen->select(bndTaetigkeit.typ=typ)
->select(bndTaetigkeit.ansatz=ansatz).wertext->sum
OCL Expressions für Vorschüsse
- Auf welchen Rechnungen wird wieviel des Vorschusses abgezogen:
rechnungvorschusslink->select(betragnetto<>0)->collect
(rechnungen.nummer.asstring + ': ' + betrag.asstring)->listtostring(' / ')
Zeigt die Rechnungsnummer und den jeweiligen Betrag, zum Beispiel in einer Listenspalte.
OCL Expressions mit Datumsoperatoren
Informationen zu den OCL Datumsoperatoren finden Sie hier.
- Heutiges Datum (inkl. Zeit):
now
- Heutiges Datum (ohne Zeitteil):
date
Kalenderwoche eines Datums
Beispiele: Berechnung eines Startdatums
OCL-Expressions, welche für eine beliebige Kalenderwoche (eines beliebigen Jahres) das Startdatum (Datum vom Montag dieser Woche) berechnen:
- Für das aktuelle Jahr:
date.firstOfYear.incDay(3).mondayOfWeek.incDay(7*(kw-1))
- Für die 12. Kalenderwoche:
date.firstOfYear.incDay(3).mondayOfWeek.incDay(7*(12-1))
- Für ein beliebiges Jahr:
encodeDate(jahr, 1, 4).mondayOfWeek.incDay(7*(kw-1))
- Für die 12. Kalenderwoche des Jahres 2026:
encodeDate(2026, 1, 4).mondayOfWeek.incDay(7*(12-1))
Formatierungen von Datums- und Zeitwerten
formatdatetime: Zur Formatierung von Datums- und Zeitwerten kann der Operator formatdatetime
verwendet werden. Diese Abfrage z.B. stellt die aktuelle Zeit dar, im Format Stunden.Minuten: now.formatdatetime('hh.mm')
. Alle Informationen zu formatdatetime
finden Sie im Artikel OCL.
encodedate: Für Datumsabfragen wird der Operator encodeDate
verwendet. Beispiel: Ordner mit allen Rechnungen, die im Jahr 2018 erstellt wurden: rechnung->select(datum >= encodeDate(2018,01,01))
. Alle Informationen zu encodeDate
finden Sie im Artikel OCL.
- Nicht bezahlte Rechnungen, die älter sind als dreissig Tage:
rechnung->select(not bezahlt)->select(faelligdatum<=date.incday(-30))
- Wer (Personenadressen) hat in den nächsten dreissig Tagen Geburtstag:
person->select(aktiv)->select(geburtsdatum.asstring<>'')->select( ((date<=encodedate(date.year,geburtsdatum.month,geburtsdatum.day))
and(date>=encodedate(date.year,geburtsdatum.month,geburtsdatum.day) .incday(-30)))or((date<=encodedate(date.year+1,geburtsdatum.month, geburtsdatum.day))
and (date>=encodedate(date.year+1, geburtsdatum.month,geburtsdatum.day).incday(-30))))
- In den letzten 360 Tagen erfasste Adressen (z.B. für Weihnachtskartencheck):
adresseintrag->select(creationDateTime >= date.incDay(-360))