Zum Hauptinhalt springen

STAR-Programmiersprache

Heute aktualisiert

Übersicht

STAR ist die integrierte Skriptsprache von Scopevisio Documents. Sie verwenden STAR beispielsweise in Formular-Events.

Wichtige Grundregeln:

  • STAR ist dynamisch typisiert und verwendet Python-Typen.

  • Anweisungen werden durch ein Zeilenende oder ein Semikolon (;) getrennt.

  • Einrückungen sind nicht signifikant.

  • Schlüsselwörter (z. B. if, null) sind nicht case-sensitiv.

  • Kommentare beginnen mit # und enden am Zeilenende.


Unterstützte Datentypen

STAR unterstützt folgende Python-Typen:

Typ

Beschreibung

String

Text in einfachen oder doppelten Anführungszeichen

Ganzzahl

Ganze Zahlen

Dezimalzahl

Zahlen mit Nachkommastellen

Boolean

true oder false

null

Leerer Wert

String-Beispiele:

python

a = 'single'
b = "double"

Arithmetische Operatoren

Die folgenden Operatoren stehen Ihnen zur Verfügung:

Operator

Bedeutung

+

Addition

-

Subtraktion

*

Multiplikation

/

Division

%

Modulo

//

Integer-Division

Beispiele:

python

a = (b + 4) * 3
b = 1 + 2 + 3
c = 10 + datepart("year", today())

Index-Operator

Mit dem Index-Operator extrahieren Sie ein Element oder einen Teilbereich (Slice) aus einem String oder einer Sammlung.

Syntax

Beschreibung

collection[0]

Gibt das erste Element zurück

collection[start:stop]

Gibt Elemente von start bis exklusive stop zurück

collection[:stop]

Entspricht collection[0:stop]

collection[start:]

Gibt alle Elemente von start bis zum Ende zurück

collection[:]

Gibt die gesamte Sammlung zurück

Hinweis für Strings:

  • str[index] → gibt das Zeichen an Position index zurück.

  • str[start:stop] → gibt den Teilstring von start bis stop-1 zurück.


Ausdrücke und Vergleichsoperatoren

Ein Ausdruck wird ausgewertet und liefert einen Wert zurück – zum Beispiel als Ergebnis eines Vergleichs.

Verfügbare Vergleichsoperatoren:

Operator

Bedeutung

==

Gleich

!=

Ungleich

<

Kleiner als

<=

Kleiner oder gleich

>

Größer als

>=

Größer oder gleich

Logische Verknüpfungen:

Mehrere Ausdrücke kombinieren Sie mit and, or und not.

Der in-Operator prüft, ob ein Wert in einem anderen enthalten ist.

Beispiele:

python

a < 5 and not (b == 1 or c > 10)
'ab' in 'abc' # true
'ac' in 'abc' # false
'Vorgesetzte' in current.user.groups_names # Ist der Nutzer Teil dieser Gruppe?

Operatorrangfolge

Die folgende Tabelle zeigt die Rangfolge von niedrigster zu höchster Priorität:

Priorität

Operator

1 (niedrigste)

or

2

and

3

not x

4

== != < <= > >=

5

+ -

6 (höchste)

* / % //

Tipp: Verwenden Sie Klammern, um die Standardrangfolge gezielt zu überschreiben.


Variablen

Benennung

Variablennamen müssen mit einem Buchstaben beginnen. Danach sind Buchstaben, Ziffern und Unterstriche erlaubt.

python

a = 100
b1 = "String"
c_2 = false

Wichtig: Sie können eine Variable erst verwenden, nachdem Sie ihr einen Wert zugewiesen haben.

Spezielle Präfix-Variablen (_)

In Formular-Events gibt es Variablen mit dem Präfix _. Diese enthalten die Werte eines Vorgangs.

  • _rechnr enthält den Wert des Datenfeldes mit dem Kurznamen rechnr.

  • Eine Zuweisung an diese Variable ändert den Wert des entsprechenden Datenfeldes direkt.


Verzweigungen (if / elseif / else)

Sie können beliebig viele elseif-Blöcke und optional einen else-Block verwenden. Schließen Sie jede Verzweigung mit end ab.

python

if a > 0 then
b = 1
elseif a < 0 then
b = -1
else
b = 0
end

Evaluierung von Variablen

STAR wertet Variablenwerte – wie Python – explizit zu true oder false aus. Das ermöglicht vereinfachte Abfragebedingungen und macht den Code lesbarer.

Strings

python

text = "Buchungstext"

# Strenge Abfrage: Text ist weder "" noch null
if text != "" and text != null then
# Logik
end

# Vereinfachte Abfrage – deckt beide Fälle ab
if text then
# Logik
end

Zahlenwerte – Prüfung auf null oder 0

null und 0 werden beide zu false evaluiert.

python

# Implizit: Prüfung auf null oder 0
if (_betragsteuer_reg or 0) == 0 then
_betragsteuer_reg = 1000
end

# Explizit: Vereinfachte Prüfung
if not _betragsteuer_reg then
_betragsteuer_reg = 1000
end

Mehrere Felder prüfen

Beide Felder sind befüllt (weder null noch ""):

python

if _kreditorname and _rechnungsnummer then
# Logik
end

Rechnungsdatum vorhanden, Leistungsdatum fehlt:

python

if _rechdat and not _leistdat then
_leistdat = date(<year>, <month>, <day>)
end

Schleifen (for)

Mit einer for-Schleife iterieren Sie über Objekte, die eine Iteration unterstützen.

python

for idx in _subtable.enumerate() do
row_field = _subtable.get(idx, 'field_name')
if row_field == 'secret' then
continue # Überspringt den Rest – weiter mit dem nächsten Index
elseif row_field == 'stop' then
break # Beendet die Schleife vollständig
end
print(row_field)
end

Schlüsselwörter in Schleifen:

Schlüsselwort

Verhalten

continue

Überspringt den restlichen Code und fährt mit dem nächsten Index fort

break

Bricht die Schleife vollständig ab


Funktionen

Sie definieren eigene Funktionen mit dem Schlüsselwort function. Parameter können Standardwerte haben. Schließen Sie die Funktion mit end ab.

python

function add_mul(a, b, c=1)
return (a + b) * c
end

Hinweise:

  • c=1 ist ein optionaler Parameter mit dem Standardwert 1.

  • Mit return geben Sie den Rückgabewert der Funktion zurück.


Abbruch und Rückgabe

return – Skript an einer bestimmten Stelle beenden

Mit return beenden Sie die Ausführung des Skripts an einer bestimmten Zeile, ohne weitere Änderungen rückgängig zu machen.

python

betrag = lookup("test_tabelle", "netto_betrag", fallback=null, _name="Mitarbeiter X")

if betrag > 1000 then
print("Ende der Logik")
return
end

print("Fortführende Logik")

abort() – Skript abbrechen und Änderungen rückgängig machen

Mit abort() brechen Sie das Skript sofort ab. Alle vorher durchgeführten Änderungen (z. B. Feldwert-Zuweisungen) werden rückgängig gemacht.

python

name = lookup("firmen", "firma", fallback=null, _name="Meine Firma")

if not name then
abort("Firma konnte nicht gefunden werden.")
else
print("Führe Logik aus")
end

Hinweis: Der optionale Parameter message wird als Fehlertext angezeigt, wenn die Meldung geworfen wird.


Verfügbare Funktionen

Steuerung

Funktion

Beschreibung

abort(message)

Bricht das Skript sofort ab und macht alle Änderungen rückgängig

return

Beendet die Ausführung an der aktuellen Stelle

print(value)

Gibt den aktuellen Wert von value aus

user_message(text)

Sendet nach dem Event eine Info-Nachricht an den Benutzer

Typkonvertierung

Funktion

Beschreibung

int(value)

Konvertiert value in einen Integer

str(value)

Konvertiert value in einen String

decimal(value)

Konvertiert einen String in eine Dezimalzahl. Punkt und Komma werden als Trennzeichen erkannt. Endet der String mit %, wird der Wert automatisch durch 100 geteilt

Mathematik

Funktion

Beschreibung

round(n) / round(n, d)

Rundet n. Mit d geben Sie die Anzahl der Nachkommastellen an

len(collection)

Gibt die Länge einer Liste oder eines Strings zurück

Objekte und Attribute

Funktion

Beschreibung

getattr(object, "attribute_name", default=null)

Liest ein Attribut eines Objekts aus. Gibt default zurück, wenn das Attribut nicht existiert oder das Objekt null ist

is_table(object)

Prüft, ob ein Objekt eine Tabelle ist

not_null(value_one, value_two, ..., value_n)

Gibt false zurück, sobald ein null-Wert gefunden wird. Gibt true zurück, wenn kein Wert null ist

Datum und Zeit

Funktion

Beschreibung

date(year, month, day)

Erstellt ein Datumsobjekt

today()

Gibt das heutige Datum zurück

datepart(part, d)

Extrahiert einen Teil aus einem Datum. Gültige Werte für part: "year", "quarter", "month", "day", "weekday", "isoweekday"

timedelta(num, unit="days")

Berechnet eine Zeitdifferenz. Gültige Werte für unit: "day", "second", "minute", "hour", "week"

relativedelta(date_1, date_2)

Berechnet eine relative Zeitdifferenz zwischen zwei Datumsangaben

weekday(dow, days=0)

Gibt ein weekday-Objekt für relativedelta zurück. Gültige Werte: "MO", "TU", "WE", "TH", "FR", "SA", "SU"

Hinweis zu datepart und Wochentagen:

  • "weekday": Montag = 0, Sonntag = 6

  • "isoweekday": Montag = 1, Sonntag = 7


String-Methoden

Methode

Beschreibung

.startswith(prefix)

Prüft, ob der String mit prefix beginnt

.endswith(suffix)

Prüft, ob der String mit suffix endet

.removeprefix(prefix)

Entfernt prefix vom Anfang des Strings

.removesuffix(suffix)

Entfernt suffix vom Ende des Strings

.isalnum()

true, wenn alle Zeichen alphanumerisch sind

.isalpha()

true, wenn alle Zeichen alphabetisch sind

.isdigit()

true, wenn alle Zeichen Ziffern sind

.lower()

Gibt den String in Kleinbuchstaben zurück

.upper()

Gibt den String in Großbuchstaben zurück

.strip()

Entfernt Whitespace (Leerzeichen, Tabs) am Anfang und Ende

.find(sub)

Gibt den Index des ersten Vorkommens von sub zurück

.replace(old, new)

Ersetzt alle Vorkommen von old durch new


Datumsobjekte

timedelta – Zeitdifferenz in Tagen und Sekunden

Ein timedelta-Objekt entsteht entweder durch die Funktion timedelta() oder durch arithmetische Operationen mit date-Objekten. Es besitzt die Attribute .days und .seconds.

pyhton

date_1 = date(2020, 2, 3)
date_2 = date(2021, 10, 5)
time_delta = date_2 - date_1
print(time_delta.days) # Ausgabe: 610
print(time_delta.seconds) # Ausgabe: 0

python

time_delta = timedelta(15, unit="days")
date_1 = date(2020, 2, 3)
date_2 = time_delta + date_1
print(date_2.days) # Ausgabe: 18

relativedelta – Relative Zeitdifferenz

Ein relativedelta-Objekt berechnen Sie mit relativedelta(date_1, date_2). Verfügbare Attribute: .years, .weeks, .days, .hours, .minutes, .seconds, .microseconds.

python

date_1 = date(2020, 2, 3)
date_2 = date(2021, 10, 5)
relative_delta = relativedelta(date_2, date_1)
print(relative_delta.years) # Ausgabe: 1
print(relative_delta.months) # Ausgabe: 8
print(relative_delta.days) # Ausgabe: 2

⚠️ Wichtiger Hinweis: .months gibt nicht die Gesamtdifferenz in Monaten zurück (hier wären das 20), sondern nur die Differenz der Monatsattribute beider Datumsobjekte. Um die Gesamtdifferenz in Monaten zu erhalten, müssen Sie die Jahresdifferenz in Monate umrechnen und addieren. Dasselbe gilt für .days.

Letzten Wochentag berechnen – Beispiel

python

# Berechnung des letzten Freitags
today() + relativedelta(weekday=weekday("FR", -1))


Globale Variablen

Schreibgeschützte globale Variablen

current_user

Enthält den aktuell angemeldeten Benutzer als Benutzer-Objekt.

Hinweis: Ist null, wenn kein Benutzer angemeldet ist – z. B. bei der Ausführung einer Hintergrundverarbeitung.


current_record

Stellt Informationen über den aktuellen Vorgang bereit. Diese Daten sind nur lesbar – Sie können sie nicht durch Zuweisung ändern.

Verfügbarkeit: In den Events on_save, on_load sowie während Workflow-Transitionen.

Attribut

Beschreibung

current_record.id

ID des Vorgangs

current_record.creation_date

Erstellungsdatum

current_record.modification_date

Änderungsdatum

current_record.creator_id

ID des Erstellers

current_record.expiration_date

Ablaufdatum

current_record.deletion_date

Löschdatum

current_record.release_id

Freigabe-ID

current_record.release_version

Freigabe-Version

current_record.release_date

Freigabedatum

current_record.status

Status des Vorgangs

current_record.postbox_users

Postfach-Benutzer

current_record.postbox_groups

Postfach-Gruppen

current_record.hidden

Gibt an, ob der Vorgang ausgeblendet ist


event

Enthält Basisinformationen über das aktuell ausgeführte Event.

Attribut

Beschreibung

event.field

Kurzname (mit vorangestelltem _) des Datenfeldes, in dem das Event ausgelöst wurde. Bei Formular-Events ist der Wert null.

event.row

Zeilennummer der Tabellenzelle, in der das Event ausgelöst wurde (beginnt bei 0). Nur bei Events einer Untertabelle verfügbar.

event.column

Kurzname der Spalte, in der das Event ausgelöst wurde. Nur bei Events einer Untertabelle verfügbar.


Veränderbare Vorgangs-Variablen

Diese Variablen können Sie per Zuweisung ändern, um Eigenschaften des Vorgangs zu bearbeiten.

Variable

Beschreibung

$expiration_date

Das Ablaufdatum des Vorgangs

$deletion_date

Das Löschdatum des Vorgangs


Mandanten-Variable ($client)

Wenn in einem Archiv die Mandanten aktiviert sind, enthält die Variable $client den aktuell ausgewählten Mandanten des Vorgangs.

Sie greifen über Attribute auf die Eigenschaften des Mandanten zu:

Attribut

Beschreibung

$client.identifier

Kürzel des Mandanten

$client.name

Name des Mandanten

$client.id

Interne ID des Mandanten


Benutzer-Objekte

Ein Benutzer-Objekt repräsentiert einen Benutzer im System. Sie erhalten Benutzer-Objekte z. B. über die globale Variable current_user oder als Rückgabewert von lookup_user().

Attribute eines Benutzer-Objekts

Attribut

Beschreibung

id

Interne Benutzer-ID

username

Login-Name

fullname

Vollständiger Name

email

E-Mail-Adresse

language

Oberflächensprache des Benutzers (de oder en)

groups

Liste der Gruppen-IDs, in denen der Benutzer Mitglied ist

groups_names

Liste der Gruppen-Namen, in denen der Benutzer Mitglied ist

roles

Liste der Rollen-IDs, in denen der Benutzer Mitglied ist

roles_names

Liste der Rollen-Namen, in denen der Benutzer Mitglied ist

substitute_id

Benutzer-ID des Vertreters – null, wenn kein Vertreter eingestellt ist

substitute_active

true, wenn ein Vertreter aktiv ist, sonst false

Beispiel:

python

# Prüft, ob der aktuell angemeldete Benutzer Mitglied der Rolle "Prüfer" ist
print("Prüfer" in current_user.roles_names)


Status-Änderung im on_save-Event

Im on_save-Event stehen zusätzliche Variablen zur Verfügung.

Standard-Variablen

Variable

Beschreibung

$status

Enthält den aktuellen Statusnamen des Vorgangs. Durch Zuweisung eines gültigen Statusnamens ändern Sie den Status.

$new

true, wenn das Event für einen neu angelegten Vorgang ausgeführt wird

$update

true, wenn das Event für einen bestehenden Vorgang ausgeführt wird

Service-gesteuerte Variablen

Variable

Beschreibung

$importservice

true, wenn das Event durch den Importservice ausgelöst wird, sonst false

$tags

Liste von Zeichenfolgen, die von einem API-Client oder Importservice übermittelt wurde


Sichtbarkeit von Datenfeldern ändern

Über Events können Sie Datenfelder im Formular steuern:

Zuweisung

Beschreibung

_feld1.visible = false

Blendet das Datenfeld aus

_feld2.editable = false

Setzt das Datenfeld auf Read-Only

_feld2.label = 'Neues Label'

Ändert das Label des Datenfeldes


Anzeige-Text eines Datenfeldes abfragen (.text)

Bei Key-Value-Feldern (z. B. Benutzer-Vorschlag oder verlinkter Vorgang) können Sie den Anzeige-Text über das Attribut .text abfragen.

Aufruf

Rückgabewert

_user oder _user.value

Die intern gespeicherte ID (z. B. Benutzer-ID)

_user.text

Der Anzeige-Text (z. B. der Name des Benutzers)

Beispiel:

python

if _user.text == current_user.fullname then
_user_refer = "You"
else
_user_refer = _user.text
end

Untertabellen

Wenn in einem Archiv Untertabellen konfiguriert sind, stehen Ihnen folgende Funktionen und Attribute zur Verfügung. Im folgenden Beispiel hat die Untertabelle den Kurznamen table.

Attribute

Attribut

Beschreibung

_table.row_count

Enthält die aktuelle Anzahl der Tabellenzeilen

Funktionen

Funktion

Beschreibung

_table.clear()

Leert die gesamte Tabelle

_table.enumerate()

Gibt einen Iterator für alle Zeilenindizes zurück – verwendbar in einer for-Schleife

_table.extend(other, strict=false)

Fügt Zeilen aus other hinzu. Mit strict=true wird ein Fehler ausgelöst, wenn die Tabellenschemata nicht übereinstimmen

_table.get(0, "ort")

Gibt den Wert aus Zeile 0, Spalte "ort" zurück. Gibt null zurück, wenn die Zeile nicht existiert

_table.set(0, "ort", "Berlin")

Schreibt einen Wert in Zeile 0, Spalte "ort"

_table.set_row(0, clear=true, _ort="Berlin", _plz=11011)

Setzt mehrere Spaltenwerte auf einmal. Mit clear=true werden alle nicht explizit gesetzten Werte auf null zurückgesetzt

_table.add_row()

Fügt eine neue Zeile ein und gibt deren Index zurück

_table.delete_row(idx)

Entfernt die Zeile am Index idx

_table.sum("betrag")

Berechnet die Summe aller Zahlenwerte in der Spalte "betrag". Gibt null zurück, wenn die Spalte nicht existiert oder keine Zahlenwerte enthält

Hinweis: Zeilenindizes beginnen bei 0 – die erste Zeile hat also den Index 0.


lookup() – Suche in Datentabellen und Archiven

Mit lookup() suchen Sie nach Werten in Datentabellen oder Archiven. Die Funktion gibt das erste gefundene Ergebnis zurück.

Erstes Argument – Quelle auswählen

Wert

Beschreibung

"zahlungsbedingungen"

Durchsucht die Datentabelle mit dem Kurznamen zahlungsbedingungen

"datatable:zahlungsbedingungen"

Identisch – explizites Präfix für Datentabellen

"archive:rechnungen"

Durchsucht das Archiv mit dem Kurznamen rechnungen

Zweites Argument – Rückgabefeld

Geben Sie den Kurznamen der Spalte an, deren Wert Sie ermitteln möchten.

Für interne Felder eines Vorgangs verwenden Sie das Präfix record::

Rückgabewert

Beschreibung

record:id

Interne ID des Vorgangs

record:release_id

Release-ID (stabil über alle Versionen)

record:release_version

Release-Version

record:client_identifier

Kürzel des Mandanten

record:client_name

Name des Mandanten

record:client_id

Interne ID des Mandanten

Keyword-Argumente

Parameter

Beschreibung

_kurzname=wert

Filtert nach dem Kurznamen einer Spalte

filter="..."

Komplexer Filter als String in der üblichen Filter-Syntax

wildcard=true

Ermöglicht Wildcard-Suche, z. B. "F*"

fallback=x

Gibt x zurück, wenn kein Treffer gefunden wurde

client=$client

Filtert nach Mandanten (erforderlich bei Archiv-Lookups mit Mandanten)

record_id

Filtert nach interner Vorgangs-ID

record_release_id

Filtert nach Release-ID

record_release_version

Filtert nach Release-Version

Beispiele

python

# Suche in einer Datentabelle mit Fallback
a = lookup("zahlungsbedingungen", "nettotage", fallback=10, _name="Firma")

# Wildcard-Suche in einem Archiv
b = lookup("archive:kunden", "strasse", wildcard=true, _name="F*", _plz=54321)

# Vorgang im Archiv finden und als Filterkriterium weiterverwenden
rechnr = 1200001
test_lookup = lookup("archive:test", "informationen", _rechnr=rechnr)
referred_lookup = lookup("archive:test_referred", "anbieter", record_release_id=test_lookup)

# Interne Felder zurückgeben
lookup("archive:test", "record:id", record_release_id=lookup_release_id)
lookup("archive:test", "record:client_identifier", record_id=lookup_record_id, client=$client)

Hinweis: Ist das gesuchte Feld eine Untertabelle, gibt lookup() ein Tabellen-Objekt zurück.


lookup_table() – Alle Treffer als Tabelle zurückgeben

lookup_table() funktioniert wie lookup(), gibt aber alle gefundenen Zeilen als Tabellen-Objekt zurück. Das zweite Argument (Feldname) entfällt.

python

a = lookup_table("archive:kunden", _name="F*")

format_filter() – Filter dynamisch erzeugen

Mit format_filter() erzeugen Sie den filter-Parameter für lookup() sicher aus Variablen.

  • Strings erhalten automatisch doppelte Anführungszeichen – enthaltene Anführungszeichen werden escaped.

  • Datumswerte werden automatisch in das ISO-Format konvertiert.

python

plz = 54321
name = 'Firma "Test"'
f = format_filter("_plz = {p} AND _name = {n} AND _date > {d}", p=plz, n=name, d=today())
```

**Erzeugt folgenden Filter-String:**
```
_plz = 54321 AND _name = "Firma \"Test\"" AND _date > "2022-06-02"

lookup_user() – Benutzer suchen

Mit lookup_user() suchen Sie nach einem Benutzer anhand eines Filterkriteriums. Die Funktion gibt ein Benutzer-Objekt oder null zurück.

Filteroptionen

Parameter

Beschreibung

user_username

Suche nach Login-Name

user_fullname

Suche nach vollständigem Namen

user_email

Suche nach E-Mail-Adresse

user_id

Suche nach Benutzer-ID

python

# Attribut substitute_active auslesen – gibt false zurück, wenn Benutzer nicht gefunden
active = getattr(lookup_user(user_id=_freigeber), "substitute_active", false)

Termine anlegen, bearbeiten und löschen

Die folgenden Funktionen stehen im on_save-Event zur Verfügung.

create_schedule() – Termin anlegen

python

create_schedule(
start_date,
escalation_rule=null,
todo=null,
recipient1=null,
recipient2=null,
recipient3=null,
repeat_unit=null,
repeat_count=null,
from_user=null,
inactive=false
)

Parameter

Pflicht

Beschreibung

start_date

✅ Ja

Startdatum des Termins. Muss als start_date= übergeben werden.

escalation_rule

Nein

Name der Eskalations-Regel. Ohne Angabe wird die Standard-Regel verwendet.

recipient1/2/3

Nein

Empfänger als Benutzer-Objekt (z. B. current_user oder Ergebnis von lookup_user())

repeat_unit

Nein

Wiederholungsintervall: "day", "week", "month" oder "year"

repeat_count

Nein

Anzahl der Wiederholungen. Erfordert auch repeat_unit.

from_user

Nein

Absender des Termins

inactive

Nein

false (Standard). Mit true wird ein deaktivierter Termin angelegt.

Rückgabewert: Das neu erstellte Termin-Objekt.

python

# Termin eine Woche ab heute anlegen
create_schedule(start_date=today() + timedelta(1, "week"))

lookup_schedules() – Termine laden und bearbeiten

python

lookup_schedules(todo=null, wildcard=false)

Parameter

Beschreibung

todo

Optional. Filtert nach der Beschreibung des Termins.

wildcard

Optional. false (Standard). Ermöglicht Wildcard-Suche für todo.

Termin-Attribute bearbeiten:

python

schedule.start_date = _date + timedelta(1, "week")
schedule.todo = "Invoice checking postponed"

delete_schedule() – Termin löschen

python

delete_schedule(schedule)

Übergibt das Termin-Objekt, das gelöscht werden soll.

Hat dies deine Frage beantwortet?