Skript

Konfiguration Skripting

Skripting

Schlüsselname

Eingabe

Bedeutung

Serverskript Zykluszeit

Standardwert: 500

Skript-Zykluszeit in Millisekunden

Clientkript Zykluszeit

Standardwert: 200

Skript-Zykluszeit in Millisekunden

Anzahl fehlerhafter Skriptdurchläufe

Standartwert: 10

Hiermit wird die Anzahl fest- gelegt, wie oft das Skript durch- laufen wird mit harten Fehlern.

Strukturen beim Zuweisen kopieren

Standardwert: ja

Gibt an, ob Strukturen beim Zuweisen kopiert werden sollen

Prozessvariablen nach jedem Skriptablauf freigeben

Standardwert: nein

Nach der Abarbeitung eines Skripts werden die registrierten Prozess- variablen wieder freigegeben

Prozessvariablen der Daten- verwaltung immer freigeben

Standardwert: nein

Nach einem Datenverwaltungs-Funk- tionsaufruf werden die registrier- ten Prozessvariablen wieder freigeben

Aufgaben des PlugIn Skripts

PROCON-WEB erlaubt das Bearbeiten von Skripten parallel zur laufenden Visualisierung. Diese Formeln stellen keinen Steuerungsersatz dar, sondern decken vorwiegend folgende Aufgaben ab:

  • Unterstützung der Visualisierung durch Aufbereiten von Prozessdaten (z. B. Erzeugen von zusammengefassten Zustandsinformationen)

  • Ergänzungsgesteuertes Abarbeiten von komplexen Funktionen (z. B. Datenerfassung, Alarme, Bildwechsel, Berechnungen)

  • Simulation von Abläufen durch Verändern interner Größen

  • Plausibilitätsprüfungen über mehrere abhängige Sollwert|

  • Zeitgesteuertes Bearbeiten von Funktionen

  • Aufruf eigener Hochsprachenprogramme

Mit Release 6.9 wird zwischen Server- und Clientskripten unterschieden. Wie der Name schon erkennen lässt, können nun auch Skripte direkt auf einem Client ausgeführt werden. Sie laufen in einem WebWorker und sind somit von der eigenlichen WebRuntime gekapselt. Im Gegensatz zu Serverskripten, sind Clientskripte in TypeScript geschrieben.

Clientskripting

Allgemein

  • Die Skripte werden im TypeScript ES6 Module geschrieben.

  • In den Skripten kann wie bei DynamicExpressions auf Tags zugegriffen werden.

  • Es kann direkt auf den Variablenwert geschrieben werden.

  • Funktionen müssen immer dann exportiert werden, wenn man diese außerhalb des eigentlichen Skripts nutzt. (z.B. Einbindung in eine andere Skript-Datei, Zuweisung einer Skriptfunktion auf einen Button, oder das Anhängen eines zyklischen Bildskripts)

  • Zugelassene Typen bei den Übergabeparametern einer zu exportierenden Funktion sind ausschließlich number, string oder boolean.

  • Union Typen und Überladungen sind erlaubt. Diese werden dann einzeln auswählbar aufgelöst.

  • Der Aufruf von browserspezifischen APIs (z.B. fetch, setTimeout) sowie die Manipulation von DOM-Elementen mittels Cientskripting ist nicht gestattet.

  • Import von anderen Skripten ist mittels relativen Pfades möglich

Erstellen eines Client-Skriptes

Über das Kontextmenü das im Projektbaum mithilfe der rechten Maustaste aufgerufen wird, wird ein neues Clientkript angelegt.

Im Folgenden werden nun einige Hinweise zur Erstellung eines Clientskriptes gegeben. Da es jedoch eine standardisierte Sprache ist, empfiehlt es sich, weitere Informationen oder Codeteile mithilfe einer Internetrecherche zu erstellen.

Erstellen einer Funktion

Um eine Funktion zu erstellen können wir dies mit folgender Syntax tun:

function nameDerFunktion(par1,par2,…) { //code } Wichtig: Möchte man diese Funktion außerhalb des Skripts einsetzen (z.B. Zuweisung auf einen Button), dann muss das keyword export ergänzt werden.

export function nameDerFunktion(par1,par2,…) { //code

Erstellen von Variablen

Die Besonderheit an TypeScript ist, dass man nicht zwingend einen Datentyp zuweisen muss. Das macht Typescript von alleine. Möchte man innerhalb eines Skriptes Variablen oder Konstanten deklarieren, kann man dies mit folgender Syntax tun:

Erstellung innerhalb einer Funktion (lokal):

export function myFunction() {

//Deklaration von Konstanten const VARIABLESTRING : string = „Das ist String“; const VARIABLENUM : number = 123; const VARIABLEBOOL : boolean = true;

//Deklaration von Variablen let variableString : string = „Das ist String“; let variableNum : number = 123; let variableBool : boolean = true;

} Erstellung außerhalb einer Funktion (global):

Gloabale Funktion

Erstellen von Variablen

Einzeiliger Kommentar mit: // Mehrzeiliger Kommentar mit: /* */

Bereich kommentieren: Markierung des Bereichs und anschließend: SHIFT + ALT + A

export function myFunction() {

//Das ist ein einzeiliger Kommentar

/Das ist ein Mehrzeiliger Kommentar/

Zuweisung der Skriptfunktion auf Objekte (z.B. Button)

Erstellen und Einbindung einer CS-Funktion z.B bei Button Unterschiede bei Funktionsaufruf mit verschiedenen Typen darstellen

  • Codebeispiel für Union-Types: Mit funktionsauswahl etc.

  • Übergabeparameter demonstrieren

Import von anderen Skripten

Hierbei ist es wichtig, dass der relative Pfad immer mit: „./“(Skript beginnt und sich im selben Ordner oder tiefer befindet

Bildskripte

Es ist auch möglich eine Skriptfunktion zyklisch aufzurufen. Im Gegensatz zum ServerSkripting muss hier eine Funktion und kein Skript angegeben werden. Wenn Funktionen aus demselben Skript Zyklisch aufgerufen werden und auch beim Bild öffnen/schließen Event wird die Skriptfunktion im Bildöffnen immer vor dem ersten zyklischen durchlauf aufgerufen und das Schließen-Event immer nach dem letzten durchlauf. Werden beim öffnen/schließen Event Funktionen in anderen Skripts aufgerufen, so ist die Reihenfolge der Ausführung nicht sicher gestellt. Wenn ein Bild geöffnet und direkt danach wieder geschlossen wird kann es passieren das es keinen zyklischen Durchlauf gibt.

Bildskript

Bei den Funktionen kann jetzt als Aktion Clientskriptfunkion ausführen festgelegt werden. Hier muss das Skript, die Funktion und die Parameter angegeben werden.

Konverter von Pascal zu TypeScript

Im Designer gibt es die Möglichkeit alten Pascal Code zu TypeScript zu konvertieren. Dies ist über das Kontextmenü im Baum bei einem Serverskript möglich.

Wenn das Skript erfolgreich Konvertiert wurde öffnet es sich anschließend. Tritt ein Fehler bei der Konvertierung auf kommt eine Meldung. Hier muss dann überprüft werden ob sich das Serverskript überhaupt übersetzten lässt. Das Originale Skript wird nicht gelöscht.

Es erfolgt keine Automatische Zuweisung des Konvertierten Skriptes zu Bilder bzw. Bildelementen (z.B. Button). Hat ein zu Konvertierendes Skript Abhängigkeiten, dann müssen diese ebenfalls manuell mit Konvertiert werden. Nach dem Konvertieren muss die Funktionalität des Skriptes überprüft werden. Dies ist nötig da nicht alle Sprachkonstrukte eines Serverskriptes in ein Clientskript übernommen werden können. Der Konverter versucht hier immer die beste Lösung zu finden.

Nach dem Konvertieren kann das Skript immer noch Fehler aufweisen. Diese müssen dann manuell behoben werden. Wurde eine Funktion der ServerSkrpt API aufgerfuen die es im Clientskript nicht gibt, bzw. der Converter nicht untersützt, dann wird eine Dummy Methode die ein Fehler wirft am Anfang des Skriptes platziert. Hier kann dann die Funktionalität nachimplementiert werden oder das Skript muss so umgebaut werden das die Funktion nicht mehr erforderlich ist.

Der Konverter ist dafür ausgelegt Serverskripte zu übersetzten die bereits in Bestandprojekten vorhanden sind. Er führt keine Überprüfung durch ob das Serverskript überhaupt gültig ist. Bei einem ungültigen Serverskript kann die Konvertierung fehlschlagen bzw. ein ungültiges Clientskript generiert werden.

Client Script V0 Api

Eine erste Api (V0) ist im ClientSkripting verfügbar. Die Api ist an die Funktionen vom Serverskripting

ngelehnt. Die Syntax zum aufrufen unterscheidet sich jedoch etwas zu der im ServerSkripting.

Des weitern befindet sich die Api unter dem namespace „pweb.v0.scripting“. Um ein userLogin aufzurufen muss also „pweb.v0.scripting.login(username, password)“ aufgerufen werden. Vor jedem API-Aaufruf werden die geänderten Tags an die Webruntime geschrieben. Ein Api aufruf gibt immer ein Promise zurück worauf mit „await“ gewartet werden muss. Während mit await auf die Antwort eine Api Funktion gewartet wird, kann ein anders Skript laufen. Wenn die Antwort dier Api Funktion zurück kommt werden auch nochmal die Tags von der WebRuntime gelesen. Für die Syntax kann IntelliSense verwendet werden.

Bildskript
  • fillImageView

  • specialFunction

  • addLogbookEntry

  • setLanguage

  • getLanguage

  • openNewBrowserWindow

  • openNewBrowserTab

  • changePicture

  • openPicture

  • closePicture

  • printPicture

  • changeAllPictures

  • fillPictureArea

  • login

  • logout

  • createUser

  • deleteUser

  • setUserPassword

  • getUserGroup

  • addUserToGroup

  • removeUserFromGroup

  • getUserInfo

  • setUserInfo

Undo/Redo Der Editor beinhaltet seinen eigenen UndoRedo Stack welcher nicht mit dem des Designers synchronisiert ist. Wenn man also in einem Clientskript ein Skript ändert, erfolgt kein Eintrag für Undo/Redo im Designer. Eine Ausnahme hier von sind Aktionen die Auswirkungen auf andere Bereiche im Designer haben. Aktuell sind das folgende:

  • Tag/Prozessvariable umbenennen (über F2 im CS-Editor)

  • Bereits exportierte Funktion umbenennen (über F2 im CS-Editor)

Note

Wenn es Fehler (keine Warnungen!) in einem Skript gibt, kann es dazu kommen, dass dann Warnungen nicht angezeigt werden können, weil der Compiler dann nicht korrekt feststellen kann, ob er eine Warnung anzeigen muss oder nicht. Eine Leerzeile innerhalb einer while-Schleife wird als Warnung erkannt, eine ungültige Zeichenfolge nicht.

Laufzeit

Zur Laufzeit werden alle Tags die in einem Skript (inklusive importierter Skripte) verwendet werden am TagServer angefragt. Ein Skript wird erst ausgeführt wenn ein erstes Lesen vom TagServer (nicht von der Steuerung) erfolgt ist.

Wird das selbe Skript (muss nicht die selbe Funktion sein) mehrmals hintereinander gestartet ist sichergestellt, dass die Skripten in der korrekten Reihenfolge ausgeführt werden. Bei unterschiedlichen Skripten ist das nicht sichergestellt.

Systemalarme

Nummer

Text

Bedeutung

9500100

WebRuntime: Clientskript konnte nicht geladen werden - Browserversion prüfen

Fehler beim Export oder Browserversion

9500101

WebRuntime: Clientskriptfunkion nicht gefunden

Funktion existiert nicht

9500102

WebRuntime: Unbehandelter Fehler im Clientskript

Fehler im try-catch Block

9500103

WebRuntime: Ungültiger Tagzugriff im Clientskript

Zugriff auf nicht vorhandenen Tag

Sicherheitshinweise

Da Clientskripts nicht auf dem Server, sondern im Browser ausgeführt werden, kann es theoretisch - wie auch jeder andere JavaScript Code, der im Browser läuft - manipuliert werden.

Debuggen

Die Skripte können über den normalen Debugger vom Browser „debuggt“ werden. Die Skripte befinden sich unter dem Worker „clientsScripts“ und dort unter der url „clientscript://“. Es existieren für die Skripte SourceMaps damit der orginale Typescript code angezeigt werden kann und nicht der übersetzte JavaScript Code.

Es Empfiehlt sich in den Optionen vom Chrome/Edge Debugger das Debuggen von der ClientScriptRuntime.js zu deaktivieren. Dazu muss die ClientScriptRuntime.js-Datei bei den benutzerdefinierten Ausschlussregeln hinzugefügt werden.

Serverskripting

Struktur der Skripte im Projekt

Es existieren drei verschiedene Skriptausführungsarten unter PROCON-WEB:

  • Tasks die zyklisch zur Laufzeit abgearbeitet werden (z.B. Globales Skript).

  • Bildspezifische Skripts, die zyklisch zur Bilddarstellungszeit abgearbeitet werden

  • Skripte, die auf Tasten oder Events z.B: Bilder öffnen oder schließen. Alle Skripte werden in der Projektdatenbank abgelegt und im Designer bearbeitet.

Abarbeitung der Ereignisse

Vor dem Abarbeiten der Skripte prüft der SkriptServer bei welchen Skripten in den Tasks die Bedingung wahr ist und arbeitet diese dann zyklisch ab. Die Zykluszeit sagt hier aus, wann das Skript das nächste Mal ausgeführt wird. Hier ist zu beachten, dass die Skripte anhand der Zykluszeiten so wenig wie möglich und so oft wie nötig ausgeführt werden. Je niedriger die Zykluszeit eingestellt wird, desto häufiger wird das Skript ausgeführt.

Die Skripte können in PROCON-WEB nun als eigenständige Skripte auf Tasten und Bilder gelegt werden.

Erstellen und Kompilieren der Skripte

Der Designer erstellt automatisch das Skript Global, sowie einen zyklischen Task mit 100 ms beim Anlegen eines neuen Projektes. Bildorientierte Skripts sind nun normale Skripts, die dem Bild über die Bildklasse zugewiesen werden. Die Skripts können in Tasks verwendet werden, in Bildern als Bildskript oder beim Bild öffnen/schließen.

Alle im Projekt vorhandenen Skripts sind im Projektbaum im PlugIn Skript wählbar.

Important

Skriptnamen müssen mit einem Buchstaben beginnen und dürfen keine Sonderzeichen außer dem Unterstrich ‚_‘ enthalten.

Important

Bildorientierte Skripte von nicht sichtbaren Bildern werden auch ausgeführt.

Um einem Bild ein Skript als bildorientiertes Skript zuzuweisen, wird über den Klassendialog des Bildes das entsprechende Skript ausgewählt.

Skript einer Bildklasse zuweisen

Bildskripte (zyklisches Skript am Bild) werden in folgenden Situationen abgearbeitet:

  • Bild öffnen z.B: über Taster

  • Unsichtbar schalten eines geöffneten Bildes

  • Unsichtbar schalten einer Picture Area, in der das Bild eingebettet ist

  • Bildbereich leeren einer Picture Area, in der das Bild eingebettet ist.

Beim Bild-schließen-Event werden bildorientierte Skripte nicht abgearbeitet

Erstellen von Tasks

Über Tasks können Skripte im SkriptServer zyklisch oder ereignisgesteuert ausgeführt werden. Der Designer erstellt automatisch beim Anlegen eines neuen Projektes einen Task Global, der das Skript Global zyklischen mit 100ms abarbeiten soll.

Task erstellen

Ein Task benötigt zwingend einen Namen, optional eine Beschreibung, und ein Skript das dieser Task ausführen soll. Weiterhin kann definiert werden, ob der Task zyklisch oder ereignisgesteuert ablaufen soll.

Important

Die minimale Zykluszeit eines Tasks beträgt 100ms.

Die Parametrisierung der ereignisgesteuerten Tasks erfolgt analog wie in der Bildmontage.

Da die Skripte Client-bezogen sind, werden sie jeweils im Kontext des entsprechenden Clients ausgeführt. Dies bedeutet, im Skript verwendete lokale Variablen sind die Variablen des jeweiligen Clients, der angemeldete Benutzer der entsprechende Clientuser usw.

Die Skripte laufen pro Client, dementsprechend werden bei mehreren angemeldeten Clients die Skripte auch jeweils entsprechend für JEDEN Client ausgeführt.

Client Start

Die Taskbedingung „Client Start“ führt das hinterlegte Script aus, wenn sich ein Client neu am System anmeldet. Das Script wird beim Starten des Clients ausgeführt und läuft dann einmalig im Hintergrund ab. Der Client wartet allerdings beim Start nicht auf die Beendigung des Skripts. Bei einem langlaufenden Client Start Script kann der Client durchaus bedient werden, bevor das Script komplett abgearbeitet wurde.

Soll der Client erst bestimmte Aktionen zulassen NACHDEM das Script beendet wurde, muss dies beispielsweise über das Setzen einer Prozessvariable am Scriptende realisiert werden, auf die dann der Client entsprechend reagieren kann.

Client Cycle

Die Taskbedingung „Client Cycle“ führt das hinterlegte Script zyklisch für jeden angemeldeten Client aus. Dabei wird das Script ähnlich wie bei globalen zyklischen Scripten immer nach der Intervallzeit erneut getriggert. Läuft das Script länger als die Intervallzeit, wird es direkt im Anschluß erneut getriggert. Es läuft immer nur ein Script pro Client zu einer Zeit, d.h. der nächste Scriptaufruf wird bis zum Ende des vorherigen verzögert bzw. der Aufruf direkt ignoriert wenn das identische Script gerade läuft.

Startup und Shutdown Events

Zusätzlich zu den bisher genannten Tasks lassen sich noch Tasks für den Systemstart und Systemstop definieren. Damit können nun beim Starten der Runtime (genauer gesagt beim Starten des SkriptServers) und beim Beenden der Runtime, Skripte ausgeführt werden.

Es können mehrere Startup- und Shutdown-Skripte definiert werden, diese werden dann der Reihe nach abgearbeitet.

Startup-Skripte jedes Mal beim Übergang des Servers nach Running.

Shutdown-Skripte jedes Mal beim Übergang von Running nach Pause.

Important

Das Startup-Skript kann z.B. für Initialisierungsaufgaben verwendet werden.

Dadurch kann das alte Pattern im globalen Skript ersetzt werden:

PROGRAM
BEGIN
     Init()
     while(1) do …
END

Der Inhalt von Init() kann jetzt als eigenständiges Skript definiert und als Startup-Skript verwendet werden.

Important

Das Shutdown-Skript wird beim Herunterfahren des Dienstes ausgeführt.

Der SystemServer stellt sicher, dass die abhängigen Funktionsserver (TagServer, DataServer, AlertServer) noch laufen. Aber zu dem Zeitpunkt ist u.U. der WebServer bereits heruntergefahren und keine Clients mehr am System angemeldet. Client-bezogene Skriptfunktionen (Bild öffnen, …) können daher fehlschlagen.

Syntax Serverskripte

Übersicht

Es wurde eine eigene Sprache definiert, welche sich an die Syntax von PASCAL anlegt. Die Sprache erlaubt Blockbildung, Kontrollstrukturen, Schleifen und Funktionen für einen modularen Aufbau des Programms.

Alle Anweisungen sind zeilenorientiert, um auf Terminatorsymbole für Anweisungen zu verzichten. Die Zeilenlänge ist auf 255 Zeichen festgelegt. Es sind an beliebigen Stellen im Quellcode Kommentare möglich. Funktionswerte müssen nicht beim Funktionsaufruf angegeben werden, auch wenn die aufgerufene Funktion einen Wert erfordert.

Die Sprache beinhaltet die Grundrechenarten Addition, Subtraktion, Division, Multiplikation, Ganzzahldivision und Divisionsrest. Ebenso die Vergleichsoperatoren =, <> oder !=, <=, >=, >, <.

Die Sprache beinhaltet die Binäroperationen NOT, AND, OR, XOR, SHL, SHR.

Die Sprache erlaubt eine lokale Variablendefinition der einfachen Typen Boolean, Integer, Real, String.

Die Sprache hat eine Standardfunktionsmenge für die einfache Einbindung von Benutzerfunktionen.

Die Sprache erlaubt die Angabe von Konstanten der Typen Boolean, Integer, Real, String.

Groß- und Kleinschreibung wird durch den Compiler unterschieden.

Die Sprache kennt alle Prozesswerte eines Projekts als Variablen des Typs Boolean, Real und String (eindimensionale Felder beachten).

Die Sprache erlaubt maximal 5 Block-Schachtelungen.

Die Sprache erlaubt maximal 5 Klammerebenen.

Die Sprache erlaubt keine Funktionsdefinitionen in Funktionen.

Die Sprache erlaubt keine Semaphore (Formeln nicht synchronisierbar).

In der folgenden Tabelle ist die Rangfolge der Operatoren näher erläutert.

Rang

Operator

not

*, /, div, mod, and, shl, shr

+, -, or, xor

=, <, >, <>, <=, >=

Operatoren mit höherem Rang werden zuerst ausgeführt. Haben Operatoren den gleichen Rang, so wird die Ausführung von links nach rechts durchgeführt. D.h. „*“ wird beispielsweise vor „div“ ausgeführt, not wird vor „*“ und „div“ ausgeführt.

Important

Division von Konstanten ohne „.“ werden als Integer-Werte interpretiert D.h. Bei einer Division muss hier mit Nachkomastellen gearbeitet werden z.B. test = 15.00/3.00 anstelle von test = 15/3

Schlüsselwörter

Bedeutung

StackSize

Stackgröße in Bytes (max. 10000; Voreinstellung: = 4096)

program

Programmbeginn

import

Importiert ein weiteres Skript

Import ..as ..

Importiert ein weiteres Skript mit Alias-Name

private

Mit „private“ definierte Funktionen und Variablen können nicht importiert werden

.

Punkt-Operator zum Zugriff auf Funktionen und Variablen importierter Skripte

const

Konstantendefinition Bsp: const Name = 100 (Der Name muss im Projekt eindeutig sein, d.h. auch keine Namensgleichheit mit Variablen)

var

Variablendefinition (steht immer nach der Konstantendefinition

boolean

Datentyp logische Variable

Integer

Datentyp Integer-Variable

real

Datentyp numersiche Variable

text

Datentyp Datei – Variable

string

Datentyp Text – Variable

begin

Blockbeginn

if..then..else

Kontrollstruktur Bedingung

for..to..do

Schleife mit Inkrementierung (Index nur Integer) (Laufvariable vom Typ: Integer)

for..downto..do

Schleife mit Dekrementierung (Index nur Integer) (Laufvariable vom Typ: Integer)

while..do

Schleife mit Bedingung (Laufvariable vom Typ: Integer)

not, and, or

xor, shl, shr

Binäre Operationen (z.B.: numvar:=numvar1 shl 2)

mod, div

Ganzzahloperationen

end

Blockende

function

Funktionsbeginn

exit

Springt aus der aktuellen Funktion

Syntaxbeschreibung

Important

Schlüsselwörter sind feststehende Begriffe und dürfen im Formelcode nicht für Konstanten oder Variablen verwendet werden.

Terminalsymbole

+, -, *, /

Grundrechenarten

(, )

Klammerung (5 Klammerebenen)

(*, *)

Kommentarkennzeichnung

<, >, <=, >=,<>, =

Vergleichsoperatoren

: =

Zuweisung

[]

Feldindizierung

.

Dezimalpunkt

Stringzeichen

$

Hex-Symbol

:

Var-Trenner

,

Bezeichner-Trenner

Sprachelemente:

Metasymbole:

<T>

T nicht Terminalsymbol

{}

optimale Wertewiederholung

[]

optimaler Wert

Buchstabe

A..Z

Ziffer

0..9

Hex-Ziffer

Ziffer

Numerische Werte:

Hex-Ziffer

$ <Hex-Ziffer> {<Hex-Ziffer>}

Integer

[+||-] <Ziffer> {<Ziffer>}

Realwert

[+||-] <Ziffer> {<Ziffer>} .<Ziffer> {<Ziffer>}

Bezeichner

<Buchstabe> {<Ziffer || Buchstabe>}

Feldbezeichner

<Bezeichner> „[“ <Bezeichner || Integer || Hex-Ziffer> „]“

Variablen-Bezeichner

<Bezeichner> || <Feldbezeichner>

Funktions-Bezeichner

<Bezeichner>

Konstantendeklaration

<Bezeichner> = <Hex-Ziffer || Integer || Realwert

Ergebnistyp

boolean

Variablendeklaration

<Variablen-Bezeichner> {„,“ <Variablen-Bezeichner>} : <Ergebnistyp>

Kommentar

(* <Text> *)

Stackgröße

STACK <Hex-Ziffer || Integer>

Zeilenanzahl

LINES <Hex-Ziffer || Integer>

Programm

program <Block>

Block

[<Import-Deklarationsteil>], [<Konstanten-Deklarationsteil>], [<Variablen-Deklarationsteil>],[<Funktions-Deklarationsteil>], <Befehlsteil>

Befehlsteil

Begin <Anweisungsblock> end

Konst.-Deklarationsteil

const <Konstantendeklaration> {<Konstantendeklaration>}

Variablen-Deklarationsteil

var <Variablendeklaration> {<Variablendeklaration>}

Funktions-Deklarationsteil

<Funktionskopf> <Funktionsblock>

Funktionskopf

function <Bezeichner [„(„<Parameterliste>“)“] : <Ergebnistyp>

Parameterliste

<Variablen-Deklaration> || var <Variablen-Deklaration> {<Parameterliste>}

Funktionsblock

[<Konstanten-Deklarationsteil>] [<Variablen-Deklarationsteil>] <Funktionsbefehlsteil>

Funktionsbefehlsteil

Begin <Anweisungsblock> <Funktions-Bezeichner>: = <Ausdruck> end

Faktor

<Variablenbezeichner> ||<Konstantenbezeichner> || (<Ausdruck>) || <Faktor> || not <Faktor> || <Funktionsaufruf> || <externe Funktion>

Term

<Faktor> {(. || / || div || mod || and || shl || shr)<Faktor>}

Funktionsaufruf

[<Variablen-Bezeichner> : =] <Funktions-Bezeichner> [(<Funktionsparameter>)]

Note

Die Größe des Variablenpools (Byte) in einer Funktion darf die Stackgröße (Voreinstellung = 1024) nicht überschreiten Die Funktionsparameter können auch vom Datentyp ‚String‘ sein.

Funktionsparameter

<Ausdruck || Variablen-Bezeichner> {, <Funktionsparameter>}

einfacher Ausdruck

<Term> { (+ || - || or || xor) <Term>}

Ausdruck

<einfacher Ausdruck> { (< || > || <= || >= || <> ||=) <einfacher Ausdruck>}

Anweisung

<Verbundanweisung> || <bedingte Anweisung> || <Wiederholungsanweisung> || <Zuweisung> || <Funktionsaufruf>

Anweisungsblock

<Anweisung> || <Anweisungsblock>

Verbundanweisung

Begin <Anweisung> {<Anweisung>} end

bedingte Anweisung

if <Ausdruck> then <Anweisung> [else <Anweisung>]

Wiederholungsanweisung

<while-Anweisung> || <for-Anweisung>

while-Anweisung

while <Ausdruck> do <Anweisung>

for-Anweisung

for <Variablen-Bezeichner>:=<Ausdruck> to || downto <Ausdruck>do<Anweisung>

Zuweisung

<Variablen-Bezeichner> : = <Ausdruck>

Allgemeine Regeln und Hinweise

Fehlerhandling

Im Skript Editor des Designers kann man in der Fehlerliste erkennen, ob es sich um eine Warnung oder um einen Fehler handelt. Dies funktioniert für Client- und Serverskripte. Wird ein gelbes „!““ angezeigt handelt es sich um eine Warnung. Bei einem Roten X um einen Fehler. Existieren Skripte mit Fehler kann nicht mehr exportiert werden. Bei Warnungen kann weiterhin exportiert werden. Es werden Fehler immer vor Warnungen angezeigt. Dies kann dazu führen, dass Warnungen nicht angezeigt werden, wenn direkt davor ein Fehler ist.

Unterprogrammaufruf

Mithilfe von eventlokalen Variablen können Prozesswerte an ein Unterprogramm übergeben und das Ergebnis an das Hauptprogramm zurückgegeben werden.

(* 2 values are transferred to the “fnMinMax” subroutine in order to compare them. The result of the
function is returned to the main program using the function variable result1 or result2.
– Call by value –
The variables Pvar1, Pvar2, Pvar3 and minmax_bit are globally defined process variables. *)

Program
  var Param1, Param2, Ergebnis1, Ergebnis2: integer

function fnMinMax(wert1 : integer, wert2 : integer, var result1, result2 : integer) : integer
begin
   if wert1 > wert2 then
   begin
     result1:=wert1
     result2:=wert2
   end
   else
   begin
      result2 := wert1
      result1 := wert2
   end
   (*Assign function own return value*)
   fnMinMax := (wert1+wert2) / 2
end

(* Main program *)
begin
   if minmax_bit = 1 then
   begin
      minmax_bit :=0

      (* Copy process variables to local transfer variables *)
      Param1 := Pvar1
      Param2 := Pvar2
      (* Function call with function parameters *)
      Pvar3:= fnMinMax(Param1, Param2, Ergebnis1, Ergebnis2)

      (* Copy local result variables to process variables *)
      Pvar1 := Ergebnis1
      Pvar2 := Ergebnis2
   end
end

Note

Der Inhalt einer Stringvariablen kann nicht an eine Funktion übergeben werden. In diesem Fall muss der Zeiger auf die Stringvariablen übergeben werden, d.h. eine Änderung in der Funktion wirkt sich unmittelbar auf die Stringvariable selbst aus –> Call by reference.

Konstante u. variable Übergabeparameter im Format „string“

Die Programmiersprache in PROCON-WEB verlangt in sehr vielen Funktionen Übergabeparameter vom Typ „String“. Diese Übergabeparameter können sowohl variabel als auch konstant sein. Variable Parameter sind lokale oder globale Textvariablen, konstante Parameter sind Texte in einfachen Hochkommas (‘xx’).

(* The CopyFiles function copies one or more files from a source directory to a target directory. The
source should be constant, the target should be defined via a variable.  *)

PROGRAM
var ziel[20] : string
var return : integer
begin
   ziel := 'c:\tmp\project.pcs'
   return := CopyFiles('C:\PCSPRJCT\Project.pcs', ziel)
end

Note

Die Textvariable „ziel“ ist lokal definiert, d.h. nur in dieser Funktion gültig. Man könnte auch eine global definierte Textvariable (aus dem Textvariableneditor der Bildmontage) verwenden und diese z.B. in einem Prozessbild interaktiv verändern.

Transiente Variablen

Es können nun flüchtige Variablen deklariert werden, deren Wert nach jedem „Skriptdurchlauf“ auf den Default-Wert zurückgesetzt wird.

Hierzu wurde das neue Schlüsselwort transient var eingeführt. Damit können Variablen definiert werden, deren Wert nach jedem Skriptdurchlauf auf Default zurückgesetzt wird.

Im Gegensatz dazu behalten „normale“ Variablen zwischen den Skriptaufrufen ihren Wert. Die Variable wird in den folgenden Fällen zurückgesetzt:

Ereignisorientiertes Skript (global oder client-spezifisch): Vor jedem einmaligen Durchlauf des Skripts

Zyklisches Bildskript: Wenn das Bild geöffnet wird. Die Variable behält dann den Wert während das Bild geöffnet bleibt. Beim Schließen und erneuten Öffnen wird sie wieder zurückgesetzt

Zyklisches globales Skript: Wenn das Skript initial gestartet wird (beim Projektstart). Die Variable behält dann den Wert während der Projektlaufzeit bis das Projekt beendet wird. D.h. für globales zyklisches Skript verhält sich eine volatile Variable wie eine normale Variable auch, es macht also keinen Unterschied, ob volatil verwendet wird oder nicht

PROGRAM

var normalVar : integer
transient var volVar : integer

BEGIN
  normVar := normVar + 1
  volVar := volVar + 1
END

Skript Import-Funktionalität

In PROCON-WEB existiert nun die Möglichkeit, Funktionen und globale Variable von anderen Skriptdateien zu referenzieren und zu benutzen. Hierzu wurden vier neue Schlüsselwörter eingefügt.

Schlüsselwörter

import

Importiert ein weiteres Skript

Import ..as ..

Importiert ein weiteres Skript mit Alias-Name

private

Mit „private“ definierte Funktionen und Variablen können nicht importiert werden

.

Punkt-Operator zum Zugriff auf Funktionen und Variablen importierter Skripte

Note

Das Import-Statement importiert ein anderes Skript entweder über den Namen oder einen Alias

Important

Das Import-Statement MUSS direkt nach PROGRAM kommen.

import <SKRIPTNAME>

import <SKRIPTNAME> as <ALIASNAME>

Um in dem importierten Skript bestimmte Variablen und Funktionen zu verbergen, können diese mit dem Schlüsselwort private nur zur Benutzung innerhalb des Skripts definiert werden.

private var <VARIABLENNAME>

private function <FUNCTIONNAME>(  )

Durch die Verwendung der Skriptnamen ergeben sich für die Skriptnamen neue Einschränkungen:

  • Skriptnamen müssen eindeutig sein

  • Skriptnamen dürfen nicht wie Prozessvariablen heißen

  • Skriptnamen dürfen nicht wie Funktionen oder Variablen innerhalb des Skripts heißen

  • Skriptnamen dürfen nur Buchstaben (A…Z || a…z || _ ) oder Ziffern (0..9) enthalten, keine sonstigen Sonderzeichen und Umlaute

Dies führt sonst zu Compiler-Fehlern

PROGRAM

var ExportVar : integer
private var TestVar : integer

function ExportFnc(input : integer) : integer
BEGIN
  ExportVar := input
  ExportFnc := input + 1
END

private function TestFnc() : integer
BEGIN

END

BEGIN

END

(* And here is a program that uses this script: *)
PROGRAM

import LibrarySkript as Lib

var testVar2,testVar3 : integer

BEGIN
  testVar2 := Lib.ExportFnc(3)
  testVar3 := Lib.ExportVar
END

Das Skript wird über den Alias „Lib“ angesprochen, die deklarierte Variable TestVar und die Funktion TestFnc () sind für das Skript NICHT benutzbar, da diese als private deklariert sind. Die Variable ExportVar und die Funktion ExportFnc () kann dagegen verwendet werden.

break und continue

Es existieren nun die beiden Schlüsselwörter break und continue, die in Schleifen verwendet werden können.

Schlüsselwörter

continue

Bricht den aktuellen Schleifendurchlauf ab und fährt mit dem nächsten Durchlauf fort

break

bricht die komplette Schleife ab

PROGRAM

var incr : integer

BEGIN
  for incr := 0 to 30 do
  begin
    if (incr = 10) then
    break
       else if (incr = 20) then
       continue

      DefaultNumericVariable := incr
  end
END

Division durch 0

Wird in einem Skript eine Division durch 0 durchgeführt, wird an dieser das Skript mit dem Systemalarm 996611 (SkriptServer: Division durch Null in Skript %s) abgebrochen.

Es wird das Skript an der Stelle des Fehlers beendet und der restliche Code des Skripts wird nicht weiter ausgeführt. Auch der Prozessvariablen-Austausch der normalerweise am Ende eines Skript stattfindet erfolgt NICHT, d.h. das normal zugewiesene und modifizierte Prozessvariablen des Skripts auf Ihren Wert vor Skriptausführung beibehalten.

Ausnahmen sind Funktionsaufrufe, die direkt bei Ihrem Aufruf zu Prozessvariablenänderungen führen: Delay(), WriteToProcess(), Alert() und DBSend() / DBRecieve(), SetValue() und SetTagProperty().

Werden diese Funktionen im Skript VOR der Division durch Null aufgerufen, findet an der Stelle natürlich korrekt der Prozessvariablenaustausch statt. Jegliche Variablenzuweisung nach einer der oben genannten Funktionen und anschließener Division durch null werden natürlich nicht ausgeführt.

PROGRAM
var zeroValue : Integer
BEGIN
    TestPvar := 1 (*TestPvar is global variable *)
    Delay(10) (* TestPvar is now 1 *)

    TestPvar := 2
    WriteToProcess(1) (* TestPvar is now 2 *)

    zeroValue := 0
    TestPvar := 10 / zeroValue (*DIVISION BY ZERO!!! Skript is aborted here*)

    (*The following code is NEVER executed*)
    WriteToProcess(1)
    TestPvar := 3
    WriteToProcess(1) (*TestPvar is still 2*)
END

Funktionsbeschreibung

Bei den nachfolgend beschriebenen Funktionen handelt es sich um fest integrierte Funktionen, die einige Leistungen des Laufzeitsystems zur Verfügung stellen. Innerhalb der einzelnen Funktionen wird definiert, ob dieses auch in der IoT-Variante oder nur in SCADA zur Verfügung steht.

Alphabetische Übersicht

Abs

Berechnung des Absolutbetrags

AbsToTime

Umrechnung von Zeiten

AddPicture

Hinzufügen eines Bildes

Alert / AlertAsync

Setzen, Quittieren und Rücksetzen von Alarmen

Alert / AlertAsync

Setzen, Quittieren und Rücksetzen von Alarmen

Append

Öffnen einer existierenden Textdatei zum Anhängen von Daten

AppendString

Funktion zum Anhängen einer Zahl an einen String, sowie eines weiteren Strings, der als Separator für die Verkettung verwendet werden kann

Arccos

Arkuskosinus eines Winkels

Arcsin

Arkussinus eines Winkels

Arctan

Arkustangens eines Winkels

Arctan2

Arkustangens mit zwei Parametern eines Winkels

Assign

Zuordnen einer Textdatei zu einer Dateivariablen

AssignUnsafe

Zuordnen einer Textdatei zu einer Dateivariablen

BackCopyFiles

Kopieren von Dateien asynchron im Hintergrund

CalculateDIN8743

Funktion zum Starten der Auswertung

CalculateStatistic

Funktion zum Starten der Auswertung

ChangeAllPictures

Bildwechselfunktion für alle Bilder

ChangePicture

Bildwechselfunktion

ChangeProject

Ändert das aktuelle Projekt

Close

Schließen einer Textdatei

ClosePicture

Schließen eines Bildes

CompareFiles

Funktion zum Vergleichen zweier Dateien auf Größe oder Zeitstempel

CopyFiles

Kopieren von Dateien

Cos

Kosinus eines Winkels

Cosh

Hyperbelkosinus eines Winkels

CreateDir

Erzeugen von Verzeichnissen

CreateUser

Benutzer erzeugen

DateAdd

Funktion zum Addieren von spezifischen Zeitspannen auf die absolute Systemzeit

DateToAbs

Funktion zum Umwandeln von einem Datum im String-Format zu einem Absolutwert

DateToString

Funktion zum Umwandeln von Datums - und Zeitangaben auf einen String

DateStringAdd

Funktion zum Addieren von spezifischen Zeitspannen auf die absolute Systemzeit

DBCloseODBC

Verbindung zum ODBC-Treiber schließen

DBCopy

Kopieren eines Datensatzes aus einer Datenbank in eine neue Datenbank

DBCopyIndex

Kopieren eines Datensatzes aus einer Datenbank in eine andere Datenbank über den Datensatzindex

DBDelete

Löschen von Datensätzen aus der Datenbank

DBDeleteIndex

Löschen von Datensätzen aus der Datenbank über den Datensatzindex

DBFetchTabODBC

Datensatz aus selektierter Menge laden

DBFieldCount

Anzahl der Felder eines Datensatzes ermitteln

DBFieldType

Typ eines Datensatzfeldes ermitteln

DBFindRecord

Datensatz mit angegebenem Namen in der Datenbank suchen

DBGetDataODBC

Datenelemente aus ODBC-Puffer lesen

DBGetErrorODBC

Fehlertexte für letzten ODBC-Fehler beschaffen

DBGetInfoDataODBC

Struktur eines Datenelemente ermitteln der selektierten Tabelle ermitteln

DBGetInfoTabODBC

Anzahl der selektierten Datensätze und der Datenelemente ermitteln

DBGetStampODBC

Zeitstempel aus ODBC-Puffer lesen

DBNotifyDataChanged

Funktion um alle Clients (Grids) über eine Änderung der übergebenen Datenverwaltung zu informieren

DBOpenODBC

Verbindung zum ODBC-Treiber herstellen

DBOpenODBCConnection

Verbindung zu einer ODBC-Datenquelle herstellen

DBProcedureODBC

ODBC-Prozedur ausführen

DBPutDataODBC

Datenelemente in ODBC-Puffer ändern

DBPutStampODBC

Zeitstempel aus ODBC-Puffer schreiben

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess zum Schreiben in die Datenbank

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess zum Schreiben in die Datenbank über den Datensatzindex

DBRecipeChangeState

Ändern des Status eines Rezepts

DBRecipeChangeStateIndex

Ändern des Status eines Rezepts über den Statusindex

DBRecipeChangeVersion

Ändern der Version eines Rezepts

DBRecipeChangeVersionIndex

Ändern der Version eines Rezepts über den

DBRecipeChangeName

Ändern des Namens eines Rezepts

DBRecipeChangeNameIndex

Ändern des Namens eines Rezepts über den Namensindex

DBRecordName

Name eines Datensatzes aus der Datenbank lesen; Anzahl der Datensätze in der Datenbank

DBSend / DBSyncSend / DBSendIndex

Senden von Datensätzen aus der Datenbank in den Prozess

DBSend / DBSyncSend / DBSendIndex

Senden von Datensätzen aus der Datenbank über die Datensatznummer (Index)

DBSendSQLODBC

SQL-Anweisung an den ODBC-Treiber schicken

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess in Datenbank mit Anforderung der akt. Treiber-Werte durch das VisuCompact

DeleteFiles

Löschen von Dateien

DeleteTree

Löschen von Verzeichnissen

DeleteUser

Benutzer löschen

DVExportView

Export der Daten einer Datenrekorder-Ansicht

ExistFile

Funktion zum Prüfen, ob eine Datei existiert oder nicht

Exp

Exponentialfunktion e ^ x

FillImageView

Löscht ein ImageView und befüllt es neu

FillPictureArea

Löscht die Bilder einer PictureArea und befüllt sie neu

GetIniString

Liefert einen String aus einer INI-Datei

GetDefaultPrinterByIndex

Liest den Default Drucker aus (Übergabe des Index)

GetDefaultPrinterByName

Liest den Defaultdrucker aus (Übergabe des Namens)

GetLanguage

Funktion zum Erfragen der aktuellen Bediensprache

GetPrinterCount

Liest die Anzahl der Drucker aus dem System aus

GetPrinterName

Liest den Namen eines Druckers aus

GetSubString

Liefert einen Substring aus einem Quellstring

GetTagProperty

Lesen des aktuellen Wertes eines Tag-Properties

GetUserGroup

Benutzergruppe auslesen

GetUserInfo

Benutzerinformationen auslesen

GetValue

Auslesen des Inhalts einer Variablen

IsNumeric

Findet heraus, ob ein Ausdruck eine Zahl ist

Length

Ermitteln der Länge eines Strings

Ln

natürlicher Logarithmus

Log

10er Logarithmus

LogEventString

Funktion zum Schreiben eines Strings in das Logbuch

Login

Benutzer anmelden

Logout

Benutzer abmelden

MoveFiles

Verschieben von Dateien, Verzeichnissen

NewPicture

Neues Bild hinzufügen bzw. Bildwechsel

OpenBrowser

Öffnen einer URL

OpenPicture

Öffnen eines Bildes

Pos

Suchen eines Strings in einem String

Pow

Potentfunktion x ^ y

PrintPicture

Drucken eines Bildes

Random

Erstellen einer Zufallszahl

Randomize

Initialisierung des Zufallgenerators

Read

Lesen von Daten aus einer Text-Datei zu einer Dateivariablen

ReadLine

Liest eine Zeile aus einer Datei und schaltet den Dateipositionszeiger auf die nächste Zeile

ReadFromProcess

Funktion zum Lesen der im Skript verwendeten Prozessvariablen

Reset

Öffnen einer Text-Datei zu einer Dateivariablen

Rewrite

Öffnen oder Erzeugen einer Text-Datei zu einer Dateivariablen

SetDefaultPrinterByIndex

Setzt den Default Drucker (Übergabe des Index)

SetDefaultPrinterByName

Setzt den Default Drucker (Übergabe des Namens)

SetIniString

Setzt einen String in einer INI-Datei

SetLanguage

Neue Sprache setzen

SetTagProperty

Setzen des aktuellen Wertes eines Tag-Properties

SetUserGroup

Benutzer zu Benutzergruppe hinzufügen/löschen

SetUserInfo

Benutzerinformationen setzen

SetUserPassword

Passwort setzen

SetValue

Zuweisen des Inhalts einer Variablen zu einer anderen Variablen

Sin

Sinus eines Winkels

Sinh

Hyperbelsinus eines Winkels

SpecAlert

Funktion zum Öffnen des Nachspezifizieren-Dialogs

Special

Auslösen von Sonderfunktionen

Sqrt

Quadratwurzel

StatisticClose

Funktion zum Freigeben des allokierten Speichers

Str

Konvertieren einer Zahl in einen String

StringEndsWith

Prüft, ob das Ende dieser Zeichenfolgeninstanz mit der angegebenen Zeichenfolge übereinstimmt

StringFormat

Formatiert einen String in ein bestimmtes Format

StringIndexOf

Liefert den nulllbasierten Index des ersten Vorkommens eines angege- benen Unicode-Zeichens oder Unicode-Zeichenfolge zurück

StringInsert

Fügt einen String an einer spezifischen Position in einen String ein

StringToLower

Konvertiert einen Sting in Kleinbuchstaben

StringRemove

Entfernt eine bestimmt Anzahl an Zeichen aus einem String

StringReplace

Ersetzt ein Zeichen durch ein anderes

StringRegExIsMatch

Prüft, ob ein Ausdruck in einem String vorhanden ist

StringStartsWith

Prüft, ob der Anfang dieser Zeichenfolgeninstanz mit der angegebenen Zeichenfolge übereinstimmt

StringTemplate

Fügt Zeichen in einen String ein

StringToInt

Konvertiert einen String in einen Integer

StringToReal

Konvertiert einen String in eine Zahl

StringTrim

Enfternt an allen Stellen einer Zeichenfolge das benannte Zeichen

StringToUpper

Konvertiert einen String in Großbuchstaben

Tan

Tangens eines Winkels

Tanh

Hyperbeltangens eines Winkels

Time

Lesen der Systemdatum und -zeit

TimespanToString (nur SCADA)

Funktion zum Wandeln von Millisekunden zu Sekunden, Stunden, Minuten

TimeToAbs

Umrechnung von Zeiten

TimeUtcToLocal

Umrechnen der UTC in die Lokale Zeit

TimeLocalToUtc

Umrechnen der lokalen in die UTC Zeit

Val

Konvertieren eines Strings in eine Zahl

ValidPath

Überprüft ob der angegebene Dateipfad vorhanden ist

WinExec

Starten eines anderen Programms

Write

Schreiben von Daten auf eine Text-Datei zu einer Dateivariablen

WriteToProcess

Funktion zum Schreiben der im Skript verwendeten Prozessvariablen

Übersicht nach Funktionsgruppen

Störungsverarbeitungsfunktionen

Störungsverarbeitungsfunktionen

Alert / AlertAsync

Setzen, Quittieren und Rücksetzen von Alarmen

SpecAlert

Funktion zum Öffnen des Nachspezifizieren-Dialogs

Dateiverarbeitungs-/ Verzeichnisfunktionen

Dateiverarbeitungs-/ Verzeichnisfunktionen

Append

Öffnen einer existierenden Textdatei zum Anhängen

von Daten

Assign

Zuordnen einer Textdatei zu einer Dateivariablen

AssignUnsafe

Zuordnen einer Textdatei zu einer Dateivariablen

BackCopyFiles

Kopieren von Dateien asynchron im Hintergrund

Close

Schließen einer Textdatei

CopyFiles

Kopieren von Dateien

CompareFiles

Funktion zum Vergleichen zweier Dateien auf Größe oder Zeitstempel.

CreateDir

Erzeugen von Verzeichnissen

DeleteFiles

Löschen von Dateien

DeleteTree

Löschen von Verzeichnissen

ExistFile

Funktion zum Prüfen ob eine Datei existiert oder nicht.

GetIniString

Liefert einen String aus einer INI-Datei

MoveFiles

Verschieben von Dateien, Verzeichnissen

Read

Lesen von Daten aus einer Text-Datei zu einer Dateivariablen

ReadLine

Liest eine Zeile aus einer Datei und schaltet den Dateipositionszeiger auf die nächste Zeile

Reset

Öffnen einer Text-Datei zu einer Dateivariablen

Rewrite

Öffnen oder Erzeugen einer Text-Datei zu einer Dateivariablen

SetIniString

Setzt einen String in einer INI-Datei

ValidPath

Überprüft ob der angegebene Dateipfad vorhanden ist

Write

Schreiben von Daten auf eine Text-Datei zu einer Dateivariablen

Datenverwaltungsfunktionen

Datenverwaltungsfunktionen

DBAccessValue

Inhalt eines Datensatzelementes lesen oder schreiben

DBCopy

Kopieren eines Datensatzes aus einer Datenbank in eine neue Datenbank

DBCopyIndex

Kopieren eines Datensatzes aus einer Datenbank in eine andere Datenbank über den Datensatzindex.

DBDelete

Löschen von Datensätzen aus der Datenbank

DBDeleteIndex

Löschen von Datensätzen aus der Datenbank über den Datensatzindex.

DBFieldCount

Anzahl der Felder eines Datensatzes ermitteln

DBFieldType

Type eines Datensatzfeldes ermitteln

DBFindRecord

Datensatz mit angegebenem Namen in der Datenbank suchen

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess zum Schreiben in die Datenbank

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess zum Schrei- ben in die Datenbank über den Datensatzindex

DBRecordName

Name eines Datensatzes aus der Datenbank lesen

DBSend / DBSyncSend / DBSendIndex

Senden von Datensätzen aus der Datenbank in den Prozess

DBSend / DBSyncSend / DBSendIndex

Senden von Datensätzen aus der Datenbank über die Datensatznummer (Index)

DBReceive / DBSyncReceive / DBReceiveIndex

Empfang von Datensätzen aus dem Prozess in die Datenbank mit Anforderung der aktuellen Werte durch das VisuCompact vom Treiber

DBSend / DBSyncSend / DBSendIndex

Senden von Datensätzen aus der Datenbank in den Prozess mit Übertragung der aktuellen Werte durch das VisuCompact an den Treiber

DBNotifyDataChanged

Funktion um alle Clients (Grids) über eine Änderung der übergebenen Datenverwaltung zu informieren

Chartfunktionen

Chart-/Datenloggerfunktionen

DVExportView

Export der Daten einer Datenrekorder-Ansicht

Funktionen zur Rezeptverwaltung

Funktionen zur Rezeptverwaltung

DBRecipeChangeState

Ändern des Status eines Rezepts

DBRecipeChangeStateIndex

Ändern des Status eines Rezepts

DBRecipeChangeVersion

Ändern der Version eines Rezepts

DBRecipeChangeVersionIndex

Ändern der Version eines Rezepts

DBRecipeChangeName

Ändern des Namens eines Rezepts

DBRecipeChangeNameIndex

Ändern des Namens eines Rezepts

Funktionen für ODBC-Schnittstelle

Funktionen der ODBC-Schnittstelle

DBOpenODBC

Verbindung zum ODBC-Treiber herstellen

DBOpenODBCConnection

Verbindung zu einer ODBC-Datenquelle herstellen

DBCloseODBC

Verbindung zum ODBC-Treiber schließen

DBSendSQLODBC

SQL-Anweisung an den ODBC-Treiber schicken

DBProcedureODBC

ODBC-Prozedur ausführen

DBFetchTabODBC

Datensatz aus selektierter Menge laden

DBGetDataODBC

Datenelemente aus ODBC-Puffer lesen

DBPutDataODBC

Datenelemente in ODBC-Puffer ändern

DBGetStampODBC

Zeitstempel aus ODBC-Puffer lesen

DBPutStampODBC

Zeitstempel aus ODBC-Puffer schreiben

DBGetInfoTabODBC

Anzahl der selektierten Datensätze und der Datenelemente ermitteln

DBGetInfoDataODBC

Struktur eines Datenelements der selektierten Tabelle ermitteln

DBGetErrorODBC

Fehlertexte für letzten ODBC-Fehler beschaffen

Stringverarbeitungsfunktionen

Stringverarbeitungsfunktionen

AppendString

Funktion zum Anhängen einer Zahl an einen String, sowie eines weiteren Strings, der als Separator für die Verkettung verwendet werden kann

DateToStr

Wandeln von Datums- u. Zeitangaben in einem String

GetSubString

Liefert einen Substring aus einem Quellstring

IsNumeric

Findet heraus, ob ein Ausdruck eine Zahl ist

Length

Ermitteln der Länge eines Strings

Pos

Suchen eines Strings in einem String

Str

Konvertieren einer Zahl in einem String

StringEndsWith

Prüft, ob das Ende dieser Zeichenfolgeninstanz

mit derangegebenen Zeichenfolge übereinstimmt

StringFormat

Formatiert einen String in ein bestimmtes Format

StringIndexOf

Liefert den nulllbasierten Index des ersten Vorkommens eines ngegebenen Unicode-Zeichens a oder Unicode-Zeichenfolge zurück

StringInsert

Fügt einen String an einer spezifischen Position

in einen String ein

StringToLower

Konvertiert einen Sting in Kleinbuchstaben

StringRemove

Entfernt eine bestimmt Anzahl an Zeichen aus einem String

StringReplace

Ersetzt ein Zeichen durch ein anderes

StringRegExIsMatch

Prüft, ob ein Ausdruck in einem String vorhanden ist

StringStartsWith

Prüft, ob der Anfang dieser Zeichenfolgeninstanz mit der angegebenen Zeichenfolge übereinstimmt

StringTemplate

Fügt Zeichen in einen String ein

StringToInt

Konvertiert einen String in einen Integer

StringToReal

Konvertiert einen String in eine Zahl

StringTrim

Enfternt an allen Stellen einer Zeichenfolge das benannte Zeichen

StringToUpper

Konvertiert einen String in Großbuchstaben

Val

Konvertieren eines Strings in eine Zahl

Mathematische Funktionen

Mathematische Funktionen

Exp

Exponentialfunktion e ^ x

Ln

natürlicher Logarithmus

Log

10er Logarithmus

Pow

Potentfunktion x ^ y

Sqrt

Quadratwurzel

Abs

Berechnung des Absolutbetrags

Trigonometrische Funktionen

Trigonometrische Funktionen

Cos

Cosinus eines Winkels

Sin

Sinus eines Winkels

Tan

Tangens eines Winkels

Arccos

Arkuskosinus eines Winkels

Arcsin

Arkussinus eines Winkels

Arctan

Arkustangens eines Winkels

Arctan2

Arkustangens mit zwei Parametern eines Winkels

Cosh

Hyperbelkosinus eines Winkels

Sinh

Hyperbelsinus eines Winkels

Tanh

Hyperbeltangens eines Winkels

Zeit und Datumsfunktionen

Zeit und Datumfunktionen

AbsToTime

Umrechnung von Sekundenwert in Datum und Uhrzeit

TimeToAbs

Umrechnung von Datum und Uhrzeit in Sekundenwert

Time

Lesen von Systemdatum und –zeit

TimeUtcToLocal

Umrechnen der UTC in die Lokale Zeit

TimeLocalToUtc

Umrechnen der lokalen in die UTC Zeit

DateAdd

Funktion zum Addieren von spezifischen Zeit- spannen auf die absolute Systemzeit.

DateStringAdd

Funktion zum Addieren von spezifischen Zeit- spannen auf die absolute Systemzeit

DateToString

Funktion zum Umwandeln von Datums- und Zeit- angaben auf einen String

DateToAbs

Funktion zum Umwandeln von einem Datum im String-Format zu einem Absolutwert

TimespanToString (nur SCADA)

Funktion zum Wandeln von Millisekunden zu

Sekunden, Stunden und Minuten

Benutzerverwaltungsfunktionen

Benutzerverwaltungsfunktionen

Login

Benutzer anmelden

Logout

Benutzer abmelden

CreateUser

Benutzer erzeugen

DeleteUser

Benutzer löschen

SetUserPassword

Passwort setzen

GetUserGroup

Benutzergruppe auslesen

SetUserGroup

Benutzer zu Benutzergruppe hinzufügen/löschen

GetUserInfo

Benutzerinformationen auslesen

SetUserInfo

Benutzerinformationen setzen

Bildverarbeitungsfunktionen

Bildverarbeitungsfunktionen

AddPicture

Hinzufügen eines Bildes

ChangePicture

Bildwechselfunktion

NewPicture

Neues Bild hinzufügen, bzw. Bildwechsel

OpenPicture

Öffnen eines Bildes

ClosePicture

Schließen eines Bildes

PrintPicture

Drucken eines Bildes

ChangeAllPictures

Bildwechselfunktion für alle Bilder

FillImageView

Löscht ein ImageView und befüllt es neu

FillPictureArea

Löscht die Bilder einer PictureArea und befüllt sie neu

Prozessvariablenfunktionen

Prozessvariablenfunktionen

GetTagProperty

Lesen des aktuellen Wertes eines Tag-Properties

ReadFromProcess

Funktion zum Lesen der im Skript verwendeten Prozessvariablen

SetTagProperty

Setzen des aktuellen Wertes eines Tag-Properties

WriteToProcess

Funktion zum Schreiben der im Skript verwendeten Prozessvariablen

GetValue

Auslesen des Inhalts einer Variablen

SetValue

Zuweisen des Inhalts einer Variablen zu einer anderen Variablen

Sonderfunktionen

Sonderfunktionen

Special

Auslösen von Sonderfunktionen

Externer Funktionsaufruf / Programmstart

Externer Funktionsaufruf, Programmstart

WinExec

Starten eines Programmes

Sonstige Funktionen

Sonstige Funktionen

Delay

Verzögert das auszuführende Skript

LogEventString

Funktion zum Schreiben eines Strings in das Logbuch

SetLanguage

Neue Sprache setzen

Random

Erstellen einer Zufallszahl

Randomize

Initialisierung des Zufallgenerators

ChangeProject

Ändert das aktuelle Projekt

GetLanguage

Funktion zum Erfragen der aktuellen Bediensprache

OpenBrowser

Öffnen einer URL

DIN 8743 Funktionen

DIN 8743 Funktionen

CalculateDIN8743

Funktion zum Starten der Auswertung

CalculateStatistic

Funktion zum Starten der Auswertung

StatisticClose

Funktion zum Freigeben des allokierten Speichers

Funktionen zum Druckerhandling

Funktionen zum Druckerhandling

GetPrinterCount

Liest die Anzahl der Drucker aus dem System aus

GetPrinterName

Liest den Namen eines Druckers aus

GetDefaultPrinterByIndex

Liest denDefault Drucker aus (Übergabe des Index)

GetDefaultPrinterByName

Liest denDefault Drucker aus (Übergabe des Names)

SetDefaultPrinterByIndex

Setzt den Default Drucker (Übergabe des Index)

SetDefaultPrinterByName

Setzt den Default Drucker (Übergabe des Namens)

Störungsverarbeitungsfunktionen (nur SCADA)

Alert / AlertAsync

Die Funktion „Alert“ bzw. „AlertAsync“ dient zum Setzen, Quittieren und Rücksetzen von Störungen. Einen Unterschied gibt es zwischen den beiden Funktionen nicht mehr. Skripte werden immer komplett von Anfang bis Ende ohne Unterbrechung abgearbeitet. Ein Benutzer wird nur beim Quittieren und Kommentieren übermittelt, nicht jedoch beim Auslösen eines Alarmes

Important

Die Funktionen schreiben vor dem Aufruf die Prozessvariablen des Skripts zum Prozess, da sich dynamische Textanteile von Alarmen verändert haben könnten und liest nach dem Aufruf die Prozessvariablen wieder zurück.

Important

Im Client/Server System kann aufgrund der vernetzten Systeme ein sofortiges Rücksetzen eines zuvor ausgelösten Alarmes nicht realisiert werden.

Funktionsdefinition: Alert(set_reset, number : integer) : integer

AlertAsync (set_reset, number : integer) : integer

Parameter:

set_reset

Index für Aktion

0 = alle Störungen rücksetzen

1 = angegebene Störung setzen

2 = angegebene Störung rücksetzen

3 = alle Störungen quittieren

4 = angegebene Störung quittieren

number

Nummer der Störung zum Rücksetzen/Setzen

Rückgabewerte:

-1

wenn Alarmaktion nicht erfolgreich war

0

wenn Alarmaktion ausgeführt wurde;

Bei Index für Aktion 1, 2 oder 4 ist der Rückgabewert (für Alarmaktion ausgeführt) gleich der entsprechenden Alarm-Instanz-ID|

Beispiel
PROGRAM

(*-----------------------------------------------*)
(* Macro for triggering alarm 100 via a constant *)
(*-----------------------------------------------*)
function macro_02:integer
begin
    Alert(1,100)
end

(*-----------------------------------------------*)
(* Macro for resetting an alarm via process var. *)
(*-----------------------------------------------*)
function macro_03 :integer
var hilfsvar : integer
begin
    hilfsvar := Prozessvariable1
    Alert(2,hilfsvar)
End

BEGIN
END

Important

Mit Index „0“ für die Aktion werden alle vorhandenen Projekt- und Systemalarme geprüft und zurückgesetzt, deshalb zeitintensiv!

SpecAlert

Funktion zum Öffnen des Nachspezifizieren-Dialogs. Optional gefiltert nach Unit.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: SpecAlert(Unit: string) : integer

Parameter:

Unit

Name der Unit nach der zu Filtern ist

Rückgabewerte:

0

Wenn Dialog geöffnet wurde

< 0

Wenn Dialog nicht geöffnet wurde

Beispiel
PROGRAM

FUNCTION DoAlertSpec(unit : string) : integer
BEGIN
    DoAlertSpec := SpecAlert(unit)
END

BEGIN
    DoAlertSpec('')
    DoAlertSpec('Maschine1.Unit1')
END

Dateiverarbeitungs-/Verzeichnisfunktionen (nur SCADA)

Append

Funktion zum Öffnen einer existierenden Textdatei zum Anhängen weiterer Daten. Append öffnet die Datei, die vorher durch Assign mit der Textdateivariablen verbunden wurde und setzt die momentane Position innerhalb dieser Datei ans Ende. Ist die Datei nicht vorhanden, so wird diese vorher erzeugt. Folgende Schreibaktionen hängen also neue Daten an.

Funktionsdefinition:

Append(File : Text) : integer

Parameter:

Name

Name der Datei die zu Öffnen ist

Rückgabewerte:

0

wenn Datei geöffnet wurde

< 0

wenn Datei nicht geöffnet wurde

Beispiel
PROGRAM
var datei1 : text, error : integer

function WriteFile:integer
(* Opens file TEXTDAT.TXT and writes temperature switch-off value = value *)
var i:integer

begin
    error := Assign(datei1,'C:\TMP\TEXTDAT.TXT')
    (* Connect the file to a file variable *)
    if (error >= 0) then
    begin
        error := Append(datei1)
        (* Open the existing file for attachment *)
        if (error >= 0) then
        begin
            error := Write(datei1, Temperaturabschaltwert:30,
                        Prozessvariable1:5:0)
            (* Write constant string and process value *)
            error := Close(datei1)
            (* Close opened file *)
        end
    end

    WriteFile := 0
    logi1 := 0
end

begin
    if (logi1 = 1) then WriteFile
end

Assign

Funktion zum Zuordnen einer Textdatei zu einer Dateivariablen. Assign ordnet der Dateivariablen „File“ die durch Namen angegebene Datei zu. Alle weiteren Operationen mit File beziehen sich so lange auf diese Datei, bis File durch einen weiteren Aufruf von Assign einer anderen externen Datei zugeordnet wird.

Funktionsdefinition: Assign(File : Text, Name : string) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

Name

Name und Pfad der Datei die zu Öffnen ist

Rückgabewerte:

0

wenn Datei zugeordnet wurde

<0

wenn Datei nicht zugeordnet wurde

Beispiel
PROGRAM
var datei1 : text, error : integer

function WriteFile:integer
(* Opens file TEXTDAT.TXT and writes temperature switch-off value = value *)
var i:integer
begin
    error := Assign(datei1,'C:\TMP\TEXTDAT.TXT')
    (* Connect the file to a file variable *)
    if (error >= 0) then
    begin
        error := Append(datei1)
        (* Write constant string and process value *)
        if (error >= 0) then
        begin
            error := Write(datei1, Temperaturabschaltwert:30,
                        Prozessvariable1:5:0)
            (* Konstanten String und Prozesswert schreiben *)
            error := Close(datei1)
            (* Close opened file *)
        end
    end
    WriteFile := 0
    logi1 := 0
end

begin
    if (logi1 = 1) then WriteFile
end

Note

Es können bis max. 20 Assign-Befehle (Zuordnungen) erfolgen.

AssignUnsafe

Die Datei-Zugriffsfunktionen, die mit Assign beginnen sind zu langsam. Grund hierfür ist, dass nach jedem ReadLine die Datei geschlossen und beim nächsten wieder geöffnet wird. Eine Datei mit vielen tausend Zeilen Text benötigt so sehr lange, bis sie eingelesen ist.

AssignUnsafe hält die Datei so lange geöffnet, bis die Datei explizit per Close-Befehl geschlossen wird.

Important

Der Applikateur muss dafür sorgen, dass die Datei auch wirklich geschlossen wird. Es sind keine gleichzeitigen Schreibzugriffe auf eine Datei mehr möglich, wie dies mit Assign der Fall ist.

Die Arbeitsweise von AssignUnsafe ist zu Assign identisch.

Note

Das Erhöhen der „Const Lines“ kann zu einer deutlich höheren Performance führen als das Verwenden von AssignUnsafe.

Funktionsdefinition: AssignUnsafe(File : Text, Name : string) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

Name

Name und Pfad der Datei die zu Öffnen ist

Rückgabewerte:

0

wenn Datei zugeordnet wurde

<0

wenn Datei nicht zugeordnet wurde

BackCopyFiles

Funktion zum Kopieren von Dateien im Hintergrund. Dabei werden zur Aufrufzeit alle angegebenen Dateien erfasst und schrittweise kopiert. Ändert sich die aktuell zu kopierende Datei, so wird diese erneut kopiert, bis eine vollständige Kopie ohne Änderung erfolgt ist. Ist nach n Kopierversuchen die Datei nicht kopiert worden wird diese übersprungen.

Die Kopierfunktion läuft parallel im Hintergrund und muss mittels Statusabfragen kontrolliert werden. Die Kopierfunktion kann nur einmal gleichzeitig im Projekt verwendet werden. Unterordner werden jedoch nicht mitkopiert. Die Nutzung von Wildcards ist möglich. Die Größe der zu übertragenden Teilblöcke wird über den Menüpunkt Konfiguration, [GLOBAL] CopyBufferSize festgelegt.

Funktionsdefinition: BackCopyFiles (Source, Destination : string, Command : integer) : integer

Parameter:

Source

Quelldateinamen mit Wildcards

Destination

Zieldateinamen mit Wildcards

Command

Kommandoparameter:

0 = Dateien kopieren

1 = Kopierstatus abfragen

2 = Fehlercode abfragen

3 = Kopieraktion abbrechen

Rückgabewerte:

Der Funktionswert hat zwei Bedeutungen je nach Kommando

Kommando 0, 1, 3

0

letzte Kopierfunktion richtig beendet

1

Kopierfunktion nicht aktiv

2

Kopierfunktion aktiv

-1

ein Fehler in Kopierfunktion

Kommando 2

0

keine Fehler in Kopierfunktion, sondern in Ereigniscodeparametern

<>0

definierter Fehlercode

Beispiel
PROGRAM
(*------------------------------------------------------*)
(*  Function for outputting the error code if within
    the background copying an error occurred            *)
(*------------------------------------------------------*)
function look_error:integer
begin
    Fehlercode := BackCopyFiles(ap_copy,ap_copy_ziel,2)
    (* Output of the error code *)
End

(*------------------------------------------------------*)
(*  function CopyAlarmsToServer: Copies the
    Alarm file "APTT ????. DBF". For DD the date of
    the previous day used. First is in function
    checked whether the BackCopy command is still
    active. Then the copying is initiated, monitored
    and, finally, is repeatedly checked whether the
    command is available again. The function is
    called cyclically from the main program.            *)
(*------------------------------------------------------*)
function CopyAlarmeZumServer : integer
begin
    CopyAlarmeZumServer := 0
    if Schritt = 0 then
    begin
        Rueckgabe := BackCopyFiles(ap_copy,ap_copy_ziel,1)
        (* Test function active? *)
        if Rueckgabe = -1 then
        begin
            look_error()
            Schritt := 0 (* Function inactive *)
            CopyAlarmeZumServer := 1
            Alert(1,9903)
            KeinServer:=1
        end
        if Rueckgabe = 1 then
        begin
            Schritt := 1 (* Function inactive *)
        end
    end
    else
    begin
        if Schritt = 1 then
        begin
            Rueckgabe := BackCopyFiles(ap_copy,ap_copy_ziel,0)
            (* Copy alarms -> Server *)
            if Rueckgabe = -1 then
            begin
                look_error()
                Schritt := 0 (* Function inactive *)
                CopyAlarmeZumServer := 1
                if (Fehlercode <> 2) then
                begin
                    Alert(1,9903)
                    KeinServer:=1 (* Display "No server" *)
                end
            end
            else
            begin
                Schritt := 2
            end
        end
        else
        begin
            if Schritt = 2 then
            begin
                Rueckgabe := BackCopyFiles(ap_copy,ap_copy_ziel,1)
                (* Test function active? *)
                if Rueckgabe = -1 then
                begin
                    look_error()
                    Schritt := 0 (* Function inactive *)
                    CopyAlarmeZumServer := 1
                    if (Fehlercode <> 2) then
                    begin
                        Alert(1,9903)
                        KeinServer:=1 (* Display "No server" *)
                    end
                end
                else
                begin
                    Schritt := 2
                end
            end
            else
            begin
                if Schritt = 2 then
                begin
                    Rueckgabe :=
                        BackCopyFiles(ap_copy,ap_copy_ziel,1)
                    (* Test function active? *)
                    if Rueckgabe = -1 then
                    begin
                        look_error()
                        Schritt := 0 (* Function inactive *)
                        CopyAlarmeZumServer := 1
                        Alert(1,9903)
                        KeinServer:=1
                    end
                    if Rueckgabe = 0 then
                    (* Copy is complete *)
                    begin
                        Schritt := 3
                    end
                end
                else
                begin
                    if Schritt = 3 then
                        begin
                        Rueckgabe :=
                            BackCopyFiles(ap_copy,ap_copy_ziel,1)
                        (* Test function active? *)
                        if Rueckgabe = -1 then
                        begin
                            look_error()
                            Schritt := 0 (* Function inactive *)
                            CopyAlarmeZumServer := 1
                            Alert(1,9903)
                            KeinServer:=1
                        end
                        if Rueckgabe = 1 then
                        begin
                            Schritt := 0 (* Function inactive *)
                            CopyAlarmeZumServer := 1
                        Alert(2,9903)
                    end
                end
            end
        end
    end
end

BEGIN
    CopyAlarmeZumServer()
END

Close

Funktion zum Schließen einer Textdatei. Die zuvor mit Reset, Rewrite oder Append eröffnete Datei wird auf den neusten Stand gebracht, d.h. noch ungeschriebene Daten werden geschrieben.

Funktionsdefinition: Close(File : Text) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

Rückgabewerte:

0

wenn Datei geschlossen wurde

<0

wenn Datei nicht geschlossen wurde

Beispiel
Program

var datei1 : text
    error : integer

function WriteFile:integer
(* Opens file TEXTDAT.TXT and writes temperature switch-off value = value *)
var i:integer
begin
    error := Assign(datei1,'C:\TMP\TEXTDAT.TXT')
    (* Connect the file to a file variable *)
    if (error >= 0) then
    begin
        error := Append(datei1)
        (* Open the existing file for attachment *)
        if (error >= 0) then
        begin
            error := Write(datei1, Temperaturabschaltwert:30,
                        Prozessvariable1:5:0)
            (* Write constant string and process value *)
            error := Close(datei1)
            (* Close opened file *)
        end
    end
    WriteFile := 0
    logi1 := 0
end

begin
    if (logi1 = 1) then
        WriteFile
end

Note

Die Verbindung zwischen der Dateivariablen und der mit Assign zugeordneten Datei wird nicht aufgehoben.

CopyFiles

Funktion zum Kopieren von Dateien.

Funktionsdefinition: CopyFiles(SourceName, DestName : string) : integer

Parameter:

SourceName

Name der Quelldatei(n) mit Wildcards “*” und “?”

DestName

Name der Zieldatei(n) mit Wildcards “*” und “?”

Rückgabewerte:

>= 0

Anzahl der kopierten Dateien

-1

Allgemeiner Fehler

Beispiel
Program

var ret1 : integer

(*-------------------------------------------------*)
(* Macro to copy all files from directory A to B   *)
(*-------------------------------------------------*)
function macro_06:integer
begin
    ret1 := CopyFiles('C:\BAT\*.*','C:\BAT_SAVE\*.*')
end

(*-------------------------------------------------*)
(* Macro for copying source files to target files  *)
(*-------------------------------------------------*)
function macro_08:integer
begin
    ret1 := CopyFiles(quelle, ziel)
end

begin
end

Note

Die Quell- und Zielverzeichnisse müssen vorhanden sein. Beim Kopieren von großen Datenmengen ist zu beachten, dass keine anderen Aktionen in diesem Moment ablaufen können.

CompareFiles

Funktion zum Vergleichen zweier Dateien auf Größe oder Zeitstempel.

Funktionsdefinition: CompareFiles(StrFile1, StrFile2 : string, Mode : integer, Delta : real) : integer

Parameter:

StrFile1

Dateiname mit vollständiger Pfadangabe

StrFile2

Dateiname mit vollständiger Pfadangabe

Mode

Vergleichsmodus

0 = Dateigrößenvergleich

1 = Zeitvergleich des Erstellungszeitstempels

2 = Zeitvergleich des Änderungszeitstempels

3 = Zeitvergleich des letzten Zugriffszeitstempels (nur bei NTFS)

Delta

Deltafenster für Zeitvergleiche in msec

Rückgabewerte:

-3

ungültige Mode-Angabe

-2

StrFile2 nicht vorhanden

-1

StrFile1 nicht vorhanden

0

beide gleich

1

StrFile1 kleiner oder älter StrFile2

2

StrFile1 größer oder jünger StrFile2

Beispiel
(* Extract from a function that compares source and target and brings both up to date *)

Program
var return : integer

begin
    return := CompareFiles(Quelle,Ziel,0,0.0) (* Compare source and target file size *)
    if return = 0 then (* Source and target the same -> end comparison and copying *)
    begin
        QgleichZ[i] := 1
        Alert(1,2089) (* Message SF = TF -> end comparison *)
        Alert(2,2089)
    end
    else
    if return = -1 then (* SF not available *)
    begin
        return := ExistFile(Ziel) (* SF not there, TF there? *)
        if return = 0 then (* TF is there -> adjustment *)
        begin
            Alert(1,2096) (* SF missing TF there -> adjustment *)
            Alert(2,2096)
            return := CopyFiles(Ziel,Quelle)
            if return < 0 then
            begin
            Alert(1,2069) (* Error during data synchronization *)
            Alert(2,2069)
            end
        end
        else
        begin
            Alert(1,2087) (* Message SF not available *)
            Alert(2,2087)
        end
    end

            Alert(1,2087) (* Message SF not available *)
            Alert(2,2087)
        end
    end
    else
    if return = -2 then (* Target does not exist *)
    begin
        Alert(1,2091) (* Message TF not available *)
        Alert(2,2091)
        return := CopyFiles(Quelle,Ziel)
        if return < 0 then
        begin
            Alert(1,2069) (* Error during data synchronization *)
            Alert(2,2069)
        end
    end
    else
    if return = 1  then (* Compare file there but S < T -> T -> S *)
    begin
        Alert(1,2097) (* Compare message SF <TF -> *)
        Alert(2,2097)
        return := CopyFiles(Ziel,Quelle)
        if return < 0 then
        begin
            Alert(1,2069) (* Error during data synchronization *)
            Alert(2,2069)
        end
    end
    if return = 2  then (* File there but S> T -> synchronize S -> T *)
    begin
        Alert(1,2090) (* Message SF> TF -> compare *)
        Alert(2,2090)
        return := CopyFiles(Quelle,Ziel)
        if return < 0 then
        begin
            Alert(1,2069) (* Error during data synchronization *)
            Alert(2,2069)
        end
    end
    if return = 2  then (* File there but S> T -> synchronize S -> T *)
    begin
        Alert(1,2090) (* Message SF> TF -> compare *)
        Alert(2,2090)
        return := CopyFiles(Quelle,Ziel)
        if return < 0 then
        begin
            Alert(1,2069) (* Error during data synchronization *)
            Alert(2,2069)
        end
    end
end

CreateDir

Funktion zum Erzeugen von Verzeichnissen.

Funktionsdefinition: CreateDir(Name : string) : integer

Parameter:

Name

Name des zu erstellenden Verzeichnisses

Rückgabewerte:

0

wenn Funktion korrekt ausgeführt wurde

< 0

wenn Funktion nicht korrekt ausgeführt wurde

Beispiel
PROGRAM

(*----------------------------------*)
(* Macro to create a file directory *)
(*----------------------------------*)
function macro_11:integer
var error,
    error1 :integer

begin
    error := CreateDir('C:\PROJECT')
    error1 := CreateDir('C:\PROJECT\DATEN')
    if ((error < 0) or (error1 < 0)) then
    begin
        Alert(1,100) (* Alarm: Directory cannot *)
        Alert(2,100) (* be opened *)
    end
end

begin
end

Important

Wenn nur ein Verzeichnis erstellt bzw. ein Verzeichnis an einen bestehenden Pfad angehängt werden soll, dann ist der Befehl nur einmal auszuführen. Will man dagegen einen tiefer gehenden Pfad erstellen, dann ist der Befehl mehrmals hintereinander auszuführen (siehe Beispiel).

DeleteFiles

Funktion zum Löschen von Dateien.

Funktionsdefinition: DeleteFiles(Name : string) : integer

Parameter:

Name

Name der zu löschenden Datei(n) mit Wildcards “*” und “?”

Rückgabewerte:

> 0

Anzahl der gelöschten Dateien

< 0

wenn Löschen Fehler hat

-1

wenn keine Datei zum Löschen gefunden

-2

wenn Datei bei Löschen nicht mehr gefunden

-3

wenn Pfad nicht passt (Quelle oder Ziel)

-4

wenn Datei nicht geöffnet werden kann

-5

wenn keine Zugriffsrechte

weitere Fehler nicht dokumentiert

Beispiel
Program

(*-----------------------------------------------------*)
(*  Delete all ASCII protocols
    The files are as follows in the directory
    C: \ DATEN \ *. * stored: PROTttmm.TXT
    This macro is started by the user                  *)
(*-----------------------------------------------------*)
function macro_12:integer
var error :integer
begin
    error := DeleteFiles('C:\DATEN\PROT????.TXT')
    if (error < 0) then
    begin
        Alert(1,10) (* Error occurred while deleting *)
        Alert(2,10)
    end
end

begin
end

DeleteTree

Funktion zum Löschen von Verzeichnissen mit Inhalt sowie allen Unterverzeichnissen und deren Inhalt.

Funktionsdefinition: DeleteTree(Name : string) : integer

Parameter:

Name

Name des zu löschenden Verzeichnisbaums

Rückgabewerte:

0

wenn Funktion korrekt ausgeführt wurde

< 0

wenn Funktion nicht korrekt ausgeführt wurde

Beispiel
Program

(*----------------------------------------------------------*)
(*  Delete the data directory with all
    subdirectories and their content                        *)
(*----------------------------------------------------------*)
function macro_13:integer
var ret1 : integer

begin
    ret1 := DeleteTree('C:\DATEN')
    (*  "ret1" is a process tag which shows the operator a
        status message                                      *)
end

begin
end

ExistFile

Funktion zum Prüfen ob eine Datei existiert oder nicht.

Funktionsdefinition: ExistFile(StrName : string) : integer

Parameter:

StrName

Dateiname mit vollständiger Pfadangabe

Rückgabewerte:

-3

Laufwerk oder UNC-Name nicht vorhanden

-2

Pfad nicht gültig

-1

Datei nicht vorhanden

0

Datei vorhanden

Beispiel
PROGRAM

VAR return : integer

BEGIN
    return := ExistFile(Ziel)
    if return = 0 then
    begin
        Alert(1, 2096)
        Alert(2, 2096)
END

GetIniString

Funktion zum Auslesen eines Strings aus einer INI-Datei.

Funktionsdefinition: GetIniString(Filename, Section, Key, Default, ReturnString : string) : integer

Parameter:

Filename

Dateiname der Ini-Datei mit Dateiendung und Verzeichnis. Ist kein Verzeichnis angegeben, wird die Datei im Projektverzeichnis gesucht. (Verzeichnis mit Dateiname max. 256 Zeichen)

Section

Section in der Datei (1 bis max. 256 Zeichen); Angabe der Section ohne Klammern

Key

Key in der Datei (1 bis max. 256 Zeichen)

Default

ReturnString wird auf Default gesetzt, wenn ReturnString nicht ermittelbar ist.

ReturnString

Gelesener String

Rückgabewerte:

0

Funktion fehlerfrei ausgeführt

-1

Verzeichnis oder Datei nicht gefunden

-6

Section nicht gesetzt

-7

Key nicht gesetzt

Beispiel
PROGRAM

VAR return : integer

BEGIN
    if GetIniStringStart then
    begin
        return :=  GetIniString(Filename, Section, Key,
                    Default, ReturnString)
        GetIniStringStart := 0
    end
END

MoveFiles

Funktion zum Verschieben von Dateien und Verzeichnissen.

Funktionsdefinition: MoveFiles(SourceName, DestName : string) : integer

Parameter:

SourceName

Name der Quelldatei(n) mit Wildcards “*” und “?”

DestName

Name der Zieldatei(n) mit Wildcards “*” und “?”

Rückgabewerte:

> = 0

Anzahl der verschobenen Dateien, Verzeichnisse

-1

Allgemeiner Fehler

Beispiel
PROGRAM

VAR return : integer

BEGIN
    if StartMoveFiles then
    begin
        StartMoveFiles := 0
        return := MoveFiles(QuellDatei, ZielDatei)
    end
END

Important

Es können keine Verzeichnisse von einem Laufwerk in ein anderes Laufwerk verschoben werden. Dies wird von der Windows API nicht unterstützt! Der Inhalt der Verzeichnisse kann jedoch verschoben werden!

Note

Die Quell- und Zielverzeichnisse müssen vorhanden sein. Beim Verschieben von großen Datenmengen ist zu beachten, dass keine andern Aktionen in diesem Moment ablaufen können.

Read

Funktion zum Lesen von Daten aus einer Text-Datei. Mit der Funktion „Assign“ wird eine Textdatei einer Dateivariablen zugewiesen. Nach dem Öffnen der Datei mit der Funktion „Reset“ kann zeilenweise der Inhalt der Datei gelesen werden, d.h. jeder „Read“ Befehl liest eine Zeile und schaltet dann den Positionszeiger auf die nächste Zeile. Soll wieder vom Anfang der Textdatei gelesen werden, so muss sie geschlossen und neu geöffnet werden. Der Inhalt einer Zeile wird durch die Feldbreite und die Nachkommastellen exakt festgelegt.

Funktionsdefinition: Read(File : Text, v1 [,v2,….,vn]) : integer

Parameter:

File

Dateivariable für Dateizugriff

v1..vn

Variablen für die gelesenen Daten, bis max. 10 Stück

Beispiel: Wert11 := 10

Read(File, Wert11 : 6 : 3) somit gilt allgemein

v1 = Variable [ : Feldbreite [ : Nachkommastellen]]

Rückgabewerte:

0

wenn alles von Datei gelesen wurde

<0

wenn von Datei nicht gelesen werden konnte

Beispiel
Program

var datei1 : text
var error, ausführung_ok :integer

begin
    ausführung_ok := -1 (* Execution control *)
    error := Assign(datei1,'c:\pcsprjct\dde_test\proto.txt')
    if (error >= 0) then
    begin
        error := Reset(datei1)
        if (error >= 0) then
        begin
            error := Read(datei1,Vorgabe_real:10:2,Vorgabe_int:10,
                Vorgabe_string:10,Vorgabe_bool:10)
            if (error >= 0) then
            begin
                error := Close(datei1)
                if (error >= 0) then
                begin
                    ausführung_ok := 0
                end
            end
        end
    end
    if (ausführung_ok < 0) then
    begin
        Alert(1,22) (* Alarm: data cannot be read *)
        Alert(2,22)
    end
end

ReadLine

Liest eine Zeile aus einer Datei und schaltet den Dateipositionszeiger auf die nächste Zeile.

Funktionsdefinition: ReadLine(File : Text, ReturnString : string) : integer

Important

Der Dateivariablen File muss zuvor mit dem Befehl Assign der Dateinamen einer Datei zugeordnet werden (siehe Beispiel)!

Parameter:

File

Dateivariable für Dateizugriff

ReturnString

Ermittelte Zeile

Rückgabewerte:

0

Funktion fehlerfrei ausgeführt

1

Dateiende erreicht

-5

Lesen nicht möglich

Note

Keine Prüfung ob ReturnString zu kurz! Bitte sicherstellen, dass der ReturnString ausreichend groß ist.

Beispiel
Program

var file : Text var error : Integer

BEGIN
    if ReadLineStart then
    begin
        error :=Assign(file,‘C::raw-latex:`\TMP`:raw-latex:`\Test`.TXT’)
        if (error >= 0) then
        begin
            error := ReadLine(file, ReturnString) error := Close(file)
        end
        ReadLineStart := 0
    end
END

Reset

Funktion zum Öffnen einer Text-Datei zu einer Dateivariablen. Die Datei wird nur zum Lesen geöffnet und ist beim Öffnen auf den Anfang der Datei positioniert.

Funktionsdefinition: Reset(File : Text) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

Rückgabewerte:

0

wenn Datei geöffnet wurde

<0

wenn Datei nicht geöffnet wurde

Beispiel
FUNCTION ReadOutputFileValue:integer

var datei:Text
var line:string

BEGIN
        ReadOutputFileValue :=  0

        if (Assign(datei, PFAD) < 0) then
            exit;

        if (Reset(datei) < 0) then
            exit;

        if (ReadLine(datei, line) < 0) then
            exit;

        Close(outputFTPFileText)
END

Rewrite

Funktion zum Öffnen oder Erzeugen einer Text-Datei zu einer Dateivariablen. Existiert die angegebene Datei wird diese vollständig gelöscht und neu angelegt. Rewrite erzeugt eine Datei mit dem bei Assign gewählten Namen.

Funktionsdefinition: Rewrite(File : Text) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

Rückgabewerte:

0

wenn Datei geöffnet wurde

< 0

wenn Datei nicht geöffnet wurde

Beispiel
Program

var datei2 : text
var error, ausführung_ok :integer

begin
    ausführung_ok := -1 (* Execution control *)
    error := Assign(datei2, 'c:\pcsprjct\dde_test\proto.txt')
    if (error >= 0) then
    begin
        error := Rewrite(datei2)
        if (error >= 0) then
        begin
            error := Write(datei2, Vorgabe_real:10:2,
                        Vorgabe_int:10:0, Vorgabe_string:10,
                        Vorgabe_bool:10)
            if (error >= 0) then
            begin
                error := Close(datei2)
                if (error >= 0) then
                begin
                    ausführung_ok := 0
                end
            end
    end
    end
    if (ausführung_ok < 0) then
        begin
        Alert(1,23) (* Alarm: write data error *)
        Alert(2,23)
    end
end

SetIniString

Funktion zum Schreiben eines Strings in eine INI-Datei.

Funktionsdefinition: SetIniString(Filename, Section, Key, StringWert : string) : integer

Parameter:

Filename

Dateiname der Ini-Datei mit Dateiendung und Verzeichnis. Ist kein Verzeichnis angegeben, wird die Datei im Projektverzeichnis gesucht. Ist die Datei nicht vorhanden, wird eine neue angelegt (Verzeichnis mit Dateiname max. 256 Zeichen)

Section

Section in der Datei. Ist die Section nicht vorhanden, wird diese automatisch angelegt (1 bis max. 256 Zeichen); Angabe der Section ohne Klammern

Key

Key in der Datei. Ist der Key nicht vorhanden, so wird dieser automatisch angelegt (1 bis max. 256 Zeichen)

StringWert

String der gesetzt werden soll

Rückgabewerte:

0

Funktion fehlerfrei ausgeführt

-1

Verzeichnis nicht gefunden

-2

Laufwerk nicht gefunden

-3

String nicht ermittelbar

-4

Section nicht korrekt

-5

Key nicht korrekt

Beispiel
PROGRAM

VAR return : integer

BEGIN
    if SetIniStringStart then
    begin
        return := SetIniString(Filename, Section, Key, StringWert)
        SetIniStringStart :=0
    end
END

ValidPath

Funktion zum Prüfen, ob ein Dateipfad gültig ist oder nicht.

Funktionsdefinition: ValidPath(StrName : string) : integer

Parameter:

StrName

Pfadangabe

Rückgabewerte:

0

wenn Pfad auffindbar ist

< 0

wenn Pfad nicht auffindbar ist

Beispiel
PROGRAM

VAR return : integer

BEGIN
    return := ValidPath(Pfad)
END

Write

Funktion zum Schreiben von Daten auf eine Text-Datei zu einer Dateivariablen.

Funktionsdefinition: Write(File : Text, v1 [,v2,….,vn]) : integer

Parameter:

File

Dateivariable für weiteren Dateizugriff

v1..vn

Variablen der zu schreibenden Daten mit Formatangabe max. 10 Stück

Beispiel: Wert11 := 10

Write(File, Wert11 : 6 : 3) führt zum Schreiben von ” 10.000” auf die Datei

somit gilt allgemein v1 = expression [ : Feldbreite [ : Nachkommastellen]]

Rückgabewerte:

0

wenn alles auf die Datei geschrieben wurde

<0

wenn auf die Datei nicht geschrieben werden konnte

Beispiel
Program

var datei2 : text
var error, ausführung_ok :integer

begin
    ausführung_ok := -1 (* Execution control *)
    error := Assign(datei2, 'c:\pcsprjct\dde_test\proto.txt')
    if (error >= 0) then
    begin
        error := Append(datei2)
        if (error >= 0) then
        begin
            error := Write(datei2, Vorgabe_real:10:2,
                    Vorgabe_int:10:0, Vorgabe_string:10,
                    Vorgabe_bool:10)
            if (error >= 0) then
            begin
                error := Close(datei2)
                if (error >= 0) then
                begin
                    ausführung_ok := 0
                end
            end
        end
    end
    if (ausführung_ok < 0) then
    begin
        Alert(1,23) (* Alarm: write data error *)
        Alert(2,23)
    end
End

Datenverwaltungsfunktion

Sehr viele der im folgenden Abschnitt beschriebenen Funktionen stehen auch in Form von Sonderfunktionen (siehe weiter unten in diesem Kapitel) und auf Funktionstasten (siehe Datenverwaltung im Kapitel Daten) zur Verfügung.

DBAccessValue

Diese Funktion dient dazu, auf einzelne Felder eines Datensatzes lesend oder schreibend zuzugreifen. Dadurch können gezielt Einzelbestandteile eines Datensatzes bearbeitet werden, ohne dass jeweils der ganze Datensatz betroffen ist.

Für die Auswahl des Datenfeldes werden zwei Indizes angegeben. Mit Record wird der Index des Datensatzes in der Datenbank und mit Index die Nummer des Feldes innerhalb des Datensatzes adressiert. Wenn man sich eine solche Datenbank als Tabelle vorstellt, so entspricht Record der Zeile und Index der Spalte der Tabelle.

Um diese Funktion sinnvoll einsetzen zu können, muss mit der Funktion DBFieldType der Typ des betroffenen Feldes ermittelt werden. Gemäß des Feldtypes muss dann ein entsprechender Puffer beim Aufruf angegeben werden, in dem die Daten beim Lesen hinterlegt oder beim Schreiben abgeholt werden können. Auf Felder vom Typ CURVEx kann mit dieser Funktion weder lesend noch schreibend zugegriffen werden.

Bei dieser Funktion ist außerdem zu beachten, dass die sechs Standardfelder vom schreibenden Zugriff ausgenommen sind (siehe DBFieldType und DBFieldCount).

Funktionsdefinition: DBAccessValue(DataMgmt: string, Record, Index, Access:integer, Buffer : undef) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Record

Nummer des Datensatzes (Standardspalten beachten!)

Index

Position des Feldes im Datensatz

Index = 0

Datenbankspalte: ‘ID’

Index = 1

Datenbankspalte: ‘Name’

Index = 2

Datenbankspalte: ‘CreatedOn’

Index = 3

Datenbankspalte: ‘CreatedBy’

Index = 4

Datenbankspalte: ‘ChangedOn’

Index = 5

Datenbankspalte: ‘ChangedBy’

Index = 6

Datenbankspalte: ‘Checksum’

Index = 7

Datenbankspalte: ‘Erste Variablen Spalte’

Access

Zugriffsart (1 = Schreiben, 2=Lesen)

Buffer

Puffer für den Wert des zu lesenden oder schreibenden Feldes; dieser Puffer muss dem Feldtyp entsprechen (Realvariable für logische und numerische Prozessvariablen, String für Stringvariable; siehe auch Befehl: DBFieldTyp)

Rückgabewerte:

>= 0

Feldelement bestimmt

-1

Allgemeiner Parametrierfehler

-3

Datenbank ist defekt

-4

zu wenig Hauptspeicher

-5

Record oder Index nicht bekannt

Important

Standardspalten sind bei Datenverwaltungen variabel je nach Headerauswahl. Bei „Standard“ sind es 7 Defaultspalten (6 bei ODBC), bei Auftrag 21, bei „Rezept“ sind es 17 und bei „kein Header (Benutzerdefiniert)“ gibt es keine die dazugerechnet werden müssen.

Beispiel
PROGRAM

function fktDBAccessValue(DataMgmt : string, Record, Index : integer, Buffer : string) : integer

var result : integer
var Access : integer

begin
    Access := 2 (* Access reading *)
    restitution := DBAccessValue(DataMgmt, Record, Index, Access, Buffer)
    fktDBAccessValue := result
end

BEGIN
END

DBCopy

Funktion zum Kopieren von Datensätzen aus einer Datenbank in eine neue, von Struktur und Namen her gleiche, Datenbank in ein anderes Verzeichnis oder Laufwerk. Ist die Datenbank im Zielverzeichnis vorhanden, so wird der Datensatz an die vorhandenen vorangestellt bzw. der vorhandene Datensatz ersetzt.

Funktionsdefinition: DBCopy(DataMgmt, DataRecord, Path: string, Flag: boolean) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

DataRecord

Name des Datensatzes

Path

Pfad für Export oder Import (Datenbankname hier nicht erforderlich)

Flag

lag für Export oder Import des Datensatzes

Export = 1 und Import = 0

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

Beispiel
PROGRAM

function fktDBCopy(DataMgmt, DataRecord, Path : string, Flag : boolean) : integer

begin
    fktDBCopy := DBCopy(DataMgmt, DataRecord, Path, Flag)
end

BEGIN
END

DBCopyIndex

Funktion zum Kopieren eines Datensatzes aus einer Datenbank in eine gleiche Datenbank in einem anderen Verzeichnis oder Laufwerk. Die Angabe des Datensatzes erfolgt über seine Position in der Datenbank.

Funktionsdefinition: DBCopyIndex(DataMgmt, Path : string, Index : integer, Append, Flag : Boolean) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Path

Pfad der Datenbank, in die der Datensatz kopiert werden soll.

Index

Index des Datensatzes in der Quelldatenbank 0..max-1 Datensätze.

Append

Flag für Datensatzappend in Zieldatenbank

1 = Append (Es wird nicht die Indexposition beachtet, sondern auf den nächsten Index angefügt)

0 = Indexposition beachten (Index wird überschrieben; er muss in der Zieldatenbank existieren!)

ExportImport

Flag für Export oder Import des Datensatzes

Export == 1 und Import == 0

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

-1

allgemeiner Parametrierfehler

Beispiel
PROGRAM

function fktDBCopyIndex(DataMgmt, Path : string, Index : integer, DoAppend, Flag : boolean) : integer

begin
    fktDBCopyIndex := DBCopyIndex(DataMgmt, Path, Index, DoAppend, Flag)
end

BEGIN
END

DBDelete

Funktion zum Löschen eines Datensatzes aus einer Datenbank.

Funktionsdefinition: DBDelete(DataMgmt, DataRecord: string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

DataRecord

Name des Datensatzes

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

-1

allgemeiner Parametrierfehler

Beispiel
PROGRAM

function fktDBDelete(DataMgmt, DataRecord : string) : integer

begin
    fktDBDelete := DBDelete(DataMgmt, DataRecord)
end

BEGIN
END

DBDeleteIndex

Funktion zum Löschen eines Datensatzes aus einer Datenbank. Die Angabe des Datensatzes erfolgt über seine Position in der Datenbank. (Erster Datensatz in der Datenbank besitzt die Nummer Null)

Funktionsdefinition: DBDeleteIndex(DataMgmt: string, Index : integer) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Index

Index des Datensatzes in der Datenbank 0..max-1 Datensätze.

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

-1

allgemeiner Parametrierfehler

Funktionswert + 100

Systemalarmnummer

Beispiel
PROGRAM

function fktDBDeleteIndex(DataMgmt : string, Index : integer) : integer

begin
    fktDeleteIndex := DBDeleteIndex(DataMgmt, Index)
end

BEGIN
END

DBFieldCount

Diese Funktion liefert die Anzahl der Felder im Datensatz einer Datenbank. Bei der Anzahl sind auch die sechs Felder miteingeschlossen, die jedem Datensatz automatisch zugeordnet sind (Name des Datensatzes, Erzeugungsdatum, Erzeugungszeit, Änderungsdatum, Änderungszeit, Benutzername der Änderung).

Würde ein Datentyp z.B. nur aus einem vom Benutzer definierten Element bestehen, so wäre der Funktionswert in diesem Fall 7.

Funktionsdefinition: DBFieldCount (Type: string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Rückgabewerte:

> 0

Anzahl der Felder in Datensatzdatei

-1

allgemeiner Parametrierfehler

-2

Datensatz nicht in Datenbank

-3

Datenbank ist defekt

-4

zu wenig Hauptspeicher für die Ausführung

Beispiel
PROGRAM

function fktDBFieldCount(DataMgmt : string) : integer

begin
    fktDBFieldCount := DBFieldCount(DataMgmt)
end


BEGIN
END

DBFieldType

Mit dieser Funktion können die Typen der einzelnen Felder ermittelt werden, um auf die Werte der Felder zugreifen zu können. Bei dieser Funktion werden auch die sechs Felder berücksichtigt, die jedem Datensatz automatisch zugeordnet sind (Name des Datensatzes, Erzeugungsdatum, Erzeugungszeit, Änderungsdatum, Änderungszeit, Benutzername der Änderung).

Die ersten sechs Felder jedes Datentyps sind also fest vergeben:

Feldname

Bedeutung

Typ

NAME

Name des Datensatzes

mit max. 31 Zeichen mit 0 abgeschlossen

CDATE

Erzeugungsdatum

Datumsstring im Format TT.MM.JJJJ

CTIME

Erzeugungszeit

Zeitstring im Format SS.MM.SE (Stunde, Minute, Sekunde)

UPDATE

letztes Änderungsdatum

Datumsstring im Format TT.MM.JJJJ

UPTIME

letzte Änderungszeit

Zeitstring im Format SS.MM.SE (Stunde, Minute, Sekunde)

USER

Benutzername der letzten Änderung

String mit max. 31 Zeichen

Wenn die Funktion DBFieldType erfolgreich ausgeführt werden kann, liefert sie im Parameter Name den Namen und in Ftype den Typ des angegebenen Feldes. Die vom Benutzer angelegten Felder können, die in der folgenden Tabelle gelistete Typen haben (x steht in Feldnamen für einen Spaltenindex).

Feldname

Bedeutung

BOOLx

logische Prozessvariable

REALx

numerische Prozessvariable

STRx

Stringvariable

CURVEx

Kurvenvariable

Funktionsdefinition: DBFieldType(DataMgmt: string, Index:integer, Name: string, Ftype:integer) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Index

Position des Feldes im Datensatz

Name

Puffer für den Feldnamen

Ftype

Typkennung des Feldes mit

$0001 = Datensatzname

$0002 = Erzeugungsdatum

$0003 = Erzeugungszeit

$0004 = Änderungsdatum

$0005 = Änderungszeit

$0006 = Benutzername

$0007 = Textvariable

$0008 = Kurvenvariable

$0101 = logische Prozessvariable

$1001 = numerische Prozessvariable

Rückgabewerte:

>= 0

Feldelement bestimmt

-1

allgemeiner Parametrierfehler

-3

Datenbank ist defekt

-4

zu wenig Hauptspeicher für die Ausführung

-5

Index nicht vorhanden

Beispiel
PROGRAM

function fktDBFieldType(DataMgmt : string, Index : integer, Name : string, Ftype : integer) : integer
begin
    fktDBFieldType := DBFieldType(DataMgmt, Index, Name, Ftype)
    Global_Name    := Name
    Global_Ftype   := Ftype
end

BEGIN
END

DBFindRecord

Mit dieser Funktion wird die angegebene Datenbank nach dem Datensatz mit dem gewünschten Namen durchsucht. Wenn der Datensatz in der Datenbank gefunden wird, so liefert der Returnwert die ID (den Index) des Datensatzes.

Funktionsdefinition: DBFindRecord(DataMgmt, DataRecord: string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

DataRecord

Name des Datensatzes

Rückgabewerte:

>= 0

wenn Funktion erfolgreich ausgeführt wurde, entspricht der Funktionswert der Position des Datensatzes

< 0

wenn Fehler in Funktion aufgetreten ist

-1

allgemeiner Parametrierfehler, kein Datensatz gefunden

-3

Datenbank ist defekt

-4

zu wenig Hauptspeicher für die Ausführung

Beispiel
PROGRAM

function fktDBFindRecord(DataMgmt, DataRecord : string) : integer
begin
    fktDBFindRecord := DBFindRecord(DataMgmt, DataRecord)
end

BEGIN
END

DBReceive / DBSyncReceive / DBReceiveIndex

Prozessvariablen, die in der Datenverwaltung festgelegt wurden, werden als Datensatz in die Datenbank (Festplatte) vom DataServer geschrieben. Hierbei wird vom ScriptServer die im Skript modifizierten Varablen zur Abarbeitung an den DataServer gegeben. Dieser liest die Variablen vom Prozess und schreibt die Werte in die Datenbank. Zur Abarbeitung geht es dann im Skript weiter über den SkriptServer.

Die Funktionen DBReceive und DBSyncReceive arbeiten identisch. Ebenfalls die Funktion DBReceiveIndex, jedoch wird hier anstelle des Namens, mit dem Index des Datensatzes gearbeitet

Funktionsdefinition: DBReceive(DataMgmt, DataRecord: string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

DataRecord

Name/Index des Datensatzes

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

-1

wenn Parametrierfehler

Beispiel
PROGRAM

function fktDBReceive(DataMgmt, DataRecord : string) : integer
begin
    fktDBReceive := DBReceive(DataMgmt, DataRecord)
end

BEGIN
END

DBRecordName

Mit dieser Funktion wird der Name des Datensatzes in der angegebenen Datenbank gelesen, der an der mit „Record“ parametrierten Position steht. Wenn der Datensatz vorhanden ist, so wird der Datensatzname in StrName zurückgeliefert. In diesem Fall entspricht der Funktionswert der Datensatznummer, ansonsten ist er kleiner als Null. Wenn der Wert -1 als Datensatznummer angegeben ist, so liefert diese Funktion die Anzahl der Datensätze der Datenbank als Funktionswert und keinen Datensatznamen in StrName.

Funktionsdefinition: DBRecordName (DataMgmt: string, Record : integer, DataRecord : string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

Record

Nummer des Datensatzes (wenn dieser Wert -1 ist gibt er die Anzahl der Datensätze wieder)

DataRecord

Name des Datensatzes

Rückgabewerte:

>= 0

wenn Funktion erfolgreich ausgeführt wurde entspricht der Funktionswert der Position des Datensatzes

< 0

wenn Fehler in Funktion aufgetreten

-1

allgemeiner Parametrierfehler

-3

Datenbank ist defekt

-4

zu wenig Hauptspeicher für die Ausführung

-5

Record nicht bekannt

Beispiel
PROGRAM

function fktDBRecordName(DataMgmt, DataRecord : string, Index : integer) : integer

var result : integer

begin
    result := DBRecordName(DataMgmt, Index, DataRecord)
    fktDBRecordName := result
end

BEGIN
END

DBSend / DBSyncSend / DBSendIndex

Funktion zum Senden von Datensätzen, welche vorher in der Datenverwaltung defniert wurden, aus der Datenbank in den Prozess.

Prozessvariablen, die in der Datenverwaltung festgelegt wurden, werden als Datensatz in die Datenbank (Festplatte) vom DataServer geschrieben. Hierbei wird vom ScriptServer die im Skript modifizierten Varablen zur Abarbeitung an den DataServer gegeben. Dieser liest die Variablen vom Prozess und schreibt die Werte in die Datenbank. Zur Abarbeitung geht es dann im Skript weiter über den SkriptServer, der die modifizierten Variablen erneut einliest, bevor er weiterarbeitet.

Die Funktionen DBSend und DBSyncSend arbeiten identisch. Ebenfalls die Funktion DBSendIndex, jedoch wird hier anstelle des Namens, mit dem Index des Datensatzes gearbeitet

Funktionsdefinition: DBSend(DataMgmt, DataRecord:string) : integer

Parameter:

DataMgmt

Name der Datenbank bzw. der Datenverwaltung

DataRecord

Name/Index des Datensatzes

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

<> 0

wenn Fehler in Funktion aufgetreten

-1

Allgemeiner Parametrierfehler

Beispiel
PROGRAM

function fktDBSend(DataMgmt, DataRecord : string) : integer

begin
    fktDBSend := DBSend(DataMgmt, DataRecord)
end

BEGIN
END

DBNotifyDataChanged

Funktion um alle Clients (Grids) über eine Änderung der übergebenen Datenverwaltung zu informieren.

Funktionsdefinition: DBNotifyDataChanged(StrType : string) : integer

Parameter:

StrType

Name des Datentyps

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Nach Aufruf werden alle Daten-Grids, die gerade Daten der angegebenen Datenverwaltung anzeigen, aktualisiert indem die fokusierten Daten neu geladen werden. Selektion und Scroll-Position bleiben jedoch erhalten. Rückgabewert 0 wenn ohne Fehler ausgeführt. Kleiner 0 wenn bei der Ausführung ein Fehler aufgetreten ist. Sollte es keine Datenverwaltung mit dem angegebenen Namen geben, wird nichts aktualisiert und 0 zurückgegeben.

Beispiel
PROGRAM

function fktDBNotifyDataChanged(DataMgmt : string) : integer

begin
    fktDBNotifyDataChanged := DBNotifyDataChanged(DataMgmt)
end

BEGIN
END

Important

Das neue Daten-Grid aktualisiert sich automatisch, wenn über Funktionen der Datenverwaltung Datensätze manipuliert, hinzugefügt oder gelöscht werden (z.B. DBReceive). Wird eine Datenverwaltung von Außerhalb oder über ODBC manupuliert bekommt dies das Grid nicht mit.

Chart-/Datenloggerfunktionen (nur SCADA)

DVExportView

Diese Funktion dient dazu, die Daten einer Datenrekorder-Ansicht bezogen auf Charge oder Datum zu exportieren. Der Export geschieht auf der Maschine, auf der der DataServer läuft, entweder in ein per Projekt oder per Aufruf-Parameter festgelegtes Verzeichnis.

Funktionsdefinition: DVExportView(ViewName : string, ChargeName : string, StartTime : real, EndTime : real, FilePath : string)

Parameter:

ViewName

Name der Datenrekorder-Ansicht

ChargeName

Name der Charge

StartTime

Optional: Startzeit in Sekunden seit 01.01.1970; Bei -1 wird Startzeit nicht ausgewertet

EndTime

Optional: Endezeit in Sekunden seit 01.01.1970; Bei -1 wird Endezeit nicht ausgewertet

FilePath

Name der Datei oder Pfad in dem der Export gespeichert werden soll

Rückgabewerte:

>=0

Anzahl exportierter Datensätze wenn Funktion erfolgreich ausgeführt wurde

-1

allgemeiner Parametrierfehler

-2

Name der Datenrekorder-Ansicht ungültig

-3

Datenrekorder für Charge nicht gefunden

-4

Keine Charge oder Daten gefunden

-5

Startzeit ungültig

-6

Endzeit ungültig

Beispiel
PROGRAM

BEGIN
    IF DoExport = 1 THEN
    BEGIN
        DoExport := 0

        retValue := DVExportView('Diag2_Drehzahl', 'Charge01',
                        TimeToAbs(16, 11, 2016, 6, 0, 0),
                        TimeToAbs(16, 11, 2016, 6, 0, 0),
                        'D:\TEMP\Export1.csv')

        retValue := DVExportView('Diag2_Drehzahl', 'Charge02',
                        -1, -1,
                        'D:\TEMP\Export1.csv')
    END
END

Important

Je nach Anzahl der Datensätze kann der Export eine gewisse Zeit in Anspruch nehmen!

Funktionen zur Rezepturverwaltung

Durch die neue Rezeptverwaltung im PROCON-WEB DataServer haben auch neue Funktionen zur Rezeptverwaltung Einzug in das PROCON-WEB Skripting erhalten.

Bei Benutzung der Funktionen der Rezeptverwaltung ist unbedingt das Statemodel der Rezeptverwaltung zu beachten, das hier noch einmal kurz skizziert wird:

Rezeptverwaltung

Important

Version und Name kann nur im Status „Draft“ eines Rezeptes geändert werden.

DBRecipeChangeState

Mit dieser Funktion kann der Status eines Rezepts verändert werden. Abhängig vom aktuellen Status des Rezepts können nur bestimmte Folgestatus gesetzt werden.

Mögliche Rezeptstatus:

  • Draft = 1,

  • Released = 2,

  • Deleted = 4,

  • Locked = 8,

  • InUse = 16

Funktionsdefinition: DBRecipeChangeState(StrType, StrName : string, State : integer) : integer

Parameter:

StrType

Name des Rezeptdatentyps

StrName

Name des Datensatzes in der Datenbank

State

Neuer Status des Rezepts

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-3

Statusänderung nicht erlaubt (falscher State)

-4

unbekannter Status

-5

Datensatz nicht gefunden

Beispiel
PROGRAM

function setRecipeStateDraft(StrType, StrName : string) : integer
var State: integer

begin
    State := 1
    setRecipeStateDraft := DBRecipeChangeState(StrType, StrName, State)
end


function setRecipeStateLocked(StrType, StrName : string) : integer
var State: integer

begin
    State := 8
    setRecipeStateLocked := DBRecipeChangeState(StrType, StrName, State)
end


BEGIN
END

DBRecipeChangeStateIndex

Mit dieser Funktion kann der Status eines Rezepts verändert werden. Abhängig vom aktuellen Status des Rezepts können nur bestimmte Folgestatus gesetzt werden.

Mögliche Rezeptstatus:

  • Draft = 1,

  • Released = 2,

  • Deleted = 4,

  • Locked = 8,

  • InUse = 16

Funktionsdefinition: DBRecipeChangeStateIndex(StrType : string, Index : integer, State : integer) : integer

Parameter:

StrType

Name des Rezeptdatentyps

Index

Index des Datensatzes in der Datenbank

State

Neuer Status des Rezepts

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-3

Statusänderung nicht erlaubt (falscher State)

-4

unbekannter Status

-5

Datensatz nicht gefunden

Beispiel
PROGRAM

function setRecipeStateDraft(StrType : string, Index : integer) : integer
var State: integer

begin
    State := 1
    setRecipeStateDraft := DBRecipeChangeStateIndex(StrType, Index, State)
end


function setRecipeStateLocked(StrType : string, Index : integer) : integer
var State: integer

begin
    State := 8
    setRecipeStateLocked := DBRecipeChangeStateIndex(StrType, Index, State)
end


BEGIN
END

DBRecipeChangeVersion

Funktionen zum Ändern der Rezeptversion. Die Rezeptversion kann nur um das angegebene Delta erhöht werden. Der Parameter versionpart gibt dabei an, welcher Teil der Version erhöht wird.

Mögliche Versionselemente (Aufbau der Versionsnummer ist: Major.Minor.Build):

  • Build = 0

  • Minor = 1

  • Major = 2

Funktionsdefinition: DBRecipeChangeVersion(StrType, StrName : string, Versionpart, Delta : integer) : integer

Parameter:

StrType

Name des Rezeptdatentyps

StrName

Name des Datensatzes in der Datenbank

Versionpart

Teil der Versionsnummer, der erhöht werden soll

Delta

Wert, um den die Versionsnummer erhöht wird

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-3

Version existiert bereits

-4

Version existiert bereits

-5

Datensatz nicht gefunden

Beispiel
PROGRAM
(*  To increase the main version of a recipe from version 1.0.3 to 2.0.3,
    Major (2) must be increased by a delta of 1:                          *)

var result : integer
var StrType, StrName : string

BEGIN
    result := DBRecipeChangeVersion(StrType, StrName, 2, 1)
    if result < 0 then
    begin
        Alert(1,4711)
    end
END

DBRecipeChangeVersionIndex

Funktionen zum Ändern der Rezeptversion. Die Rezeptversion kann nur um das angegebene Delta erhöht werden. Der Parameter versionpart gibt dabei an, welcher Teil der Version erhöht wird.

Mögliche Versionselemente (Aufbau der Versionsnummer ist: Major.Minor.Build):

  • Build = 0

  • Minor = 1

  • Major = 2

Funktionsdefinition: DBRecipeChangeVersionIndex(StrType : string, Index, versionpart, delta : integer): integer

Parameter:

StrType

Name des Rezeptdatentyps

Index

Index des Datensatzes in der Datenbank

Versionpart

Teil der Versionsnummer, der erhöht werden soll

Delta

Wert, um den die Versionsnummer erhöht wird

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-3

Version existiert bereits

-4

Version existiert bereits

-5

Datensatz nicht gefunden

Beispiel
PROGRAM
(*  To increase the main version of a recipe from version 1.0.3 to 2.0.3,
    Major (2) must be increased by a delta of 1:                          *)

var result, Index : integer
var StrType : string
BEGIN
    result := DBRecipeChangeVersionIndex(StrType, Index, 2, 1)
    if result < 0 then
    begin
        Alert(1,4711)
    end
END

DBRecipeChangeName

Funktionen zum Ändern des Rezeptnamens.

Funktionsdefinition: DBRecipeChangeName(StrType, StrName, Name : string) : integer

Parameter:

StrType

Name des Rezeptdatentyps

StrName

Name des Datensatzes in der Datenbank

Name

Neuer Name des Rezepts

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-5

Datensatz nicht gefunden

Beispiel
PROGRAM

var result : integer
var StrType, StrName : string

BEGIN
    result := DBRecipeChangeName(StrType, StrName, 'Neuer Name')
    if result < 0 then
    begin
        Alert(1,4711)
    end
END

DBRecipeChangeNameIndex

Funktionen zum Ändern des Rezeptnamens.

Funktionsdefinition: DBRecipeChangeNameIndex(StrType : string, Index : integer, Name : string) : integer

Parameter:

StrType

Name des Rezeptdatentyps

Index

Index des Datensatzes in der Datenbank

Name

Neuer Name des Rezepts

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Typ nicht gefunden

-2

Typ ist kein Rezepttyp

-5

Datensatz nicht gefunden

Beispiel
PROGRAM

var result, Index : integer
var StrType : string

BEGIN
    result := DBRecipeChangeNameIndex(StrType, Index, 'Neuer Name')
    if result < 0 then
    begin
        Alert(1,4711)
    end
END

Funktionen der ODBC-Schnittstelle (nur SCADA)

Die Open Database Connectivitiy-Schnittstelle erweitert den Leistungsumfang der PROCON-WEB Formeln um die Möglichkeit, auf interne und externe Datenbanken zuzugreifen. Dabei ist nicht das Format der Datenbank bzw. der in der Datenbank verwendeten Dateiformate ausschlaggebend, sondern die Verfügbarkeit eines ODBC-Treibers.

Um diese Schnittstelle in den Formeln einsetzen zu können, muss zunächst ODBC selber im Betriebssystem (Systemsteuerung) installiert sein. Wenn eine externe Datenbank angesprochen werden soll, so muss auch diese korrekt installiert sein. Bei der ODBC-Installation müssen die Treiber eingerichtet sein, mit denen in den PROCON-WEB Formeln gearbeitet werden soll. Für die Verwendung der internen Datenbanken muss z.B. ein dBase-Treiber definiert werden. Die Einrichtung eines ODBC-Treibers beinhaltet die Zuordnung der Zieldatenbank sowie die Vergabe von Zugriffsnamen und Passwörtern.

Die Leistungsfähigkeit sowie der Funktionsumfang der ODBC-Schnittstelle hängen vom eingesetzten ODBC-Treiber ab. Bei der Verwendung der Formeln für die ODBC-Schnittstelle ist daher der Leistungumfang des eingesetzten Treibers anhand der entsprechenden Dokumentation zu prüfen.

Das Funktionsprinzip der ODBC-Schnittstelle basiert jedoch im Allgemeinen auf gleiche Mechanismen. Zunächst muss die Verbindung zum ODBC-Treiber hergestellt werden (Funktion DBOpenODBC). Dazu wird der Name eingesetzt, der bei der Treiberinstallation vergeben wurde. Wenn dies erfolgreich durchgeführt wurde, so wird für diese Verbindung ein sog. Handle geliefert, über das alle weiteren Aktionen adressiert werden. Gleichzeitig können maximal zwanzig derartige Verbindungen benutzt werden.

Auf einer geöffneten Verbindung wird dann mittels einer SQL-Anweisung eine Selektion („Select-Anweisung“) auf der Datenbank ausgeführt (DBSendSQLODBC). Mit dieser Anweisung wird, aus der über den Treiber hergestellten Datenbank-Verbindung, eine Teilmenge („Tabelle“) aus der Datenbank oder die gesamte Datenbank ausgewählt. Für die Selektierung wird ein String verwendet, in dem die Art der Selektierung mit einer vorgegebenen SQL-Grammatik beschrieben wird.

Neben der Selektion mit dem SQL-Befehl SELECT können auch Datensätze mit den SQL-Befehlen INSERT und DELETE direkt in der Datenbank eingefügt oder gelöscht werden.

Die unterschiedlichen ODBC-Treiber erlauben die SQL-Grammatik in den unterschiedlichen Ausbaustufen zu verwenden. Sie unterstützen jedoch zumindest die Minimalgrammatik.

Die über die Selektierung erzeugte Tabelle ist dann die Ausgangsbasis für die weiteren Operationen. Auf ihr können Informations-, Lese- und Schreibfunktionen ausgeführt werden (DBFetchTabODBC, DBGetDataODBC, DBPutDataODBC, DBGetErrorODBC, DBGetInfoTabODBC, DBGetInfoDataODBC). Je nach Typ des ODBC-Treibers gibt es darüber hinaus noch die Möglichkeit, ODBC-Prozeduren auszuführen (DBProcedureODBC). ODBC-Prozeduren können komplette SQL-Sequenzen enthalten und vereinfachen standardisierte oder stereotype Aktionen auf Datenbanken erheblich.

Wenn die Verbindung zum ODBC-Treiber nicht mehr benötigt wird, so ist sie wieder zu schließen (DBCloseODBC). Aus Sicherheitsgründen wurde die ODBC-Schnittstelle in den Formeln so implementiert, dass beim Beenden des ausgeführten Ereigniscodes die Verbindung zum ODBC-Treiber und somit zur Datenbank automatisch geschlossen wird. Dies betrifft zum Beispiel ODBC-Aktivitäten in einem Bildereigniscode.

DBOpenODBC

Mit dieser Funktion wird die Verbindung zum ODBC-Treiber hergestellt. Sie muss als erste Funktion ausgeführt werden, da bei erfolgreicher Ausführung das Handle als Datenbankschlüssel zurückgeliefert wird, das dann beim Aufruf der anderen ODBC-Funktionen als Parameter einzusetzen ist.

Bei dieser Funktion wird der gewünschte ODBC-Treiber über seinen Namen parametriert. Wenn bei der Einrichtung dieses Treibers Benutzernamen und Passwörter vergeben wurden, so sind diese beim Öffnen der Verbindung ebenfalls anzugeben. Es können gleichzeitig maximal 20 ODBC-Verbindungen offen sein.

Funktionsdefinition: DBOpenODBC (ODBCDriver, User, Password : string) : integer

Parameter:

ODBCDriver

Name des ODBC-Treibers (max. 255 Zeichen )

User

Name des Benutzers (max. 255 Zeichen )

Password

Passwort des Benutzers (max. 255 Zeichen )

Rückgabewerte:

0..19

Schlüssel auf Datenbank für weiteren Datenbankzugriff

-1

kein freies Handle mehr

-2

Speichermangel

-3

Fehler von ODBC-Treiber

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBOpenODBCConnection

Mit dieser Funktion wird die Verbindung zu einer ODBC-Datenquelle hergestellt. Die ODBC-Datenquelle ist vorher im Designer zu definieren.

Dies muss als erste Funktion ausgeführt werden, da bei erfolgreicher Ausführung das Handle als Datenbankschlüssel zurückgeliefert wird, das dann beim Aufruf der anderen ODBC-Funktionen als Parameter einzusetzen ist.

Bei dieser Funktion wird der gewünschte ODBC- Datenquelle über ihren Namen parametriert. Es können gleichzeitig maximal 20 ODBC-Verbindungen offen sein.

Funktionsdefinition: DBOpenODBCConnection (ConnectionName : string) : integer

Parameter:

ConnectionName

Name der im Designer definierten ODBC-Datenquelle (max. 255 Zeichen )

Rückgabewerte:

0..19

Schlüssel auf Datenbank für weiteren Datenbankzugriff

-1

kein freies Handle mehr

-2

Speichermangel

-3

Fehler von ODBC-Treiber

-4

ODBC-Datenquelle nicht gefunden

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBCConnection('SQL_ODBC')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBCloseODBC

Die Verbindung zum angegebenen ODBC-Treiber wird geschlossen.

Diese Funktion sollte immer ausgeführt werden, wenn eine Verbindung nicht mehr benötigt wird. Dadurch werden belegte Ressourcen wieder freigemacht. Wenn diese Funktion nicht aufgerufen wird, so schließt die Laufzeit die Verbindungen beim Verlassen des betroffenen Ereigniscodes automatisch.

Die Verbindung wird über das Verbindungs-Handle parametrisiert.

Funktionsdefinition: DBCloseODBC (ODBCHandle : integer) : integer

Parameter:

ODBCHandle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBSendSQLODBC

Diese Funktion führt eine SQL-Anweisung auf einer geöffneten Verbindung aus.

SQL-SELECT - Anweisung: Sie muss aufgerufen werden, bevor die eigentlichen Zugriffsfunktionen auf die Datenbanktabelle benutzt werden können. Alle weiteren ODBC-Funktionen werden dann auf den über diese Anweisung selektierten Daten durchgeführt.

SQL-INSERT und SQL-DELETE-Anweisung: Mit diesen Anweisungen werden Datensätze in der Datenbank eingefügt oder gelöscht.

Die Verbindung zum ODBC-Treiber muss geöffnet sein. Der angegebene SQL-String muss der SQL-Grammatik des angeschlossenen ODBC-Treibers genügen.

Funktionsdefinition: DBSendSQLODBC (ODBCHandle : integer, SQL : string) : integer

Parameter:

ODBCHandle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

SQL

SQL-Anweisung (bis max. 4000 Zeichen )

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBProcedureODBC

Mit dieser Funktion wird eine ODBC-Prozedur ausgeführt. Voraussetzung dafür ist, dass zum einen die Verbindung zum Treiber hergestellt ist und dass zum anderen der betroffene ODBC-Treiber diese Möglichkeit überhaupt unterstützt.

Die Prozedur muss auch in der Datenbank unter dem angegebenen Namen angelegt sein. Weitere Informationen zu diesem Thema sind in der Dokumentation zum ODBC-Datenbankserver zu finden.

Funktionsdefinition: DBProcedureODBC (ODBCHandle : integer, Proc : string) : integer

Parameter:

ODBCHandle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

Proc

Name der auszuführenden Prozedur (max. 255 Zeichen )

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-6

die Datenbank kann keine Prozeduren ausführen

Beispiel
PROGRAM

(*-------------------------------------------------------------*)
(* ODBC example for executing a database procedure             *)
(*-------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer (*----- function return value -----------*)
var handle: (*----- connection handle -------------*)

begin
(*----- Open the connection to the ODBC driver named ACC -*)
    handle := DBOpenODBC('ACC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBProcedureODBC(handle,'Del_all')

(*----- Error handling -------------------------------------- *)
        if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
            ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBFetchTabODBC

Mit dieser Funktion wird ein Datensatz aus der selektierten Menge in einen internen Puffer geladen. Dort steht er dann für die weitere Verarbeitung zur Verfügung. Der Datensatz wird über den Parameter „Pos“ ausgewählt. Dabei wird immer relativ zu den vorangegangenen Aktionen positioniert oder direkt an den Anfang oder das Ende der selektierten Datensätze.

Mit dem tabellenorientierten Modell der ausgewählten Datensatzmenge wird über diese Funktion eine Zeile der Tabelle zur Bearbeitung vorbereitet. Die Verbindung zum ODBC-Treiber muss geöffnet sein.

Funktionsdefinition: DBFetchTabODBC (ODBCHandle, Pos : integer) : integer

Parameter:

ODBCHandle

Verbindungs-Handle zum ODBC-Treiber (0 … 19)

Pos

Position des Datensatzes in der selektierten Menge; es sind nur folgende Angaben erlaubt:

0 = nächsten Datensatz in der Tabelle

1 = vorangegangener Datensatz

2 = erster Datensatz

3 = letzter Datensatz

während 0 bei allen ODBC-Treibern erlaubt ist, gelten die anderen Werte nur bei einigen.

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-4

keine Daten mehr verfügbar

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBGetDataODBC

Wenn ein Datensatz mit der Funktion DBFetchTabODBC in den internen Bearbeitungspuffer geladen ist, so kann auf die Datenelemente dieses Datensatzes mit dieser Funktion lesend zugegriffen werden. Mit Pos wird das Element (Spalte) innerhalb des Datensatzes ausgewählt.

Der Wert der ausgewählten Spalte wird im angegebenen Puffer zur Verfügung gestellt. Der Puffer muss dem Typ des Eintrages entsprechen. Daher ist zuerst der Typ mit der Funktion DBGetInfoDataODBC festzustellen. Die Funktion DBGetDataODBC kann auf Elemente der Typen String, logisch oder numerisch angewendet werden. Die Verbindung zum ODBC-Treiber muss geöffnet sein.

Funktionsdefinition: DBGetDataODBC (ODBCHandle, Pos : integer, Buffer : undef) : integer

Parameter:

ODBC-Handle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

Pos

Nummer des gewünschten Elementes (Spaltennummer)

Buffer

Puffer für die Übername des Elementinhaltes; er muss mit dem Typ des Elementes übereinstimmen (s. DBGetInfoDataODBC)

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-4

keine Daten mehr vorhanden

-5

falsche Datentypen

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBPutDataODBC

Mit dieser Funktion können Elemente eines Datensatzes verändert werden. Der zu bearbeitende Datensatz ist vorher mit der Funktion DBFetchTabODBC zuerst in den internen Puffer zu laden. Mit dem Parameter Pos wird das Element des Datensatzes, also die Spalte adressiert.

Der Wert für die ausgewählte Spalte muss im angegebenen Puffer bereitgestellt sein. Der Puffer muss dem Typ des Eintrages entsprechen. Daher ist der Typ mit der Funktion DBGetInfoDataODBC vorher erst festzustellen. Die Funktion DBPutDataODBC kann auf Elemente der Typen String, logisch oder numerisch angewendet werden.

Important

Der DBPutDataODBC-Befehl funktioniert für Datenbanken im Excel Format nicht.

Die Verbindung zum ODBC-Treiber muss geöffnet sein.

Funktionsdefinition: DBPutDataODBC (ODBCHandle, Pos : integer, Buffer : undef) : integer

Parameter:

ODBC-Handle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

Pos

Nummer des gewünschten Elementes (Spaltennummer)

Buffer

Puffer für die Übergabe des Elementinhaltes; er muss mit dem Typ des Elementes übereinstimmen (s. DBGetInfoDataODBC)

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-4

keine Daten mehr vorhanden

-5

falsche Datentypen

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBGetStampODBC

Wenn ein Datensatz mit der Funktion DBFetchTabODBC in den internen Bearbeitungspuffer geladen ist, so kann mit dieser Funktion auf ein Datenelement dieses Datensatzes, das vom Typ „Datumsstempel“ ist, lesend zugegriffen werden. Mit Pos wird das Element (Spalte) innerhalb des Datensatzes ausgewählt.

Da es sich beim Typ „Datumsstempel“ um sechs Einzelwerte handelt, werden für die Übernahme der Werte auch sechs Variablenangaben benötigt. Ob ein Datenelement von diesem Typ ist, ist mit der Funktion DBGetInfoDataODBC festzustellen.

Die Verbindung zum ODBC-Treiber muss geöffnet sein.

Funktionsdefinition: DBGetStampODBC (ODBCHandle, Pos, Hour, Min, Sec, Day, Month, Year : integer) : integer

Parameter:

ODBC-Handle

Verbindungs-Handle zum ODBC-Treiber (0 . 19)

Pos

Nummer des gewünschten Elementes (Spaltennummer)

Hour

Puffer für Stundenwert

Min

Puffer für Minutenwert

Sec

Puffer für Sekundenwert

Day

Puffer für Tageswert

Month

Puffer für Monatswert

Year

Puffer für Jahreswert

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-4

keine Daten mehr vorhanden

Beispiel
PROGRAM

(*----------------------------------------------------------------------*)
(* ODBC example for reading out the creationdate from the yoghurt table *)
(* and transferred to the update date of the strawberry data set        *)
(*----------------------------------------------------------------------*)
function ODBC_BSP : integer

var ret :integer        (*-- function return value --*)
var act :integer        (*-- connection handle ------*)
var hour :integer       (*-- Hour -------------------*)
var min :integer        (*-- minute -----------------*)
var sec :integer        (*-- second -----------------*)
var mon :integer        (*-- month ------------------*)
var day :integer        (*-- Day --------------------*)
var year :integer       (*-- Year -------------------*)
var sp_typ :integer     (*-- column type ------------*)
var rinse :integer      (*-- column length ----------*)
var sp_name     :string     (*-- column name ------------*)


begin
(*-- Open the connection to the ODBC driver with the name SQL_ODBC --*)
    handle := DBOpenODBC('SQL_ODBC', '', '')
    if (handle >= 0) then
    begin
(*-- loading the first line from the table --*)
        ret := DBFetchTabODBC(handle, 0)
        if(ret = 0) then
        begin
(*-- Determine the column type of the 2nd column --*)
            ret := DBGetInfoDataODBC(handle, 2, sp_name, sp_typ, sp_len)
            if(ret = 0) AND (sp_typ = 4) then
            begin
(*-- Enter the date from the second column (CDATE) in the variables --*)
                ret := DBGetStampODBC(handle, 2, hour, min, sec, day,
                        mon, year)
                if(ret = 0) then
                begin
(*-- Date transferred to fourth column (UPDATE) of the table --*)
                ret := DBPutStampODBC(handle, 4, hour, min, sec,
                        day, mon, year)
                end
            end
        end
    end

(*-- Error handling --------------------------------------*)
    if(ret = -3) then
    begin
(*-- Get driver error information ----------------------*)
        ret := DBGetErrorODBC(mess, status)
    end
(*-- Enable ODBC driver connection ----------------------*)
    ret := DBCloseODBC(handle)
end

BEGIN
    ODBC_BSP
END

DBPutStampODBC

Mit dieser Funktion kann ein Datumseintrag in einem Datensatzelement überschrieben werden. Dazu ist der Datensatz mit der Funktion DBFetchTabODBC in den internen Bearbeitungspuffer zu laden. Mit Pos wird das Element (Spalte) innerhalb des Datensatzes ausgewählt.

Da es sich beim Typ „Datumsstempel“ um sechs Einzelwerte handelt, werden für die Übergabe der Werte auch sechs Parameter benötgt. Ob ein Datenelement von diesem Typ ist, ist mit der Funktion DBGetInfoDataODBC festzustellen. Die Verbindung zum ODBC-Treiber muss geöffnet sein.

Funktionsdefinition: DBPutStampODBC (ODBCHandle, Pos, Hour, Min, Sec, Day, Month, Year : integer) : integer

Parameter:

ODBCHandle

Verbindungs-Handle zum ODBC-Treiber (0 … 19)

Pos

Nummer des gewünschten Elementes (Spaltennummer)

Hour

Stundenwert

Min

Minutenwert

Sec

Sekundenwert

Day

Tageswert

Month

Monatswert

Year

Jahreswert

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

-4

keine Daten mehr vorhanden

-5

falsche Datentypen

Beispiel
PROGRAM

(*----------------------------------------------------------------------*)
(* ODBC example for reading out the creationdate from the yoghurt table *)
(* and transferred to the update date of the strawberry data set        *)
(*----------------------------------------------------------------------*)
function ODBC_BSP : integer

var ret :integer        (*-- function return value --*)
var act :integer        (*-- connection handle ------*)
var hour :integer       (*-- Hour -------------------*)
var min :integer        (*-- minute -----------------*)
var sec :integer        (*-- second -----------------*)
var mon :integer        (*-- month ------------------*)
var day :integer        (*-- Day --------------------*)
var year :integer       (*-- Year -------------------*)
var sp_typ :integer     (*-- column type ------------*)
var rinse :integer      (*-- column length ----------*)
var sp_name     :string     (*-- column name ------------*)


begin
(*-- Open the connection to the ODBC driver with the name SQL_ODBC --*)
    handle := DBOpenODBC('SQL_ODBC', '', '')
    if (handle >= 0) then
    begin
(*-- loading the first line from the table --*)
        ret := DBFetchTabODBC(handle, 0)
        if(ret = 0) then
        begin
(*-- Determine the column type of the 2nd column --*)
            ret := DBGetInfoDataODBC(handle, 2, sp_name, sp_typ, sp_len)
            if(ret = 0) AND (sp_typ = 4) then
            begin
(*-- Enter the date from the second column (CDATE) in the variables --*)
                ret := DBGetStampODBC(handle, 2, hour, min, sec, day,
                        mon, year)
                if(ret = 0) then
                begin
(*-- Date transferred to fourth column (UPDATE) of the table --*)
                ret := DBPutStampODBC(handle, 4, hour, min, sec,
                        day, mon, year)
                end
            end
        end
    end

(*-- Error handling --------------------------------------*)
    if(ret = -3) then
    begin
(*-- Get driver error information ----------------------*)
        ret := DBGetErrorODBC(mess, status)
    end
(*-- Enable ODBC driver connection ----------------------*)
    ret := DBCloseODBC(handle)
end

BEGIN
    ODBC_BSP
END

DBGetInfoTabODBC

Mit dieser Funktion kann man sich über die Anzahl der Zeilen und Spalten, also die Anzahl der Datensätze und der Datenelemente informieren. Diese Funktion wird auf die mit der Funktion DBSendSQLODBC selektierten Tabelle angewandt. Die Verbindung zum ODBC-Treiber muss geöffnet und die Selektierung durchgeführt worden sein.

Note

Nach Ausführung dieser Funktion steht die Fetch-Position der Funktion DBFetchTabODBC() wieder am Anfang der Tabelle

Funktionsdefinition: DBGetInfoTabODBC (ODBCHandle, Rec, Col : integer) : integer

Parameter:

ODBC-Handle

Verbindungs-Handle zum ODBC-Treiber (0 … 19)

Rec

Puffer für die Übername der Anzahl der Zeilen (Datensätze bzw. Records)

Col

Puffer für dir Übernahme der Anzahl der Spalten (Anzahl der Datenelemente in einem Datensatz bzw. Record)

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBGetInfoDataODBC

Diese Funktion liefert Informationen über den Typ und die Länge einer Spalte in der selektierten Tabelle. Es wird hier also die Struktur eines Datensatzelementes beschrieben. Die hiermit beschafften Informationen sind notwendig, um lesend bzw. schreibend auf die Einzelelemente der Datensätze zugreifen zu können, da bei den Zugriffsfunktionen typkonforme Parameter anzugeben sind.

Die Verbindung zum ODBC-Treiber muss geöffnet und die Selektierug durchgeführt worden sein.

Funktionsdefinition: DBGetInfoDataODBC (ODBCHandle, Pos: integer, name: string, len: integer): integer

Parameter:

ODBC-Handle

Verbindungs-Handle zum ODBC-Treiber (0 … 19)

Pos

Spaltenindex des gewünschten Datenelementes (beginnt bei 1)

Spaltenname

Name der Datenbankspalte

Type

Puffer für die Übernahme des Spaltentyps

1 =

Varbinary (Checksumme von PROCON-WEB Standard Spalten)

2 =

Bool Element

3 =

numerisches Element

4 =

Datumsstempel

5 =

String

Len

Puffer für die Übernahme der Spaltenbreite

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Falscher Datenbankzugriffsschlüssel

-3

Fehler von ODBC-Treiber

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

DBGetErrorODBC

Wenn eine der ODBC-Funktionen als Funktionswert den Wert -3, also Fehler aus dem ODBC-Treiber gemeldet hat, so kann mit dieser Funktion der zugehörige Fehlertext von dem ODBC-Treiber abgeholt werden. Dabei ist jeweils ein Puffer für einen Meldungs- und einen Statustext anzugeben. Die Texte können bis zu 255 Zeichen lang sein, d.h. die Puffer müssen auf die entsprechende Größe angelegt worden sein.

Funktionsdefinition: DBGetErrorODBC (Message, State:string) : integer

Parameter:

Message

Puffer für Meldungstext (255 Zeichen)

State

Puffer für Statustext (255 Zeichen

Rückgabewerte:

0

Funktion erfolgreich ausgeführt

-1

Stringpuffer nicht verfügbar

Beispiel
PROGRAM

(*---------------------------------------------------------------*)
(* ODBC example for reading out the 7th value from table yoghurt *)
(* for the strawberry data set and setting the 8th value so      *)
(*---------------------------------------------------------------*)
function ODBC_BSP:integer

var ret:integer    (*----- function return value ----------------*)
var handle:integer (*----- connection handle --------------------*)
var rec:integer    (*----- number of rows in the table ----------*)
var col:integer    (*----- number of columns in the table -------*)

begin
(*----- Open the connection to the ODBC driver with the name SQL_ODBC -*)
    handle := DBOpenODBC('SQL_ODBC','','')
    if (handle >= 0) then
    begin
(*----- select table with one line and two columns -*)
        ret := DBSendSQLODBC(handle, 'SELECT REAL7, REAL8 from joghurt
                            where NAME = ''Erdbeer''')
        if(ret = 0) then
        begin
(*----- Load the first line from the table ----------------*)
            ret := DBFetchTabODBC(handle, 0)
            if(ret = 0) then
            begin
(*----- Determine number of rows and columns in the table ------- *)
                ret := DBGetInfoTabODBC(handle, rec, col)
                if(ret = 0) then
                begin
(*----- Read the value of the first column (REAL7) into the variable value *)
                    ret := DBGetDataODBC(handle, 1, wert)
                    if(ret = 0) then
                    begin
(*----- Enter the tag value in the second column (REAL8) of the table *)
                        ret := DBPutDataODBC(handle, 2, wert)
                    end
                end
            end
        end

(*----- Error handling --------------------------------------*)
                if(ret = -3) then
        begin
(*----- Get driver error information ----------------------*)
            ret := DBGetErrorODBC(mess, status)
        end
(*----- Enable ODBC driver connection ----------------------*)
        ret := DBCloseODBC(handle)
    end
end

BEGIN
    ODBC_BSP
END

Stringverarbeitungsfunktion

Umgang mit Textvariablen (Strings) im Eventcode.

PROCON-WEB unterscheidet zwei Textvariablentypen, die eventlokalen (Variablentyp: string) und die globalen Textvariablen aus der Bildmontage.

Lokale Textvariablen haben einen begrenzten Gültigkeitsbereich z.B. nur in der Makrodatei, im Global Event oder in der jeweiligen Bildformel (Pictevent).

Globale Textvariablen sind hingegen, wie der Name schon sagt, überall im Projekt gültig.

Neben Eventfunktionen (Length, Pos, Str und Val, siehe weiter unten in diesem Kapitel) können Textvariablen auf folgende Weise editiert werden:

Editieren einzelner Buchstaben einer globalen Textvariablen: Wenn zu einer Textvariablen ein Prozessvariablenfeld zugeordnet ist (siehe Kapitel Text dynamisieren), so kann im Formelinterpreter jeder Buchstabe einzeln editiert werden. Das Feldelement „0“ beinhaltet den ASCII-Wert des ersten, das Feldelement „n-1“ den ASCII-Wert des letzten Buchstabens. Im „n-ten “ Feldelement muss die „0“ als Stringendekennung stehen.

Beispiel
(*--------------------------------------------------------------------------------------*)
(*  The current date is to be written in a text variable in the format "ddmmyyyy".
    A process tag field "Date field []" is assigned to the text tag.
    The following calculation is based on the ASCII table. The numbers in
    the ASCII table begin with 48 (decimal “0”) and end with 57 (decimal 9).
    Each decimal number (eg day = 23) must be broken down into individual
    characters (2 and 3) and converted to ASCII (+ ASCII value of "0").                 *)
(*--------------------------------------------------------------------------------------*)

function Datumskonvertierer() : integer
var Tag, Monat, Jahr, Jahrhilf: integer

begin
    Tag   := Time(0)  (* Read out the day in an auxiliary tag *)
    Monat := Time(1)  (* Read out the month in an auxiliary tag *)
    Jahr  := Time(2)  (* Read out the year in an auxiliary tag *)

    (* ASCII value calculation for day *)
    Datumfeld[0] := 48 + Tag div 10
    Datumfeld[1] := 48 + Tag mod 10

(* ASCII value calculation for month *)
    Datumfeld[2] := 48 + Monat div 10
    Datumfeld[3] := 48 + Monat mod 10
    Datumfeld[4] := 48 + Jahr div 1000     (* 1. ASCII value for year             *)
    Jahrhilf     := Jahr mod 1000          (* Remainder of the integer division   *)
    Datumfeld[5] := 48 + Jahrhilf div 100  (* 2. ASCII value for year             *)
    Jahrhilf     := Jahrhilf mod 100       (* Remainder of the integer division   *)
    Datumfeld[6] := 48 + Jahrhilf div 10   (* 3. ASCII value for year             *)
    Datumfeld[7] := 48 + Jahrhilf mod 10   (* 4. ASCII value for year             *)
    Datumfeld[8] := 0                      (* Terminate string with zero          *)
end

Note

Das Erstellen eines Prozessvariablenfeldes ist im Kapitel „Prozesspunktdefinition“ (Feldgröße (#) beschrieben.

Editieren einzelner Buchstaben einer lokalen Textvariablen: Lokale Textvariablen können ebenfalls über ASCII-Werte buchstabenweise editiert werden. Das erste Variablenelement beinhaltet den ASCII-Wert des ersten, das vorletzte Variablenelement den ASCII-Wert des letzten Buchstabens. Im letzten Variablenelement muss die „0“ als Stringendekennung stehen.

Beispiel
(*--------------------------------------------------------------*)
(*  The word "DATA" should be written in a text tag
    The following calculation is based on the ASCII table. The
    capital letters in the ASCII table begin with 65 (“A”) and
    end with 90 (“Z”).                                          *)
(*--------------------------------------------------------------*)

function AsciiTest():integer
var Testvar[20]:string
begin
    Testvar[0]:=68
    Testvar[1]:=65
    Testvar[2]:=84
    Testvar[3]:=69
    Testvar[4]:=78
    Testvar[5]:=0
    (* copy to a global tag for display in the picture  *)
    Global_Testvar := Testvar
end

Kopieren einer lokalen bzw. globalen Textvariablen: Textvar1 := Textvar2

Inhalt zweier Textvariablen vergleichen: if Textvar1= Textvar2 then …

Aneinanderhängen von lokalen bzw globalen Textvariablen: Textvar1:= Textvar2 + Textvar3

Konstanten Text in eine lokale bzw globale Textvariable schreiben: Textvar2:= ’Dies ist ein konstanter Text’ Textvar1:= ’konstanter Teil A’ + Textvar2 + ’konstanter Teil B’

Note

Textvariablen und Prozessvariablen müssen sich in ihrem Namen unterscheiden. Entsprechendes gilt für lokale und globale Textvariablen.

AppendString

Funktion zum Anhängen einer Zahl an einen String, sowie eines weiteren Strings, der als Separator für die Verkettung verwendet werden kann.

Funktionsdefinition: AppendString(v1 : real, Mode1, Mode2 : integer, StrSeparator, StrDest : string) : integer

Parameter:

v1

Variable der zu schreibenden Daten mit Formatangabe, bis 20 Stellen

v1 = Variable [ :Feldbreite [: Nachkommastelle]]

Mode1

0 = mit Leerzeichen (abhänig von der Formatangabe)

1 = mit Vorkommanullen (abhänig von der Formatangabe)

Mode2

0 = Nachkommastellen aus der Formatangabe

1 = Nachkommastellen aus der Prozessvariablendeklaration

StrSeparator

Konstanter oder variabler String, der als Separator für die Verkettung verwendet werden kann.

StrDest

String, an den die Daten angehängt werden

Rückgabewerte:

0

Daten angehängt

-1

Parameterfehler

-2

zu viele Zeichen im String

Note

Es sind maximal 4095 Zeichen in einem String erlaubt. Bei globalen Textvariablen ist die maximale Zeichenanzahl 255 Zeichen.

Beispiel
PROGRAM

(* The content of the tag v1 should be appended to the string tag "StrDest": *)
function fktAppendTest: integer

var v1 : real
var Mode1, Mode2 : integer
var StrSeparator, StrDest : string

begin
    Mode1 := 1
    Mode2 := 1
    StrSeparator := ','
    fktAppendTest := AppendString(v1:5:2, Mode1, Mode2, StrSeparator,
                    StrDest)
end

BEGIN
    fktAppendTest
END

DateToStr

Funktion zum Wandeln von Datums- und Zeitangaben in einen String. Die Umwandlung wird durch einen Formatstring vorgegeben.

Die Funktion wandelt den übergebenen Wert der Time()-Funktion unter Berücksichtigung des Sommerzeitoffsets und des Zeitzonenoffsets um. Wird der Funktion beispielsweise ein Wert der Funktion Time(8) übergeben, so erhält man die aktuelle Uhrzeit als String. Über den Parameter Time(12) erhält man einen String als UTC-Zeit.

Funktionsdefinition: DateToStr(InputSec : real, Format, Destination : string) : integer

Parameter:

InputSec

Prozessvariable mit absolutem Sekundenwert (Time(8) oder Time(12))

Format

Stringvariable für Zeitformatierung Folgende Formatzeichen sind definiert:

h = Stundenangabe

m = Minutenangabe

s = Sekundenangabe

D = Tagesangabe

M = Monatsangabe

Y = Jahresangabe

Destination

String in den die Ausgabe geschrieben wird

Rückgabewerte:

:-

:-

0

String erstellt

-1

Parameterfehler

Important

Die Funktionen Time() und DateToStr() arbeiten mit Sekunden-Werten

Im Gegensatz dazu arbeiten die Systemvariable „$Current.UTCTime“ und die Zahlenfeldanzeige mit Format „Datum/Uhrzeit“ mit Millisekunden-Werten. Hier muss also im Bedarfsfall eine Umrechung erfolgen.

Formatbezeichner die nur aus einem Zeichen bestehen müssen mit einem vorangestellten Leerzeichen erweitert werden (Bsp.: „f“ -> „ f“)

Beispiel
PROGRAM

(* Target string must be a global variable!                     *)
(* Function cannot return a string!                             *)
(* Example for formatting 11:00:10 on 03/01/98              *)
(* Content: date format         Content: data record name       *)
(* hh / mm / ss DD.MM.YY    11/00/10 03/01/98           *)
(* hh: mm: ss DMYYYY            11:00:10 1.3.1998               *)


function fktDateToStr(InputSec : real, Format : string) : integer
begin
    fktDateToStr:= DateToStr(InputSec, Format, Global_Destination)
end

BEGIN
    fktDateToStr(Input, Format)
END

Note

Der Formatstring kann auch ohne Trennzeichen (z.B. :,/) verwendet werden. Dieses ist für Dateinamen mit Datum sinnvoll (z.B.DateiX01031998).

GetSubString

Die Funktion liefert einen Substring aus einem Quellstring zurück. Sie extrahiert den Substring ab einer Startadresse und beendet den Substring sobald der übergebene Separator gefunden wurde.

Wird der Separator nicht gefunden ist der Returnwert -2 und der Substring wird mit dem Quellstring ab der Startadresse bis zum Ende des Strings zurückgeliefert.

Wird ein ungültiger Parameter übergeben, oder die Startadresse liegt außerhalb des Quellstring, so wird der Substring nicht angerührt.

Ist beim Aufruf der Funktion bereits ein Wert in der Variablen enthalten, so bleibt dieser auch nach der Funktion erhalten.

Funktionsdefinition: GetSubString(Quell, Sub, Separator : string, Start : integer) : integer

Parameter:

Source

Quellstring aus dem der Substring extrahiert wird

Sub

Variable in der der Substring geschrieben wird

Separator

Separator, bei dem der Substring endet

Start

Startposition, bei der der Substring beginnt

Rückgabewerte:

>= 0

Position des gefundenen Separators

-1

Parameterfehler

-2

Separator nicht gefunden

-3

Startadresse liegt außerhalb des Quellstrings

Beispiel
PROGRAM

function fktGetSubString(Source, Sub : string, Start : integer) : integer

var StrSeparator : string

begin
    StrSeparator := ','
    fktGetSubString := GetSubString(Source, Sub, StrSeparator, Start)
end

BEGIN
    fktGetSubString(Source, Sub, 2)
END

Length

Funktion zum Ermitteln der Länge eines Strings.

Funktionsdefinition: Length(Source : string) : integer

Parameter:

Source

Name des Quellstrings

Rückgabewerte:

>= 0

Anzahl der Zeichen

<0

wenn Fehler

Beispiel
PROGRAM

function fktLength(Input : string) : integer
begin
    fktLength := Length(Input)
end

BEGIN
    fktLength(Source)
END

Pos

Funktion zum Suchen eines Strings in einem String.

Funktionsdefinition: Pos(Sub, Source : string) : integer

Parameter:

Sub

Name des zu suchenden Strings

Source

Name des zu durchsuchenden Strings

Rückgabewerte:

>= 0

Position des Substrings in String

<0

wenn nicht gefunden

Beispiel
PROGRAM

function fktPos(Sub, Source : string) : integer
begin
    fktPos := Pos(Sub, Source)
end

BEGIN
    fktPos(Sub, Source)
END

Str

Funktion zum Konvertieren einer Zahl in einen String. Es kann auch eine Formatierung übergeben werden.

Funktionsdefinition: Str(Source : real, Destination : string) : integer

Parameter:

Source

Variable der zu schreibenden Daten mit Formatangabe, bis max. 20 Stellen es gilt allgemein:

Source = Variable [ : Feldbreite [ : Nachkommastellen]]

Destination

Name des Zielstrings

Rückgabewerte:

>= 0

wenn konvertiert

<0

wenn nicht konvertiert

Important

Die Feldbreite gibt nur die Mindestbreite an, d.h. wenn die zu wandelnde Zahl größer ist wie die Mindestfeldbreite wird trotzdem die gesamte Zahl in einen String gewandelt Bsp: Feldbreite 1 Nachkommstelle 1 zu wandelnde Zahl 22 Als Ergebnis wird die 22.0 als String geliefert.

Ist die Feldbreite größer als die Zahl, wird String am Anfang mit 0 aufgefüllt Bei Feldbreite 3 wird aus 22 ein String „022“ Damit auf String wieder gleicher Wert kommt kann alternativ der Befehl AppendString mit Mode1=0 verwendet werden.

Beispiel
PROGRAM

(* Target string must be a global variable! *)
(* Function cannot return a string!         *)

begin
    time:=Time(8)
    Str(time:10:2, varTimeStamp)
end

Val

Funktion zum Konvertieren eines Strings in eine Zahl. In der als „Interrupt“ übergebenen Integer Variablen speicherte VAL in PROCON-WIN die Position des Zeichens in „Source“ bei dem die Konvertierung abgebrochen wurde. Heute wird der Parameter „Interupt“ bei der Ausführung ignoriert muss aber in der Funktion angegeben werden!

Führende Leerzeichen werden von Val automatisch übersprungen. Enthält ein String die folgende Zeichenkombination ‘ 12.13’ so wird der Prozessvariablen der Wert 12,13 zugewiesen.

Important

Der zu konvertierende String darf nur Zahlen, Punkt oder Komma enthalten! Enthält er andere Zeichen wird die Funktion nicht ausgeführt. Der Parameter Interupt muss zwingend angegeben werden wird aber nicht ausgewertet!

Alternativ können auch die Funktionen StringToInt oder StringToReal verwendet werden.

Funktionsdefinition: Val(Source : string, Value : real, Interrupt : integer) : integer

Parameter:

Source

Name des Quellstrings

Value

Name der num. Variable für Wert

Interrupt

Konvertierungsinformation (wird nicht ausgewertet)

Rückgabewerte:

keiner, doch Variable Code zeigt den Konvertierungsstatus an

> = 0

wenn konvertiert

< 0

wenn nicht konvertiert

Beispiel
PROGRAM

(* Function gives the index of the position in the "Interrupt" variable, *)
(* at which the function was interrupted again.                          *)

function fktVal(Source : string) : integer

var Value : real
var Interrupt: integer

begin
    Val(Source, Value, Interrupt)
    fktVal := Value
end

BEGIN
    fktVal(Source)
END

StringToUpper

Funktion zum Konvertieren eines String in Großbuchstaben.

Funktionsdefinition: StringToUpper(var string:text) : integer

Parameter:

StrSrc

Variable die konvertiert werden soll

Rückgabewerte:

0

wenn konvertiert

<0

wenn nicht konvertiert

Beispiel
PROGRAM

function ToUpper(Source : string) : integer

var Error : integer
begin
Error := StringToUpper(Source)
end

BEGIN
ToUpper('text')
END

(* -->   Source := 'TEXT' *)

StringToLower

Funktion zum Konvertieren eines String in Kleinbuchstaben.

Funktionsdefinition: StringToLower(var string:text) : integer

Parameter:

StrSrc

Variable die konvertiert werden soll

Rückgabewerte:

0

wenn konvertiert

<0

wenn nicht konvertiert

Beispiel
PROGRAM

function ToLower(Source : string) : integer

var Error : integer
begin
Error := StringToLower(Source)
end

BEGIN
ToLower('TEXT')
END

(* -->   Source := 'text' *)

StringTrim

Entfernt alle benannten Stellen (links, rechts oder beidseitig) an denen der zu entfernende Buchstabe in einem String vorkommt.

Funktionsdefinition: StringTrim(var string: strSrc, integer: type, string(char):v1…vn) : integer

Parameter:

StrSrc

String auf dem der Trim-Befehl angewendet werden soll

Type

Art des Trimmens (1=Links, 2=Rechts, 3 = Links und Rechts)

V1…n

Ein oder mehrere zu entferende Zeichen

Rückgabewerte:

-3

TrimTyp wurde nicht gefunden

-2

Liste mit den zu entferenenden Zeichen ist nicht korrekt

-1

Unbehandelter Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function Trim(Source : string, Type : integer, V1,V2 : string) : integer

var Error : integer
begin
Error := StringTrim(Source, Type, V1, V2)
end

BEGIN
Trim('AACCABCCAAB', 1, 'A', 'B')
END

(* -->   Source := 'CCABCCAAB' *)

StringTemplate

Funktion zum Einfügen von Werten in eine Zeichenfolge

Funktionsdefinition: StringTemplate(var string: strSrc (string,integer,real, Boolean:v1…vn) : integer

Parameter:

StrSrc

Zeichenfolge die formatiert werden soll

V1…n

Ein oder mehrere einzufügende Zeichen

Rückgabewerte:

-2

Format ist nicht korrekt (nicht in IoT vorhanden)

-1

Unbehandelter Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function Template(Source : string, V1,V2 : string) : integer

var Error : integer
begin
Error := StringTemplate(Source, V1, V2)
end

BEGIN
Template('Temperature in room {0} is {1} degrees', V1, V2)
END

(* -->   Source := 'Temperature in room Support is 50 degrees' *)

StringReplace

Funktion zum Ersetzen eines Unicode-Zeichen oder eines Strings in einer Zeichenfolge

Funktionsdefinition: StringReplace(var string: strSrc real, Boolean:v1…vn) : integer

Parameter:

StrSrc

Zeichenfolge in der die Unicode-Zeichen ersetzt werden soll

OldValue

Das zu ersetzende Zeichen oder die Zeichenfolge

NewValue

Das ersetzende Zeichen oder die Zeichenfolge

Rückgabewerte:

-1

Unbehandelter Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

    function Replace(Source : string, OldValue,NewValue : string) : integer

var Error : integer
begin
Error := StringReplace(Source, OldValue, NewValue)
end

BEGIN
Replace('How are you!', '!', '?')
END

(* -->   Source := 'How are you?' *)

StringToInt

Funktion zum Konvertieren eines String in einen Integer

Funktionsdefinition: StringToInt(string: strSrc, var integer:intDest) : integer

Parameter:

StrSrc

Name des Quellstrings

IntDest

Name des Ziel-Integers

Rückgabewerte:

-1

Konvertieren nicht möglich

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function ToInt(Source : string, Dest : integer) : integer

var Error : integer
begin
Error := StringToInt(Source, Dest)
end

BEGIN
ToInt('5', Dest)
END

(* -->   Dest := 5 *)

StringToReal

Funktion zum Konvertieren eines Strings in eine Zahl mit Nachkommastellen. Darstellung nur mit Punkt möglich und keine Komma, da dies dem internationalen Standard entspricht

Funktionsdefinition: StringToReals(string: strSrc, var integer:realDest) : integer

Parameter:

StrSrc

Name des Quellstrings

RealDest

Name des Ziel-Reals

Rückgabewerte:

-1

Konvertieren nicht möglich

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function ToReal(Source : string, Dest : real) : integer

var Error : integer
begin
Error := StringToReal(Source, Dest)
end

BEGIN
ToInt('5.55', Dest)
END

(* -->   Dest := 5.55 *)

IsNumeric

Funktion zum Abfragen, ob ein Ausdruck als Zahl ausgewertet werden kann.

Funktionsdefinition: IsNumeric(string: strSrc) : integer

Parameter:

StrSrc

Name des Quellstrings

Rückgabewerte:

-1

Ist kein Real oder Integer

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function IsNumVar(Source : string) : integer

var Error : integer
begin
Error := IsNumeric(Source)
end

BEGIN
IsNumVar('5')
END

(* -->   Error := 0 *)

StringFormat

Funktion zum Formatieren eines Integers/Reals der entsprechend den Anweisungen in einem String-Formatausdruck formatiert wird

Funktionsdefinition: StringFormat(string: strSrc, string format, [var]destString) : integer

Parameter:

Source

Integer/Real der formatiert werden soll

Format

Ein gültiger Format-String-Ausdruck

DestString

Name des Ziel-Strings

Rückgabewerte:

-3

Format ist nicht korrekt

-2

Ist kein Integer oder Real

-1

Unbehandelbarer Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function Format(Source : integer, Format,DestString : string) : integer

var Error : integer
begin
Error := StringFormat(Source, Format, DestString)
end

BEGIN
Format(1000000, '{0:n}', DestString)
END

(* -->   DestString := '1,000,000.00' *)

StringRegExIsMatch

Funktion zum Abfragen, ob der reguläre Ausdruck eine Übereinstimmung in der angegebenen Eingabezeichenfolge findet

Funktionsdefinition: StringRegExIsMatch(string: strSrc, string pattern) : integer

Parameter:

StrSrc

Die nach einer Übereinstimmung zu durchsuchenden Zeichenfolge

Pattern

Das Muster eines regulären Ausdrucks, mit dem Übereinstimmungen gefunden werden sollen

Rückgabewerte:

-3

Ein Analysefehler für reguläre Ausdrücke ist aufgetreten (nicht in IoT vorhanden)

-2

Timeout (nicht in IoT vorhanden

-1

Wenn der reguläre Ausdruck keine Übereinstimmung findet

0

Wenn der reguläre Ausdruck eine Übereinstimmung findet

Beispiel
PROGRAM

function RegExIsMatch(Source,Pattern : string) : integer

var Error : integer
begin
Error := StringRegExIsMatch(Source, Pattern)
end

BEGIN
RegExIsMatch('hello', 'l{2}')
END

(* --> Error := 0 *)

StringIndexOf

Funktion liefert den nulllbasierten Index des ersten Vorkommens eines angegebenen Unicode-Zeichens oder Unicode-Zeichenfolge zurück

Funktionsdefinition: StringIndexOf(string: strSrc, string pattern) : integer

Parameter:

StrSrc

Der zu durchsuchende String

Pattern

Die zu suchende Zeichenfolge

Rückgabewerte:

-1

Die zu suchende Zeichenfolge wurde nicht gefunden

>0

Liefert den nullbasierten Index des ersten Vorkommens

Beispiel
PROGRAM

function IndexOf(Source,SeekStr : string) : integer

var Error : integer
begin
Error := StringIndexOf(Source, SeekStr)
end

BEGIN
IndexOf('PROCON-WEB', 'C')
END

(* -->   Error := 3 *)

StringStartsWith

Funktion zum Abfragen, ob der Anfang dieser Zeichenfolgeninstanz mit der angegebenen Zeichenfolge übereinstimmt

Funktionsdefinition: StringStartsWith(string: strSrc, string comString) : integer

Parameter:

StrSrc

Der zu durchsuchende String

ComString

Die zu vergleichende Zeichenfolge

Rückgabewerte:

-1

String startet nicht mit der zu vergleichenden Zeichenfolge

0

String startet mit der zu vergleichenden Zeichenfolge

Beispiel
PROGRAM

function StartsWith(Source,ComStr : string) : integer

var Error : integer
begin
Error := StringStartsWith(Source, ComStr)
end

BEGIN
StartWith('PROCON-WEB', 'PROCON')
END

(* --> Error := 0 *)

StringEndsWith

Funktion zum Abfragen, ob das Ende dieser Zeichenfolgeninstanz mit der angegebenen Zeichenfolge übereinstimmt

Funktionsdefinition: StringEndsWith(string: strSrc, string comString) : integer

Parameter:

StrSrc

Der zu durchsuchende String

ComString

Die zu vergleichende Zeichenfolge

Rückgabewerte:

-1

String endet nicht mit der zu vergleichenden Zeichenfolge

0

String endet mit der zu vergleichenden Zeichenfolge

Beispiel
PROGRAM

function EndsWith(Source,ComStr : string) : integer

var Error : integer
begin
Error := StringEndsWith(Source, ComStr)
end

BEGIN
EndsWith('PROCON-WEB', '-WEB')
END

(* -->   Error := 0 *)

StringInsert

Funktion zum Einfügen eines Strings an der angegebenen Indexposition in der aktuellen Zeichenfolge

Funktionsdefinition: StringInsert(string: strSrc, integer:startIndex, string:insertValue) : integer

Parameter:

StrSrc

Der zu durchsuchende String

startIndex

Die zu vergleichende Zeichenfolge

insertValue

Der einzufügende Wert

Rückgabewerte:

-2

Startindex ist zu groß oder zu klein

-1

Unbehandelbarer Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function Insert(Source : string, StartIndex : integer, InsertVal : string) : integer

var Error : integer
begin
Error := StringInsert(Source, StartIndex, InsertVal)
end

BEGIN
Insert('PROCONWEB', 6, '-')
END

(* -->   Source := 'PROCON-WEB' *)

StringRemove

Funktion zum Entfernen einer angegebenen Anzahl von Zeichen aus der aktuellen Zeichenfolge

Funktionsdefinition: StringRemove(string: strSrc, integer:position, integer:count) : integer

Parameter:

StrSrc

Name des Quellstrings

Position

Position des Entfernens (1 = links, 2 = rechts)

Count

Anzahl der zu löschenden Zeichen

Rückgabewerte:

-3

Position wurde nicht gefunden

-2

Count ist nicht korrekt

-1

Unbehandelbarer Fehler

0

Wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function Remove(Source : string, StartIndex,Count : integer) : integer

var Error : integer
begin
Error := StringRemove(Source, StartIndex, Count)
end

BEGIN
Remove('PROCON-WEB 6.4', 2, 4)
END

(* -->   Source := 'PROCON-WEB' *)

Mathematische Funktion

Sqrt

Funktion zum Berechnen der Quadratwurzel

Funktionsdefinition: Sqrt(Value : real) : real

Parameter:

Value

Wert aus dem die Quadartwurzel gezogen wird

Rückgabewerte:

Funktionswert

Quadratwurzel

Beispiel
PROGRAM

function fktSqrt(Value : real) : integer
begin
    fktSqrt := Sqrt(Value)
end

BEGIN
    fktSqrt(Source)
END

Ln

Funktion zum Berechnen des natürlichen Logarithmus

Funktionsdefinition: Ln(Value : real) : real

Parameter:

Value

Wert der logarithmiert werden soll

Rückgabewerte:

Funktionswert

Logarithmus des Wertes

Beispiel
PROGRAM

function fktLn(Value : real) : integer
begin
    fktLn := Ln(Value)
end

BEGIN
    fktLn(Source)
END

Exp

Funktion zum Berechnen der Potenz e ^ x

Funktionsdefinition: Exp(Value : real) : real

Parameter:

Wert der potenziert werden soll

Rückgabewerte:

Funktionswert

natürliche Potenz des Wertes

Beispiel
PROGRAM

function fktExp(Value : real) : integer
begin
    fktExp := Exp(Value)
end

BEGIN
    fktExp(Source)
END

Log

Funktion zum Berechnen des 10er Logarithmus

Funktionsdefinition: Log(Value : real) : real

Parameter:

Value

Wert der logarithmiert werden soll

Rückgabewerte:

Funktionswert

10er Logarithmus des Wertes

Beispiel
PROGRAM

function fktLog(Value : real) : integer
begin
    fktLog := Log(Value)
end

BEGIN
    fktLog(Source)
END

Pow

Funktion zum Berechnen einer Potenz x ^ y

Funktionsdefinition: Pow(XValue, YValue : real) : real

Parameter:

XValue

Basis zur Potenzierung

YValue

Exponent zur Potenzierung

Rückgabewerte:

Funktionswert

Wert aus der Potenzierung

Beispiel
PROGRAM

function fktPow(XValue, YValue : real) : integer
begin
    fktPow := Pow(XValue, YValue)
end

BEGIN
    fktPow(XValue, YValue)
END

Abs

Funktion zum Berechnen des Absolutwertes. Die Betragsfunktion ordnet jeder reellen Zahl ihren Absolutbetrag zu

Funktionsdefinition: Abs(Value : real) : real

Parameter:

Value

Wert für die Betragsfunktion

Rückgabewerte:

Funktionswert

Absolutwert

Beispiel
PROGRAM

function fktAbs(Value : real) : integer
begin
    fktAbs := Abs(Value)
end

BEGIN
    fktAbs(Source)
END

Trigonometrische Funktion

Sin

Funktion zum Berechnen des Sinuswertes aus einem Winkelwert.

Funktionsdefinition: Sin(Value : real) : real

Parameter:

Value

Winkelwert in Rad zwischen 0 und 2 PI

Rückgabewerte:

Funktionswert

Sinuswert

Beispiel
PROGRAM

function fktSin(Value : real) : integer
begin
    fktSin := Sin(Value)
end

BEGIN
    fktSin(Source)
END

Cos

Funktion zum Berechnen des Cosinuswertes aus einem Winkelwert.

Funktionsdefinition: Cos(Value : real) : real

Parameter:

Value

Winkelwert in Rad zwischen 0 und 2 PI

Rückgabewerte:

Funktionswert

Cosinuswert

Beispiel
PROGRAM

function fktCos(Value : real) : integer
begin
    fktCos := Cos(Value)
end

BEGIN
    fktCos(Source)
END

Tan

Funktion zum Berechnen des Tangenswertes aus einem Winkelwert

Funktionsdefinition: Tan(Value : real) : real

Parameter:

Value

Winkelwert in Rad zwischen -PI/2 und PI/2

Rückgabewerte:

Funktionswert

Tangenswert

Beispiel
PROGRAM

function fktTan(Value : real) : integer
begin
    fktTan := Tan(Value)
end

BEGIN
    fktTan(Source)
END

Arcsin

Funktion zum Berechnen des Arkus-sinuswertes aus einem Winkelwert.

Funktionsdefinition: Arcsin(Value : real) : real

Parameter:

Value

Wert zwischen -1 und 1

Rückgabewerte:

Funktionswert

Arkussinuswert

Beispiel
PROGRAM

function fktArcsin(Value : real) : integer
begin
    fktArcsin := Arcsin(Value)
end

BEGIN
    fktArcsin(Source)
END

Arccos

Funktion zum Berechnen des Arkuskosinuswertes aus einem Winkelwert.

Funktionsdefinition: Arccos(Value : real) : real

Parameter:

Value

Wert zwischen -1 und 1

Rückgabewerte:

Funktionswert

Arkuskosinuswert

Beispiel
PROGRAM

function fktArccos(Value : real) : integer
begin
    fktArccos:= Arccos(Value)
end

BEGIN
    fktArccos(Source)
END

Arctan

Funktion zum Berechnen des Arkustangenwertes aus einem Winkelwert.

Funktionsdefinition: Arctan(Value : real) : real

Parameter:

Value

zwischen -unendlich und +unendlich

Rückgabewerte:

Funktionswert

Arkustangenswert

Beispiel
PROGRAM

function fktArctan(Value : real) : integer
begin
    fktArctan := Arctan(Value)
end

BEGIN
    fktArctan(Source)
END

Arctan2

Funktion zum Berechnen des Arkustangenwertes mit zwei Parametern. Im Gegensatz zum Arctan kann sie dabei die Vorzeichen beider Parameter beachten und so den Quadranten des Ergebnisses bestimmen.

Funktionsdefinition: Arctan(Value1, Value2 : real) : real

Parameter:

Value1

zwischen -unendlich und +unendlich

Value2

zwischen -unendlich und +unendlich

Rückgabewerte:

Funktionswert

Arkustangens2wert

Beispiel
PROGRAM

function fktArctan2(Value1, Value2 : real) : integer
begin
    fktArctan2 := Arctan2(Value1, Value2)
end

BEGIN
    fktArctan2(Source1, Source2)
END

Sinh

Funktion zum Berechnen des Hyperbelsinuswertes aus einem Winkelwert.

Funktionsdefinition: Sinh(Value : real) : real

Parameter:

Value

Reelle Zahlen

Rückgabewerte:

Funktionswert

Hyperbelsinuswert

Beispiel
PROGRAM

function fktSinh(Value : real) : integer
begin
    fktSinh := Sinh(Value)
end

BEGIN
    fktSinh(Source)
END

Cosh

Funktion zum Berechnen des Hyperbelkosinuswertes aus einem Winkelwert.

Funktionsdefinition: Cosh(Value : real) : real

Parameter:

Value

Reelle Zahlen

Rückgabewerte:

Funktionswert

Hyperbelkosinuswert

Beispiel
PROGRAM

function fktCosh(Value : real) : integer
begin
    fktCosh := Cosh(Value)
end

BEGIN
    fktCosh(Source)
END

Tanh

Funktion zum Berechnen des Hyperbeltangenswertes aus einem Winkelwert.

Funktionsdefinition: Cosh(Value : real) : real

Parameter:

Value

Reelle Zahlen

Rückgabewerte:

Funktionswert

Hyperbeltangenswert

Beispiel
PROGRAM

function fktTanh(Value : real) : integer
begin
    fktTanh := Tanh(Value)
end

BEGIN
    fktTanh(Source)
END

Zeit- und Datumsfunktionen

Die nachfolgenden Formatierungen gelten nicht für PROCON-WEB Embedded Systems.

Formatbezeichner

Beschreibung

Beispiele

„ d“

Der Tag des Monats, von 1 bis 31.

2009-06-01T13:45:30 -> 1

2009-06-15T13:45:30 -> 15

„dd“

Der Tag des Monats, von 01 bis 31.

2009-06-01T13:45:30 -> 01

2009-06-15T13:45:30 -> 15

„ddd“

Der abgekürzte Name des Tags der Woche.

2009-06-15T13:45:30 -> Mo.

„dddd“

Der vollständige Name des Wochentags.

2009-06-15T13:45:30 -> Montag

„ f“

Die Zehntelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6170000 -> 6

2009-06-15T13:45:30.05 -> 0

„ff“

Die Hundertstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6170000 -> 61

2009-06-15T13:45:30.0500000 -> 00

„fff“

Die Millisekunden in einem Datums- und Uhrzeitwert.

6/15/2009 13:45:30.617 -> 617

6/15/2009 13:45:30.0005 -> 000

„ffff“

Die Zehntausendstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175000 -> 6175

2009-06-15T13:45:30.0000500 -> 0000

„fffff“

Die Hunderttausendstelsekunde in einem Datums- und Uhrzeitwert.

009-06-15T13:45:30.6175400 -> 61754

6/15/2009 13:45:30.000005 -> 00000

„ffffff“

Die Millionstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175420 -> 617542

2009-06-15T13:45:30.0000005 -> 000000

„fffffff“

Die Zehnmillionstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175425 -> 6175425

2009-06-15T13:45:30.0001150 -> 0001150

„ F“

Wenn ungleich 0 (null), die Zehntelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6170000 -> 6

2009-06-15T13:45:30.0500000 -> (keine Ausgabe)

„FF“

Wenn ungleich 0 (null), die Hundertstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6170000 -> 61

2009-06-15T13:45:30.0050000 -> (keine Ausgabe)

„FFF“

Wenn ungleich 0 (null), die Millisekunden in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6170000 -> 617

2009-06-15T13:45:30.0005000 -> (keine Ausgabe)

„FFFF“

Wenn ungleich 0 (null), die Zehntausendstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.5275000 -> 5275

2009-06-15T13:45:30.0000500 -> (keine Ausgabe)

„FFFFF“

Wenn ungleich 0 (null), die Hunderttausendstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175400 -> 61754

2009-06-15T13:45:30.0000050 -> (keine Ausgabe)

„FFFFFF“

Wenn ungleich 0 (null), die Millionstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175420 -> 617542

2009-06-15T13:45:30.0000005 -> (keine Ausgabe)

„FFFFFFF“

Wenn ungleich 0 (null), die Zehnmillionstelsekunde in einem Datums- und Uhrzeitwert.

2009-06-15T13:45:30.6175425 -> 6175425

2009-06-15T13:45:30.0001150 -> 000115

„ g“, „gg“

Der Zeitraum.

2009-06-15T13:45:30.6170000 -> A.D.

„ h“

Die Stunde, von 1 bis 12 (12-Stunden-Format).

2009-06-15T01:45:30 -> 1

2009-06-15T13:45:30 -> 1

„hh“

Die Stunde, von 01 bis 12 (12-Stunden-Format).

2009-06-15T01:45:30 -> 01

2009-06-15T13:45:30 -> 01

„ H“

Die Stunde, von 0 bis 24 (24-Stunden-Format).

2009-06-15T01:45:30 -> 1

2009-06-15T13:45:30 -> 13

„HH“

Die Stunde, von 00 bis 23 (24-Stunden-Format).

2009-06-15T01:45:30 -> 01

2009-06-15T13:45:30 -> 13

„ K“

Zeitzoneninformationen.

Mit DateTime-Werten:

2009-06-15T13:45:30, Art nicht angegeben ->

2009-06-15T13:45:30, UTC-Zeitzone -> Z

2009-06-15T13:45:30, Lokale Zeitzone -> -07:00 (hängt von den lokalen Computereinstellungen ab)

Mit DateTimeOffset-Werten:

2009-06-15T01:45:30-07:00 –> -07:00

2009-06-15T08:45:30+00:00 –> +00:00

„ m“

Die Minute, von 0 bis 59.

2009-06-15T01:09:30 -> 9

2009-06-15T13:29:30 -> 29

„mm“

Die Minute, von 00 bis 59.

2009-06-15T01:09:30 -> 09

2009-06-15T01:45:30 -> 45

„M“

Der Monat, von 1 bis 12.

2009-06-15T13:45:30 -> 6

„MM“

Der Monat, von 01 bis12.

2009-06-15T13:45:30 -> 06

„MMM“

Der abgekürzte Name des Monats.

2009-06-15T13:45:30 -> Jun

„MMMM“

Der vollständige Name des Monats.

2009-06-15T13:45:30 -> Juni

„ s“

Die Sekunde, von 0 bis 59.

2009-06-15T13:45:09 -> 9

„ss“

Die Sekunde, von 00 bis 59.

2009-06-15T13:45:09 -> 09

„ t“

Das erste Zeichen des AM/PM-Kennzeichners.

2009-06-15T13:45:30 -> P (en-US)

„tt“

Der AM/PM-Kennzeichner.

2009-06-15T13:45:30 -> PM

„ y“

Das Jahr, von 0 bis 99.

0001-01-01T00:00:00 -> 1

0900-01-01T00:00:00 -> 0

1900-01-01T00:00:00 -> 0

2009-06-15T13:45:30 -> 9

2019-06-15T13:45:30 -> 19

„yy“

Das Jahr, von 00 bis 99.

0001-01-01T00:00:00 -> 01

0900-01-01T00:00:00 -> 00<

1900-01-01T00:00:00 -> 00

2019-06-15T13:45:30 -> 19

„yyy“

Das Jahr, mit einem Minimum von drei Ziffern.

0001-01-01T00:00:00 -> 001

0900-01-01T00:00:00 -> 900

1900-01-01T00:00:00 -> 1900

2009-06-15T13:45:30 -> 2009

„yyyy“

Das Jahr als vierstellige Zahl.

0001-01-01T00:00:00 -> 0001

0900-01-01T00:00:00 -> 0900

1900-01-01T00:00:00 -> 1900

2009-06-15T13:45:30 -> 2009

„yyyyy“

Das Jahr als fünfstellige Zahl.

0001-01-01T00:00:00 -> 00001

2009-06-15T13:45:30 -> 02009

„ z“

Offset von UTC in Stunden, ohne führende Nullen.

2009-06-15T13:45:30-07:00 -> -7

„zz“

Offset von UTC in Stunden, mit einer führenden Null für einen einstelligen Wert.

2009-06-15T13:45:30-07:00 -> -07

„zzz“

Offset von UTC in Stunden und Minuten.

2009-06-15T13:45:30-07:00 -> -07:00

„ :“

Das Zeittrennzeichen.

2009-06-15T13:45:30 -> : (en-US)

2009-06-15T13:45:30 -> .(it-IT)

2009-06-15T13:45:30 -> : (ja-JP)

„ /“

Das Datumstrennzeichen.

2009-06-15T13:45:30 -> / (en-US)

2009-06-15T13:45:30 -> - (ar-DZ)

2009-06-15T13:45:30 -> .(tr-TR)

„Zeichenfolge“

Trennzeichen für Literalzeichenfolge.

2009-06-15T13:45:30 („arr:“ h:m t) -> arr: 1:45 P

%

Definiert das nächste Zeichen als benutzerdefinierten Formatbezeichner.

2009-06-15T13:45:30 (%h) -> 1

Das Escapezeichen.

2009-06-15T13:45:30 (h h) -> 1 h

Jedes andere Zeichen

Das Zeichen wird unverändert in die Ergebniszeichenfolge kopiert.

2009-06-15T01:45:30 (arr hh:mm t) -> arr 01:45 A

Embedded Systems setzt zu SCADA unterschiedliche Formatierungen ein. Bitte beachten Sie in einem Embedded Systems Projekt folgende Zeitformatierungen.

Formatierer

Beschreibung

%a

Der abgekürzte Wochentagsname des Gebietsschemas.

%A

Der abgekürzte Wochentagsname des Gebietsschemas.

%b

Der volle Monatsname des Gebietsschemas.

%B

Der volle Monatsname des Gebietsschemas.

%c

Die Darstellung von Datum und Uhrzeit des Gebietsschemas. Der geänderte Befehl %c erzeugt die alternative Datums- und Uhrzeitdarstellung des Gebietsschemas

%C

Das Jahr geteilt durch 100 mit Bodenteilung. Wenn das Ergebnis eine einzelne Dezimalstelle ist, wird ihr O vorangestellt. Der geänderte Befehl %OC erzeugt die alternative Darstellung des Jahrhunderts im Gebietsschema.

%d

Der Tag des Monats als Dezimalzahl. Wenn das Ergebnis eine einstellige Zahl ist, wird ein O vorangestellt. Der abgeänderte Befehl %Od erzeugt die Alternative des Gebietsschemas.

%D

Äquivalent zu %m/%d/%y.

%e

Der Tag des Monats als Dezimalzahl. Wenn das Ergebnis eine einstellige Zahl ist, wird ein Leerzeichen vorangestellt. Der veränderte Befehl %Oe erzeugt die alternative Darstellung im Gebietsschema.

%F

Äquivalent zu %Y-%m-%d.

%g

Die letzten beiden Dezimalzahlen des ISO-basierten Jahres. Das Ergebnis ist eine einzelne Zahl mit einer vorausgestellten 0.

%G

Das ISO wochen-basierte Jahr als Dezimalzahl. Wenn das Ergebnis weniger wie vier Zeichen, wird es linksseitig mit 0 auf vier Zeichen aufgefüllt.

%h

Äquivalent zu %b.

%H

Die Stunde (24-Stunden-Format) als Dezimalzahl Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OH liefert die ortsbezogene Alternative.

%I

Die Stunde (12-Stunden-Format) als Dezimalzahl. The hour (12-hour clock) as a decimal number. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OI liefert die ortsbezogene Alternative.

%j

Der Tag des Jahres als Dezimalzahl. Jan 1 ist 001. Wenn das Ergebnis weniger wie drei Zeichen, wird es linksseitig mit 0 auf drei Zeichen aufgefüllt.

%m

Der Monat als Dezimalzahl. Jan ist 01. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %Om liefert die ortsbezogene Alternative

%M

Die Minute als Dezimalzahl. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OM liefert die ortsbezogene Alternative

%n

Ein Zeilenvorschub

%p

Das örtliche Äquivalent der AM/PM Bezeichner in Verbindung mit dem 12 Stunden-Format.

%r

Die Zeit des Gebietsschemas im 12-Stunden-Format.

%R

Äquivalent zu %H:%M.

%S

Sekunden als Dezimalzahl. Wenn die Anzahl der Stellen weniger wie zehn ist, wird das Ergebnis mit vorangestellten Nullen aufgefüllt. Wenn die Genauigkeit der Eingabe nicht genau mit Sekunden angegeben werden kann, ist das Format eine dezimale Gleitkommazahl mit einem festen Format und einer Genauigkeit, die der Genauigkeit der Eingabe entspricht (oder zu einer Mikrosekunden-Genauigkeit, wenn die Umrechnung in Gleitkomma-Dezimalsekunden nicht innerhalb von 18 Bruchteilen erfolgen kann. Der veränderte Befehl %OS liefert die ortsbezogene Alternative

%t

Ein Zeilentabulator bzw. Tabstoppzeichen.

%T

Äquivalent zu %H:%M:%S.

%u

Der ISO Wochentag als Dezimalzahl (1-7), wobei Montag 1 ist. Der veränderte Befehl %u liefert die ortsbezogene Alternative.

%U

Die Wochennummer des Jahres als Dezimalzahl. Der erste Sonntag im Jahr ist der erste Tag der Woche 01. Tage desselben Jahres vor diesem sin in der Woche 00. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OU liefert die ortsbezogene Alternative.

%V

Die ISO wochen-basierte Nummer ist eine Dezimalzahl. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OV liefert die ortsbezogene Alternative.

%w

Der Wochentag als Dezimalzahl (0-6), wobei Sonntag die 0 ist. Der veränderte Befehl %Ow liefert die ortsbezogene Alternative.

%W

Die Wochennummer des Jahres als Dezimalzahl. Der erste Montag im Jahr ist der erste Tag der Woche 01. Tage desselben Jahres vor diesem sin in der Woche 00. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt. Der veränderte Befehl %OW liefert die ortsbezogene Alternative

%x

Ortsbezogene Datumsdarstellung. Der veränderte Befehl %Ex liefert die ortsbezogene Alternative.

%X

Ortsbezogene Zeitdarstellung. Der veränderte Befehl %EX liefert die ortsbezogene Alternative The locale’s time representation.

%y

Die letzten beiden Dezimalzahlen des Jahres. Wenn das Ergebnis einstellig ist, wird eine 0 vorangestellt.

%Y

Das Jahr als Dezimalzahl. Wenn das Ergebnis weniger wie vier Zeichen hat, wird es linksseitig mit Nullen auf vier Stellen aufgefüllt.

%z

Das Offset der UTC Zeit im ISO 8601 OFrmat. Zum Beispiel -0430 bedeutet 4 Stunden 30 Minuten nach der UTC Zeit. Wenn das Offset Null ist, wird +0000 benutzt. Die veränderten Befehle %Ez und %Oz fügen ein : zwischen Stunden und Minuten ein: -4:30

%Z

Die Abkürzung der Zeitzone.

%%

Ein % Zeichen.

Beispiele für Embedded Systems Formatierungen:

Formatierer

Ergebnis

%H:%M:%S %d.%m.%Y

14:20:30.00000000 23.07.2021

%H:%M:%OS %d.%m.%Y

14:20:30 23.07.2021

%I:%M:%OS %d.%m.%Y %p

02:30:39 28.07.2021 PM

%FT%H:%M

2021-07-23T14:20

%c

Wed Jul 28 14:31:48 2021

%A %B %Y

Wednesday July 2021

%T %Z

14:36:38.000000000 UTC

AbsToTime

Funktion zum Bestimmen der Datum- und Zeitangaben aus einer absoluten Systemzeit seit 1.1.1970. Das Ausgabeformat entspricht dem Eingabeformat, bedeutet, wenn Millisekunden eingegeben werden, werden diese auch mit ausgegeben, werden die bei der Eingabe nicht erfasst, ist auch der Ausgabewert nur in Sekunden.

Funktionsdefinition: AbsToTime(AbsTime : real, Day, Month, Year, Hour, Minute, Second, Millisecond : integer) : integer

Parameter:

AbsTime

Absolute Systemzeit in Millisekunden seit 1.1.1970

Day

Variable die als Wert den Tag des Monats 1..31 erhält.

Month

Variable die als Wert den Monat des Jahres 1..12 erhält.

Year

Variable die als Wert das Jahr 1970..2038 erhält.

Hour

Variable die als Wert die Stunde des Tages 0..23 erhält.

Minute

Variable die als Wert die Minute der Stunde 0..59 erhält.

Second

Variable die als Wert die Sekunde der Minute 0..59 erhält.

Millisecond

Variable die als Wert die Millisekunde der Sekunde 0..999 erhält.

Rückgabewerte:

>= 0

wenn ok

< 0

Fehlerhafte Parametrierung

Beispiel
PROGRAM

function fktAbsToTime(AbsTime : real) : integer

var Day, Month, Year, Hour, Minute, Second, Millisecond : integer

begin
    AbsToTime(AbsTime, Day, Month, Year, Hour, Minute, Second, Millisecond)
    (* copy to global variables *)
    Global_Day    := Day
    Global_Month  := Month
    Global_Year   := Year
    Global_Hour   := Hour
    Global_Minute := Minute
    Global_Second := Second
        Global_Millisecond := Millisecond
end

BEGIN
    fktAbsToTime(Source)
END

TimeToAbs

Funktion zum Bestimmen der Systemzeit in Sekunden seit 1.1.1970.

Funktionsdefinition: TimeToAbs(Day, Month, Year, Hour, Minute, Second, Millisecond : integer) : real

Parameter:

Day

Tag des Monats 1..31

Month

Monat des Jahres 1..12

Year

Jahr 1970..2038

Hour

Stunde des Tages 0..23

Minute

Minute der Stunde 0..59

Second

Sekunde der Minute 0..59

Millisecond

Millisekunden der Sekunde 0..999

Rückgabewerte:

>= 0

wenn kein Fehler auftritt gibt er den Zeitwert zurück

< 0

Fehlerhafte Parametrierung

Beispiel
PROGRAM

function fktTimeToAbs() : integer

var Day, Month, Year, Hour, Minute, Second, Millisecond : integer

begin
    Day     := Time(0)
    Month   := Time(1)
    Year    := Time(2)
    Hour    := Time(5)
    Minute  := Time(6)
    Second  := Time(7)
    Milllisecon := Time(8)

    fktTimeToAbs := TimeToAbs(Day, Month, Year, Hour, Minute, Second, Millisecond)
end

BEGIN
    fktTimeToAbs()
END

Time

Funktion zum Auslesen der aktuellen Systemzeit in Einzelkomponenten. Genauigkeit von 1 Sekunde

Funktionsdefinition: Time(Index : integer) : integer

Parameter:

Index

Index des Zeiteintrages

Bereich

0

Tag

1..31

1

Monat

1..12

2

Jahr

1970…

3

Tag der Woche 0 = Sonntag

0..6

4

Tag des Jahres

1..365

5

Stunde am Tag

0..23

6

Minute der Stunde

0..59

7

Sekunde der Minute

0..59

8

Zeit in Sekunden seit 1970

0..2^31

9

Millisekunden

0..999

10

Zeit in Sekunden seit 1970 mit Sommerzeitoffset ohne Zeitzonenoffset

0..2^31

11

Zeit in Sekunden seit 1970 mit Zeitzonenoffset ohne Sommerzeitoffset

0..2^31

12

Zeit in Sekunden seit 1970 ohne Zeitzonenoffset und Sommerzeitoffset (liefert UTC-Zeit)

0..2^31

Rückgabewerte:

-1

wenn Index nicht gültig ist

sonst

Wert des Zeiteintrags

Beispiel
PROGRAM

function fktTime() : integer

var Day, Month, Year, Day_W, Day_Y : integer
var Hour, Minute, Second, Second1970, Millisecond : integer

begin
    Day          := Time(0)
    Month        := Time(1)
    Year         := Time(2)
    Day_W        := Time(3)
    Day_Y        := Time(4)
    Hour         := Time(5)
    Minute       := Time(6)
    Second       := Time(7)
    Second1970   := Time(8)
    Millisecond  := Time(9)
end

BEGIN
    fktTime()
END

TimeUtcToLocal

Wandelt die absolute Zeit von UTC-Zeit zur lokalen Zeit um. Setzt voraus, dass die angegebene Zeit UTC ist.

Funktionsdefinition: TimeUTCToLocal(Var integer : absTime)

Parameter:

AbsTime

Absolute Systemzeit in Millisekunden seit 1.1.1970

Rückgabewerte:

-1

wenn Index nicht gültig ist

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktTimeUtcToLocal(AbsTime : integer) : integer

(*
AbsTime: 957503105005
AbsTimereturn: 957510305005
2 hours shift
*)

var Error :integer
begin
        Error := TimeUtcToLocal(AbsTime)
end
BEGIN
        fktTimeUtcToLocal(Source)
END

TimeLocalToUtc

Wandelt die absolute Zeit von der lokalen Zeit zur UTC-Zeit um. Setzt voraus, dass die angegebene Zeit die lokale ist.

Funktionsdefinition: TimeLocalToUtc(Var integer : absTime)

Parameter:

AbsTime

Absolute Systemzeit in Millisekunden seit 1.1.1970

Rückgabewerte:

-1

wenn Index nicht gültig ist

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktTimeLocalToUtc(AbsTime : integer) : integer

(*
AbsTime: 957503105005
AbsTime return: 957495905005
2 hours shift
*)

var Error :integer
begin
        Error := TimeLocalToUtc(AbsTime)
end
BEGIN
        fktTimeLocalToUtc(Source)
END

DateAdd

Funktion zum Addieren von spezifischen Zeitspannen auf die absolute Systemzeit.

Funktionsdefinition: DateAdd(Var integer AbsTime, integer Version, integer Addition)

Parameter:

AbsTime

Absolute Systemzeit in Milliekunden seit 1.1.1970

Version

Numerische Unterscheidung der Art der Addition

0

Millisekunden

1

Sekunden

2

Minuten

3

Stunden

4

Tage

5

Monate

6

Jahre

Addition

Numerische Menge welche addiert wird

Rückgabewerte:

-2

Falsche Version

-1

Fehlerhafte Parametrierung

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktDateAdd(Milliseconds : real) : integer

(*
AbsTime: 957503105005
Version:5 (month)
Addition:5
Date return:970722305005
*)

var Error :integer
begin
        Error := DateAdd(AbsTime, Version, Addition)
end
BEGIN
        fktDateToString(Source,  Version, Addition)
END

DateStringAdd

Funktion zum Addieren von spezifischen Zeitspannen auf die absolute Systemzeit.

Funktionsdefinition: DateStringAdd(Var string: Date,string : Format, integer Version, integer Addition)

Parameter:

Date

Datum, welches als Grundlage genommen wird

Version

Numerische Unterscheidugn der Art der Addition

0

Millisekunden

1

Sekunden

2

Minuten

3

Stunden

4

Tage

5

Monate

6

Jahre

Addition

Numerische Menge welche addiert wird

Rückgabewerte:

-3

Falsches Format

-2

Falsche Version

-1

Fehlerhafte Parametrierung

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktDateStringAdd(Milliseconds : real) : integer

(*
Date: 05.05.2000 05:05:05:0050
Format:MM.dd.yyyy HH:mm:ss:ffff
Version:5 (month)
Addition:5
Date return:10.05.2000 05:05:05:0050
*)

var Error :integer
begin
        Error := DateStringAdd(Date, Format, Version, Addition)
end
BEGIN
        fktDateToString(Source, Format, Version, Addition)
END

DateToString

Funktion zum Umwandeln von Datums- und Zeitangagben in einen String. Genauigkeit von 1 Sekunde

Funktionsdefinition: DateToString(integer: AbsTime,string : Format, Var string: Date)

Parameter:

AbsTime

Absolute Systemzeit in Millisekunden seit 1.1.1970

Format

Format des Datum-Strings

Date

Formatiertes Datum

Format

Parameter DateTime

Rückgabewerte:

-3

Falsches Format

-2

Das Datum ist zu groß (nicht in IoT vorhanden)

-1

Fehlerhafte Parametrierung

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

PROGRAM

function fktDateToString(Milliseconds : real) : integer

(*
Abstime: 957503105005
Format:MM.dd.yyyy HH:mm:ss:ffff
Datestring:05.05.2000 05:05:05:0050
*)

var Error :integer
begin
        Error := DateToString(Abstime, Format, Datestring)
end
BEGIN
        fktDateToString(Source)
END

DateToAbs

Funktion zum Umwandeln von einem Datum im String-Format zu einem Absolutwert.

Funktionsdefinition: DateToAbs(string: Date,string : Format, Var integer: AbsTime)

Parameter:

Date

Formatiertes Datum

Format

Format des Datum-Strings

AbsTime

Absolute Systemzeit in Sekunden seit 1.1.1970

Format

Parameter DateTime

Rückgabewerte:

-2

Falsches Format

-1

Fehlerhafte Parametrierung

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktDateToString(Milliseconds : real) : integer

(*
Datestring: 05.05.2000 05:05:05:0050
Format:MM.dd.yyyy HH:mm:ss:ffff
AbsTime:957503105005
*)

var Error :integer
begin
        Error := DateToAbs(Datestring, Format, AbsTime)
end
BEGIN
        fktDateToString(Source)
END

TimespanToString (nur SCADA)

Funktion zum Umwandeln von Millisekunden zu Sekunden, Stunden und Minuten

Funktionsdefinition: TimespanToString(integer: Milliseconds, string: Format, Var string: Timespan)

Parameter:

Millisecons

Umzuwandelnde Millisekunden

Format

Formatstring der Zeitspanne

Timespan

Zeitspanne als String

Rückgabewerte:

-3

Falsches Format

-2

Das Datum ist zu groß

-1

Fehlerhafte Parametrierung

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

function fktTimespanToString(Milliseconds : real) : integer

(*
Milliseconds: 1535486000
= 17 days, 18 hours, 31 minutes, 26 seconds
Format:dd\.hh\:mm\:ss
Resultstring:17.18:31:26
*)

var Error :integer
begin
        Error := TimespanToString(Milliseconds, Format, Resultstring)
end
BEGIN
        fktTimespanToString(Source)
END

Benutzerverwaltungsfunktionen (nur SCADA)

Login

Funktion zum Login (Anmelden) eines Benutzers.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: Login(User, Password : string) : integer

Parameter:

User

Name des Benutzers

Password

Passwort des Benutzers

Rückgabewerte:

1

Login erfolgreich, bei nächster Anmeldung neues Passwort erforderlich

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Zugriff verweigert

-2

Unbekannter User/Passwort

-3

Fehlerhafte Passworteingabe, Account wird bei erneuter Falscheingabe gesperrt

-4

Account gesperrt

-5

Passwort abgelaufen

Beispiel
PROGRAM

function loginMeister(passWD : string) : integer

begin
    loginMeister := Login('Meister', passWD)
end

BEGIN
    loginMeister('MstPss')
END

Logout

Funktion zum Logout (Abmelden) des aktuellen Benutzers.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: Logout() : integer

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn kein Logout möglich ist

Beispiel
PROGRAM

function loginOut() : integer

begin
    loginOut:= Logout()
end

BEGIN
    loginOut()
END

Es stehen auch folgende Funktionen für das Benutzermanagement zur Verfügung:

  • SetUserPassword

  • CreateUser

  • DeleteUser

  • SetUserGroup

  • GetUserGroup

  • SetUserInfo

  • GetUserInfo

Important

Es ist wichtig zu beachten, dass die Funktionen IMMER im jeweiligen Kontext des ausführenden Benutzers durchgeführt werden, daher funktionieren die Funktionen aktuell nur im Context eines Clients,

d.h. sie können z.B. von Button-Clicks oder Bildscripts innerhalb eines Clients im Context des jeweils angemeldeten Benutzers ausgeführt werden, allerdings NICHT als globale Tasks, da im Servercontext kein Benutzer existiert, mit dem das Benutzermanagement die Erlaubnis zur Abarbeitung der Funktion erfragen könnte

Important

Beispiel: Im System existieren 2 Clients:

Client1, Benutzer „admin“ angemeldet. Er befindet sich in der Benutzergruppe „Administratoren“, die das Recht besitzt, Benutzer anzulegen (Systemrecht > Benutzerverwaltung > Neue Benutzer anlegen)

Client2, Benutzer „guest“ angemeldet. Er befindet sich in der Benutzergruppe „Guests“, die das Recht NICHT besitzt Führt Client1 die Funktion CreateUser() aus wird ein neuer Benutzer erzeugt, falls dieser noch nicht vorhanden war und als Ergebnis noError (0) zurückgeliefert

Führt Client2 die Funktion CreateUser() aus, wird KEIN neuer Benutzer erzeugt, weil der Benutzer „guest“ das Recht dazu nicht besitzt und als Fehler wird permissionDenied (-1) zurückgeliefert. Dies würde auch passieren, wenn eine globale Task die Funktion ausführt, weil dort kein gültiger Benutzer zur Verifizierung existiert.

Alle Funktionen liefern dieselben Returnwerte zurück, die direkt aus der Benutzerverwaltung von PROCONWEB zurückgeliefert werden. Manche Fehlercodes gibt es nur in speziellen Kontexten, aber das sind alle möglichen Fehlercodes, die bei den Funktionen auftreten können.

Bei jedem Fehlercode <> noError (0) wurde die gewünschte Funktionalität NICHT ausgeführt. Alle Funktionen liefern wie die anderen Systemfunktionen auch 0 bei erfolgreicher Abarbeitung zurück, ansonsten wird einer der folgenden Fehlercodes zurückgeliefert:

Fehlercode

Rückgabewert

Beschreibung

noError

0

Funktion erfolgreich ausgeführt

permissionDenied

-1

Keine Erlaubnis die Funktion auszuführen

unkno wnUserOrWrongPassword

-2

Unbekannter Benutzer oder falsches Passwort

wrong PasswordAccountClosed

-3

Falsches Benutzerpassword, der Account wurde deaktiviert

accountClosed

-4

Account ist deaktiviert

passwordExpired

-5

Passwort ist abgelaufen

nameAlreadyUsed

-6

Der Name wird bereits verwendet

invalidUserInfo

-7

Ungültige Benutzer Info

changeUserDenied

-8

Keine Erlaubnis, den Benutzer zu modifizieren

password PolicyNotRespected

-9

Die Passwort-Policies wurden nicht eingehalten

passwordAlreadyUsed

-10

Das Passwort wurde bereits verwendet

groupUnknown

-11

Unbekannte Benutzergruppe

group AssignmentNotAllowed

-12

Gruppenzuordnung ist nicht erlaubt

deleteUserNotAllowed

-13

15. Das Löschen des Benutzers ist nicht erlaubt

deleteUser NotAvailable

-14

Der zu Löschende Benutzer ist nicht vorhanden

deleteUserNotPossible

-15

Das Löschen des Benutzers ist nicht möglich

duplicateIdentCode

-16

Der IdentCode existiert bereits

languageNotAvailable

-17

Die angeforderte Sprache existiert nicht

unknown

-99

Unbekannter Fehler im Benutzermanagement

CreateUser

Mit dieser Funktion kann ein Benutzer erzeugt werden mit dem übergebenen Passwort. Weitere Attribute des Benutzers können erst nach erfolgreichem Anlegen eines Benutzers gesetzt werden mit der Funktion SetUserInfo().

Für die Funktion ist das Recht (5) Benutzerverwaltung -> Neue Benutzer anlegen notwendig

Wird die Funktion erfolgreich ausgeführt, wird der Logbucheintrag 10000004 Neuer Benutzer angelegt, erzeugt.

Funktionsdefinition: CreateUser(Username: string, Password: string) : integer

Parameter:

Username

Benutzername für den neuen Benutzer

Password

Initiales Passwort für den neuen Benutzer

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function CreateTestUser() : boolean
begin
    CreateUser('Test', 'Pw1*')
end

DeleteUser

Mit dieser Funktion kann ein Benutzer gelöscht. Für die Funktion ist das Recht (2) Benutzerverwaltung -> Benutzer verändern notwendig Wird die Funktion erfolgreich ausgeführt, wird der Logbucheintrag 10000005 Benutzer gelöscht, erzeugt

Funktionsdefinition: DeleteUser(Username: string) : integer

Parameter:

Username

Benutzername für den zu löschenden Benutzer

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function DeleteTestUser() : boolean
begin
    DeleteUser('Test')
end

SetUserPassword

Mit dieser Funktion kann einem Benutzer ein neues Passwort gesetzt werden. Wenn Passwortrichtlinien definiert sind, muss das zu setzende Passwort den Passwortrichtlinien entsprechen

Für die Funktion ist das Recht (3) Benutzerverwaltung -> Kennwort anderer Benutzer ändern, notwendig Wird die Funktion erfolgreich ausgeführt, wird der Logbucheintrag 10000007 Passwort geändert, erzeugt

Da die Funktion zum Ändern des Passworts eines anderen Users bestimmt ist, wird das Passwort unabhängig von der Passwort-Historie gesetzt.

Funktionsdefinition: SetUserPassword(Username: string, Password: string) : integer

Parameter:

Username

Benutzername für den das Passwort gesetzt werden soll

Password

Neues Passwort für den neuen Benutzer

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function ChangePassword() : boolean
begin
    Return := SetUserPassword('Admin', 'Admin1*')
end

GetUserGroup

Mit dieser Funktion kann überprüft werden, ob ein Benutzer zu einer Benutzergruppe zugeordnet ist oder nicht.

Important

ACHTUNG: Um die Funktion im Sinne einer Boolschen Abfrage verwenden zu können sind die Rückgabewerte verändert: Es wird eine 1 zurückgeliefert, wenn der Benutzer zur Benutzergruppe gehört, 0 falls nicht. Im Falle eines Fehlers einer der Fehlercodes.

Funktionsdefinition: GetUserGroup(Username: string, Groupname: string, CountryCode: string) : integer

Parameter:

Username

Benutzername des Benutzers, der überprüft werden soll ob er einer Grouppe zugewiesen ist

Groupname

Name der Benutzergruppe

CountryCode

Länderkennung des Gruppennamens

(z.B. 049 für Deutsch, oder Wert der Systemvariablen __CurrentLanguage)

Rückgabewerte:

0

wenn der Benutzer nicht zur Gruppe gehört

1

Wenn der Benutzer zur Gruppe gehört

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function Benutzer1Group() : boolean
var i : integer
begin
    i := GetUserGroup('Benutzer1', 'Administrators', __CurrentLanguage)

    if (i = 1) then
        IsUserAdmin := 1
    else
        IsUserAdmin := 0
end

SetUserGroup

Mit dieser Funktion kann ein Benutzer zu einer Benutzergruppe zugeordnet (Modus = 1) oder aus ihr entfernt werden (Modus = 2).

Für die Funktion ist das Recht (6) Benutzerverwaltung -> Fremde Gruppe zuweisen, notwendig Wird die Funktion erfolgreich ausgeführt, wird der Logbucheintrag 10000006 Benutzer wurde geändert, erzeugt

Funktionsdefinition: SetUserGroup(Username: string, Groupname: string, Modus : integer, CountryCode: string) : integer

Parameter:

Username

Benutzername des Benutzers, der einer Gruppe zugewiesen werden soll

Groupname

Name der Benutzergruppe

Modus

Modus 1: Benutzer einer Gruppe zuordnen

Modus 2: Benutzer aus einer Gruppe entfernen

CountryCode

Länderkennung des Gruppennamens

(z.B. 049 für Deutsch, oder Wert der Systemvariablen __CurrentLanguage)

Rückgabewerte:

0

wenn die Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function Benutzer1NotAdmin() : boolean
begin
    SetUserGroup('Benutzer1', 'Administrators', 2, __CurrentLanguage)
end

GetUserInfo

Mit dieser Funktion kann ein Attribut eines Benutzers ausgelesen und auf eine Prozessvariable geschrieben werden. Folgende Attribute können ausgelesen werden und wenn das Attribut nicht als „readonly“ markiert ist kann es auch mit der Funktion SetUserInfo() verändert werden. Die folgenden Attribut-IDs gibt es:

ID

Beschreibung

Variablentyp

0

Name des Benutzers

string

1

ID des Benutzer, nur intern, readonly

string

2

Vollständiger Name des Benutzer

string

3

Beschreibung des Benutzers, mehrsprachig

string

4

Zeitpunkt der letzten Anmeldung, readonly

Numerisch (Millisekunden seit 1970)

5

Status (1=aktiv, 2=inaktiv)

numerisch

6

Passwortalterung aktiv

bool

7

Passwort muss beim nächsten Login gewechselt werden

bool

8

Identcode für T okenauthentifizierung

string

9

Identcode aktiv (kann für Login verwendet werden)

bool

10

NotificationType (für Notifiaction)

numerisch

11

Email-Adresse des Benutzers

string

12

Telefon-Nummer des Benutzers

string

13

Mobilfunk-Nummer des Benutzer

  1. string

14

Flag, ob der Benutzer ein LDAP Benutzer ist

bool

15

Default-Sprache des Benutzers

string

16

Bei Identcode, trotzdem Login anzeigen

bool

Die Beschreibung des Benutzers ist mehrsprachig, soll sie für mehrere Sprachen gesetzt werden muss die Funktion mehrfach, jeweils mit der entsprechenden Länderkennung als Parameter aufgerufen werden

Als Default-Sprache des Benutzers ist die Länderkennung als Text anzugeben, also z.B. 049 für Deutsch oder 044 für Englisch. Die Länderkennung wird im Designer bei der Sprachauswahl konfiguriert.

Für das Setzen des NotificationType gibt es folgende Typen (siehe Notification):

NotificationType

Beschreibung

4

Voice

28

CityCall

44

SMS GSM

66

Voice ISDN

85

CityCall ISDN

10000

Email WithNumerInSubject

10001

Email

20000

Sipgate SMS

Funktionsdefinition: GetUserInfo(Username: string, InfoId: integer, var variable: undef, CountryCode: string) : integer

Parameter:

Username

Benutzername des Benutzers, dessen Info gelesen werden soll

InfoID

ID des Atrributs (siehe obige Tabelle)

Variable

Prozessvariable vom passenden Typ (string, num, bool)

CountryCode

Länderkennung des Gruppennamens

(z.B. 049 für Deutsch, oder Wert der Systemvariablen __CurrentLanguage)

Nur bei der InfoID für die Beschreibung werden unterschiedliche Werte geliefert

Rückgabewerte:

0

wenn die Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function AdminInfoAnfordern() : boolean
begin
    GetUserInfo('Admin', 0, Benutzername, __CurrentLanguage)
    GetUserInfo('Admin', 1, BenutzerID, __CurrentLanguage)
    GetUserInfo('Admin', 2, BenutzernameFull, __CurrentLanguage)
    GetUserInfo('Admin', 3, BenutzerBeschreibung, __CurrentLanguage)
    GetUserInfo('Admin', 4, BenutzerLetzterLogin, __CurrentLanguage)
    GetUserInfo('Admin', 5, BenutzerStatus, __CurrentLanguage)
    GetUserInfo('Admin', 6, PasswortalterungAktiv, __CurrentLanguage)
    GetUserInfo('Admin', 7, PasswortWechsel, __CurrentLanguage)
    GetUserInfo('Admin', 8, BenutzerIdentcodeToken, __CurrentLanguage)
    GetUserInfo('Admin', 9, BenutzerIdentcodeAktiv, __CurrentLanguage)
    GetUserInfo('Admin', 10, BenutzerNotificationTyp, __CurrentLanguage)
    GetUserInfo('Admin', 11, BenutzerEmail, __CurrentLanguage)
    GetUserInfo('Admin', 12, BenutzerTel, __CurrentLanguage)
    GetUserInfo('Admin', 13, BenutzerMobiltel, __CurrentLanguage)
    GetUserInfo('Admin', 14, BenutzerLDAP, __CurrentLanguage)
    GetUserInfo('Admin', 15, BenutzerDefaultsprache, __CurrentLanguage)
    GetUserInfo('Admin', 16, BenutzerIdentcodeLogin, __CurrentLanguage)
end

SetUserInfo

Mit dieser Funktion kann ein Attribut eines Benutzers gesetzt werden.

Die bei der Funktion GetUserInfo() aufgelisteten Attribute können gesetzt werden, wenn sie nicht als „readonly“ markiert sind. Der Versuch, ein readonly Attribut zu schreiben führt zum Fehler 7 – invalid User Info Für die Funktion ist das Recht (2) Benutzerverwaltung -> Benutzer verändern, notwendig

Wird die Funktion erfolgreich ausgeführt, wird der Logbucheintrag 10000006 Benutzer wurde geändert, erzeugt

Funktionsdefinition: SetUserInfo(Username: string, InfoId: integer, variable: undef, CountryCode: string) : integer

Parameter:

Username

Benutzername des Benutzers, dessen Info geschrieben werden soll

InfoID

ID des Attributs (siehe Tabelle Attribute von der Funktion GetUserInfo)

Variable

Prozessvariable vom passenden Typ (string, num, bool)

CountryCode

Länderkennung des Gruppennamens

(z.B. 049 für Deutsch, oder Wert der Systemvariablen __CurrentLanguage)

Nur bei der InfoID für die Beschreibung werden unterschiedliche Werte geliefert

Rückgabewerte:

0

wenn die Funktion erfolgreich ausgeführt wurde

Oder einen der allgemeinen Fehler der Benutzerverwaltung (siehe Tabelle oben)

Beispiel
function AdminInfoSetzen() : boolean
begin
    SetUserInfo('Admin', 0, Benutzername, __CurrentLanguage)
    SetUserInfo('Admin', 2, BenutzernameFull, __CurrentLanguage)
    SetUserInfo('Admin', 3, BenutzerBeschreibung, __CurrentLanguage)
    SetUserInfo('Admin', 5, BenutzerStatus, __CurrentLanguage)
    SetUserInfo('Admin', 6, PasswortalterungAktiv, __CurrentLanguage)
    SetUserInfo('Admin', 7, PasswortWechsel, __CurrentLanguage)
    SetUserInfo('Admin', 8, BenutzerIdentcodeToken, __CurrentLanguage)
    SetUserInfo('Admin', 9, BenutzerIdentcodeAktiv, __CurrentLanguage)
    SetUserInfo('Admin', 10, BenutzerNotificationTyp, __CurrentLanguage)
    SetUserInfo('Admin', 11, BenutzerEmail, __CurrentLanguage)
    SetUserInfo('Admin', 12, BenutzerTel, __CurrentLanguage)
    SetUserInfo('Admin', 13, BenutzerMobiltel, __CurrentLanguage)
    SetUserInfo('Admin', 15, BenutzerDefaultsprache, __CurrentLanguage)
    SetUserInfo('Admin', 16, BenutzerIdentcodeLogin, __CurrentLanguage)
end

Bildverarbeitungsfunktion

Wenn die Bildverarbeitungsfunktionen von einem Client aufgerufen werden (Bild- oder Control-Events), so werden die entsprechenden Bildverarbeitungsfunktionen nur für diesen Client ausgeführt. Wenn die Funktionen im globalen Skripting (globale Tasks) ausgeführt werden, werden die Bildverarbeitungsfunktionen für ALLE aktuell angemeldeten Clients ausgeführt. So können z.B. systemweite Meldungen auf allen Clients angezeigt werden.

Bei Bildern mit Bildskripten (zyklisches Skript) wird dieses in folgenden Fällen abgearbeitet:

  • Beim öffnen des Bildes z.B. über einen Taster

  • Beim offenen Bild dieses auf „unsichtbar“ setzen

  • Bei einem Bild in einer Picture Area und dieses auf „unsichtbar“ setzen

Beim Schließen und Leeren eines Bildbereiches wird das Skript nicht abgearbeitet. Das gilt auch für die bisherigen, jetzt wieder lauffähigen Funktionen.

Important

Alle Funtionen liefern aktuell immer den Wert 0 zurück!

AddPicture

Funktion zum Hinzufügen eines Prozessbildes an einer bestimmten Position und mit einer definierten Größe auf dem Bildschirm.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Important

AddPicture unterstützt ab der Version 6.8 nur den 2. Parameter (Number) sowie den 3. und 4. optionalen Paremeter (XPos und YPos)

Funktionsdefinition: AddPicture(Picture, Number, XPos, YPos : integer): integer

Parameter:

Picture

Nummer des Bildes aus dem heraus hinzugefügt werden soll

Number

Nummer des Bildes das hinzugefügt werden soll

XPos, YPos

  • Position des Bildes (linke obere Ecke) auf dem Bildschirm wenn Prozessbild,

  • Position des Bildes (linke obere Ecke) auf dem im Vaterfenster wenn Kindbild

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn Parametrierfehler

-2

wenn hinzugefügtes Bild nicht existiert

-3

wenn Benutzerlevel zu niedrig

Beispiel
PROGRAM

function AddMyPicture: integer

var vaterbild, kindbild, xpos, ypos, breite, höhe, flag: integer
var Error : integer
begin
    vaterbild := Vater
    kindbild := Kind
    xpos := XPOS
    ypos := YPOS
    breite := Breite
    höhe := Höhe
    flag := 3

    Error := AddPicture(vaterbild, kindbild, xpos, ypos, breite, höhe, flag)
end

BEGIN
    AddMyPicture()
END

ChangePicture

Funktion zum Wechseln in ein anderes Prozessbild.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: ChangePicture(PictNumberOld, PictNumberNew, XPos, YPos : integer): integer

Parameter:

PictNumberOld

Bildnummer des Bildes aus dem gewechselt werden soll, Bildnummer von 0 bis 65520

PictNumberNew

Nummer des Bildes in das gewechstelt werden soll; Bildnummer von 0 bis 65520

XPos, YPos

  • Position des Bildes (linke obere Ecke) auf dem Bildschirm wenn Prozessbild,

  • Position des Bildes (linke obere Ecke) auf dem im Vaterfenster wenn Kindbild

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Bildwechsel nicht möglich

-3

Bildnummer des Bildes aus dem gewechselt werden soll ist ungültig

Beispiel
PROGRAM

var pictnumberOld, pictnumberNew : integer
var Error : integer

BEGIN
    if BildWechsel then
    begin
        BildWechsel:=0
        pictnumberOld := 0
        pictnumberNew :=10
        Error := ChangePicture(pictnumberOld, pictnumberNew)
    end
END

NewPicture

Funktion zum Hinzufügen eines Prozessbildes, bzw. Funktion zum Wechseln in ein anderes Prozessbild.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: NewPicture(Function, PictNumber : integer): integer

Parameter:

Function

0 = Hinzufügen eines neuen Bildes

1 = Bildwechsel auf Bild

PictNumber

Nummer des Bildes das hinzugefügt werden soll;

Bildnummer von 0 bis 65520

XPos, YPos

Position des Bildes (linke obere Ecke) auf

dem Bildschirm wenn Prozessbild, Position des Bildes (linke obere Ecke) auf

dem im Vaterfenster wenn Kindbild

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn Fenster nicht gefunden

-2

wenn Funktion nicht korrekt

-3

wenn Bildnummer nicht korrekt

Beispiel
PROGRAM

var mode, pictnumber : integer
var Error : integer

BEGIN
    if NeuesBild then
    begin
        NeuesBild := 0
        pictnumber :=10
        mode := 1
        Error := NewPicture(mode, pictnumber)
        If Error <> 0 then
        begin
            Alert(1,400) (* Error executing the function *)
            Alert(2,400)
        end
    end
END

OpenPicture

Mit dieser Funktion kann ein Bild anhand des Bildnamens oder der Bildnummer geöffnet werden. Der Parameter ist immer ein String, kann aber entweder den Bildnamen oder die Bildnummer als String enthalten.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: OpenPicture(PictureNameOrNumber : string): integer

Parameter:

PictureNameOrNumber

Name oder Nummer des Bildes als String

Rückgabewerte:

0

wenn Fuktion erfolgreich ausgeführt wurde

-1

Bild konnte nicht geladen werden (Bild nicht vorhanden)

-2

Bild ist bereits offen

-3

Bildaufruf ist bereits im Gange und wurde währenddessen erneut aufgerufen

Beispiel
PROGRAM

var Error : integer

Function OpenMyPicture(pict : string) : integer

var Error : integer

Begin
    Error := OpenPicture(pict)
    If Error <> 0 then
    begin
        Alert(1,400) (* Error executing the function *)
        Alert(2,400)
    end

    OpenMyPicture := Error
End

BEGIN
    (* Open picture by name *)
    Error := OpenMyPicture('Uebersicht')

    If Error <> 0 then
    begin
        (* Open picture by number *)
        Error := OpenMyPicture('0004')
    END

    If Error <> 0 then
    begin
        (* Open picture by number *)
        Error := OpenMyPicture('4')
    END
END

ClosePicture

Mit dieser Funktion kann ein Bild anhand des Bildnamens oder der Bildnummer geschlossen werden. Der Parameter ist immer ein String, kann aber entweder den Bildnamen oder die Bildnummer als String enthalten.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: ClosePicture(PictureNameOrNumber : string): integer

Parameter:

PictureNameOrNumber

Name oder Nummer des Bildes als String

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Bild konnte nicht geschlossen werden (Bild nicht gefunden/vorhanden)

Beispiel
PROGRAM

var Error : integer

Function CloseMyPicture(pict : string) : integer

var Error : integer

Begin
    Error := ClosePicture(pict)
    If Error <> 0 then
    begin
        Alert(1,400) (* Error executing the function *)
        Alert(2,400)
    end

    CloseMyPicture := Error
End

BEGIN
    (* Close picture by name *)
    Error := CloseMyPicture('Uebersicht')

    If Error <> 0 then
    begin
        (* Close picture by number *)
        Error := CloseMyPicture('0004')
    END

    If Error <> 0 then
    begin
        (* Close picture by number *)
        Error := CloseMyPicture('4')
    END
END

PrintPicture

Mit dieser Funktion kann ein Bild anhand des Bildnamens oder der Bildnummer gedruckt werden. Der Parameter ist immer ein String, kann aber entweder den Bildnamen oder die Bildnummer als String enthalten.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: PrintPicture(PictureNameOrNumber : string): integer

Parameter:

PictureNameOrNumber

Name oder Nummer des Bildes als String

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

var Error : integer

Function PrintMyPicture(pict : string) : integer

Begin
    Error := PrintPicture(pict)
    If Error <> 0 then
    begin
        Alert(1,400) (* Error executing the function *)
        Alert(2,400)
    end

    PrintMyPicture := Error
End

BEGIN
    (* Close picture by name *)
    Error := PrintMyPicture('Uebersicht')

    If Error <> 0 then
    begin
        (* Close picture by number *)
        Error := PrintMyPicture('0004')
    END

    If Error <> 0 then
    begin
        (* Close picture by number *)
        Error := PrintMyPicture('4')
    END
END

ChangeAllPictures

Mit dieser Funktion werden alle sichtbaren Bilder geschlossen und das neue Bild geöffnet. Der Parameter ist immer ein String, kann aber entweder den Bildnamen oder die Bildnummer als String enthalten.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: ChangeAllPictures(PictureNameOrNumber : string): integer

Parameter:

PictureNameOrNumber

Name oder Nummer des Bildes als String

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

var Error : integer

Function ChangeMyPicture(pict : string) : integer

var Error : integer

Begin
    Error := ChangeAllPictures(pict)
    If Error <> 0 then
    begin
        Alert(1,400) (* Error executing the function *)
        Alert(2,400)
    end

    ChangeMyPicture := Error
End

BEGIN
    (* Print picture by name *)
    Error := ChangeMyPicture('Uebersicht')

    If Error <> 0 then
    begin
        (* Print picture by number *)
        Error := ChangeMyPicture('0004')
    END

    If Error <> 0 then
    begin
        (* Print picture by number *)
        Error := ChangeMyPicture('4')
    END
END

FillPictureArea

Durch diesen Befehl wird der Inhalt einer PictureArea gelöscht und mit den angegebenen Bildern neu befüllt.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegennimmt! Der Befehl darf jedoch nicht zyklisch aufgerufen werden, da dies zu einer hohen Systemauslastung führt!

Funktionsdefinition: FillPictureArea(PictureAreaId, PictureList : string): integer

Parameter:

PictureAreaId

Name der PictureArea-Instanz im Bild

PictureList

Liste von Bildnamen, mit denen die Area gefüllt werden soll. Die Namen müssen durch Strichpunkt getrennt sein

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Bildbereich mit dem gegebenen Namen wurde nicht gefunden

-2

Es sind mehre Bildbereiche mit dem gleichen Namen gefunden worden

-3

Es ist ein Fehler beim Laden/Zuweisen der Bilder aufgetreten (Bild nicht gefunden/vorhanden)

Beispiel
PROGRAM

BEGIN
    FillPictureArea('P_Area', 'Bild1;Bild2;Bild3')
END

FillImageView

Löscht ein ImageView, befüllt es mit den angegebenen Grafiken neu und zeigt die Grafik mit dem entsprechenden Index an. Die Imagedatei muss im WebVisu-Verzeichnis des Projektverzeichnisses liegen. Alternativ können die Dateien von extern mit einem Startskript in das WebVisu-Verzeichnis hineinkopiert werden.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren, das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt! Die Instanz des ImageView muss innerhalb des Projektes einmalig sein!

Funktionsdefinition: FillImageView(ImageViewId, ImageList : string, Index : integer): integer

Parameter:

ImageViewId

Name der ImageView-Instanz im Bild

ImageList

Liste von Grafiknamen, mit denen die Area gefüllt werden soll. Die Namen müssen durch Strichpunkt getrennt sein

Index

Index der Grafik, die angezeigt werden soll. Der Index ist 0 basierend und muss zwischen 0 und der Anzahl der übergebenen Grafiken - 1 sein

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

BEGIN
    FillImageView('ImageView1', 'Bitmap1; Bitmap2; Bitmap3', 0)
END

Prozessvariablen-Funktionen

ReadFromProcess

Mit dieser Funktion werden die im Skript verwendeten Prozessvariablen aktuell vom TagServer gelesen. Über den Parameter sync kann festgelegt werden, ob das Lesen synchron oder asynchron erfolgt. Beim synchronen Lesen wartet das Skript bis alle Werte gelesen wurden und fährt dann mit der Abarbeitung fort.

Attention

Ein synchrones Lesen kann sehr zeitintensiv sein, da die Prozessvariablen bis zur Steuerung synchronisiert werden.

Important

ReadFromProcess sollte nur in Ausnahmefällen eingesetzt werden, da der SkriptServer zu Beginn eines Skriptes bereits liest und auch bei allen Kontextswitches zu anderen Servern (Datenverwaltung, Alarming …) unnötiges Lesen von Prozessvariablen aus Performancegründen vermieden werden sollte.

Funktionsdefinition: ReadFromProcess(Sync: integer) : integer

Parameter:

Sync

1: liest die Werte vom Prozess synchron, d.h. das Skript wartet mit der Abarbeitung, bis alle Werte zurückgeliefert wurden

<>1: liest die Werte Asynchron, d.h. das Lesen der Werte wird getriggert, aber die Skriptabarbeitung läuft direkt weiter ohne zu warten bis die Werte tatsächlich gelesen wurden

Rückgabewerte:

1

wenn die Funktion erfolgreich durchlaufen wurde

Beispiel
PROGRAM

FUNCTION Nochmal: integer

var p : integer

begin
    for p:=21 downto 0 do
    begin
        (* Read values from the process *)
        ReadFromProcess(1)
        while XY_Feld[p] > 0 do
            XY_Feld[p] := XY_Feld[p] - 1
        (* Values are now written to the process immediately *)
        WriteToProcess(1)
    end
end

BEGIN
    Nochmal()
END

WriteToProcess

Mit dieser Funktion werden die im Skript verwendeten Prozessvariablen aktuell zum TagServer geschrieben. Über den Parameter sync kann festgelegt werden, ob das Schreiben synchron oder asynchron erfolgt. Beim synchronen Schreiben wartet das Skript bis alle Werte geschrieben wurden und fährt dann mit der Abarbeitung fort.

Attention

Ein synchrones Schreiben kann sehr zeitintensiv sein, da die Prozessvariablen bis zur Steuerung synchronisiert werden.

Important

WriteToProcess sollte nur in Ausnahmefällen eingesetzt werden, da der SkriptServer am Ende eines Skriptes bereits schreibt und auch bei allen Kontextswitches zu anderen Servern (Datenverwaltung, Alarming, …) unnötiges Schreiben von Prozessvariablen aus Performancegründen vermieden werden sollte.

Funktionsdefinition: WriteToProcess(Sync: integer) : integer

Parameter:

Sync

1: schreibt die Werte zum Prozess synchron, d.h. das Skript wartet mit der Abarbeitung, bis alle Werte geschrieben wurden

<>1: schreibt die Werte Asynchron, d.h. das Schreiben der Werte wird getriggert, aber die Skriptabarbeitung läuft direkt weiter ohne zu warten bis die Werte tatsächlich geschrieben wurden

Rückgabewerte:

1

wenn die Funktion erfolgreich durchlaufen wurde

Beispiel
PROGRAM

FUNCTION Nochmal: integer

var p : integer

begin
    for p:=21 downto 0 do
    begin
        while XY_Feld[p] > 0 do
            XY_Feld[p] := XY_Feld[p] - 1
        (* Values are now written to the process immediately *)
        WriteToProcess(1)
    end
end

BEGIN
    Nochmal()
END

GetTagProperty

Mit den beiden Skript-Funktionen GetTagProperty und SetTagProperty können die neuen Tag-Properties gelesen oder geschrieben werden. Zusätzlich können mit den Funktionen auch die Properties Min, Max, MinSPS, MaxSPS und die Anzahl Nachkommastellen für numerische Werte beschrieben werden.

Attention

Werden Prozessvariablen ausschließlich im Skripting über die dynamischen Funktionen GetValue(), SetValue(), GetTagProperty() und SetTagProperty() verwendet und sonst NIRGENDWO anders im Projekt, werden sie vom Designer als nicht referenziert erkannt, da der Zugriff bei diesen Funktionen dynamisch zur Laufzeit über den Namen funktioniert und NICHT über eine feste Referenz.

Dies kann man erkennen, wenn man sich alle Referenzen der Prozessvariable anzeigen lässt und diese sind dann leer und somit wird die Variable nicht für die Laufzeit exportiert Das führt zur Laufzeit zum Returnwert -2 bei den oben genannten Funktionen.

Die folgenden TagProperties können dabei über ihre ID angesprochen werden:

Name

ID

Hinweis

Min

200

Typ numerisch, nur für numerische Prozessvariablen gültig

Max

201

Typ numerisch, nur für numerische Prozessvariablen gültig

MinExt

202

Typ numerisch, nur für numerische Prozessvariablen gültig

MaxExt

203

Typ numerisch, nur für numerische Prozessvariablen gültig

DecimalPlaces

205

Typ numerisch, nur für numerische Prozessvariablen gültig

Num1

500

Typ numerisch

Num2

510

Typ numerisch

Num3

520

Typ numerisch

Num4

530

Typ numerisch

Bool1

540

Typ logisch

Bool2

550

Typ logisch

String1

560

Typ Text

String2

570

Typ Text

Die folgenden zusätzlichen TagProperties können dabei READONLY über ihre ID angesprochen werden:

Name

ID

Hinweis

Name

1

Typ Text

ID

2

Typ numerisch

Size

3

Typ numerisch, Array-Länge oder String-Länge, sonst 1

DriverID

4

Typ numerisch, Nummer des Treibers

DefaultValue

5

Typ numerisch logisch oder Text, je nach Prozessvariable

Access

6

Typ numerisch, 1 = write, 2 = read, 3 = readwrite

External Access

7

Typ numerisch, 0= none, 1 = write, 2 = read, 3 = readwrite, wenn Zugriff über OPC UA Server erfolgt

Type

8

Typ numerisch, 1 = logisch, 2 = numerisch, 3 = Text

Treiberparameter

9

Typ Text

Treiber Verbindung

10

Typ numerisch, bei ve rbindungsorientierten Treibern

AnzeigeName

11

Typ Text, Name in der aktuell eingestellten Sprache

AnzeigeKommentar

12

Typ Text, Kommentar in der aktuell eingestellten Sprache

EinheitName

13

Typ Text, Name der Einheit

Einheit

14

Typ Text, Einheit in der aktuell eingestellten Sprache

Einheit Beschreibung

15

Typ Text, Beschreibung der Einheit in der aktuell eingestellten Sprache

Kommentar

16

Typ Text, Projektierungs-Kommentar

Funktionsdefinition: GetTagProperty(TagName: string, PropertyId: integer, Value: var undef) : integer

Parameter:

TagName

Name der Prozessvariable

PropertyId

Id / Nummer des Properties

Value

Wert des Properties

boolean für logische Properties

real für numerische Properties

string für Text-Properties

Es dürfen nur echte Variablen, keine Instanzen verwendet werden

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

allgemeiner Fehler

-2

ungültige Prozessvariable

-3

ungültiges Property

Beispiel
PROGRAM

Var TagMin, TagMax : Integer
Var BooProp1 : Integer

BEGIN
    (* read the min / max value of the variable 'NumVar01' *)
    GetTagProperty('NumVar01', 200, TagMin)
    GetTagProperty('NumVar01', 201,  TagMax)

    (* read the tag property 'Num1' of the variable 'BooVar01' *)
    GetTagProperty('BooVar01', 500, BooProp1)
END

SetTagProperty

Mit den beiden Skript-Funktionen GetTagProperty und SetTagProperty können die neuen Tag-Properties gelesen oder geschrieben werden. Zusätzlich können mit den Funktionen auch die Properties Min, Max, MinSPS, MaxSPS und die Anzahl Nachkommastellen für numerische Werte beschrieben werden.

Für die Parameter der Tag-Properties siehe Funktion GetTagProperty.

Important

Beim Setzen eines Bereichsproperties (Min, Max, MinExt, MaxExt, DecimalPlaces) einer numerischen Variablen kann es dazu führen, dass der aktuelle Variablenwert angepasst wird. Desweiteren werden bei Arrays beim Ändern von z.B. des maxvalue alle Tags auf den neuen Maxwert angepasst. Soll dies nur für ein Element passieren, muss der Index angegeben werden.

Attention

Werden Prozessvariablen ausschließlich im Skripting über die dynamischen Funktionen GetValue(), SetValue(), GetTagProperty() und SetTagProperty() verwendet und sonst NIRGENDWO anders im Projekt, werden sie vom Designer als nicht referenziert erkannt, da der Zugriff bei diesen Funktionen dynamisch zur Laufzeit über den Namen funktioniert und NICHT über eine feste Referenz.

Dies kann man erkennen, wenn man sich alle Referenzen der Prozessvariable anzeigen lässt und diese sind dann leer und somit wird die Variable nicht für die Laufzeit exportiert. Das führt zur Laufzeit zum Returnwert -2 bei den oben genannten Funktionen.

Funktionsdefinition: SetTagProperty(TagName: string, PropertyId: integer, Value: var undef) : integer

Parameter:

TagName

Name der Prozessvariable

PropertyId

Id / Nummer des Properties

Value

Wert des Properties

boolean für logische Properties

real für numerische Properties

string für Text-Properties

Es dürfen nur echte Variablen, keine Instanzen verwendet werden

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

ungültige Prozessvariable

-2

ungültiges Property

Beispiel
PROGRAM

BEGIN
    (* set the min / max value of the variable 'NumVar01' *)
    SetTagProperty('NumVar01', 200, -1000)
    SetTagProperty('NumVar01', 201,  1000)

    (* set the tag property 'Num1' of the variable 'BooVar01' *)
    SetTagProperty('BooVar01', 500, 99)
END

GetValue

Funktion zum Erfragen von Variablenwerten über den Variablennamen, der auch dynamisch zusammengebaut werden kann. Befindet sich die Variable NICHT in der aktuellen Anforderungsliste, wird sie automatisch für den Zeitraum der Ausführung in die Anforderungsliste übernommen.

Array-Elemente können über die komplette Angabe inklusive Arrayindex erfragt werden, z.B. ‚TestNumArr[3]‘ erfragt das 4. Element des Arrays ‚TestNumArr‘.

Attention

Werden Prozessvariablen ausschließlich im Skripting über die dynamischen Funktionen GetValue(), SetValue(), GetTagProperty() und SetTagProperty() verwendet und sonst NIRGENDWO anders im Projekt, werden sie vom Designer als nicht referenziert erkannt, da der Zugriff bei diesen Funktionen dynamisch zur Laufzeit über den Namen funktioniert und NICHT über eine feste Referenz.

Dies kann man erkennen, wenn man sich alle Referenzen der Prozessvariable anzeigen lässt und diese sind dann leer und somit wird die Variable nicht für die Laufzeit exportiert. Das führt zur Laufzeit zum Returnwert -2 bei den oben genannten Funktionen.

Funktionsdefinition: GetValue (TagName: string, Mode: integer, VarNameResult: undef) : integer

Parameter:

TagName

Name der zu erfragenden Variable

Numerische, Logische Prozessvariable oder Textvariable als Stringkonstante oder Variable

Mode

0 Funktion wird asynchron abgearbeitet, der gerade aktuelle Wert wird zurückgeliefert

1 Funktion wird synchron abgearbeitet, d.h. es wird bei Treibervariablen so lange gewartet, bis ein Fetsch-Zyklus abgearbeitet ist

VarNameResult

Wert der zu erfragenden Variablen

Es dürfen nur echte Variablen, keine Instanzen verwendet werden

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Parameterfehler

-2

Prozessvariable nicht gefunden

Beispiel
PROGRAM

var mode : integer

BEGIN
    if GetValueNow then
    begin
        GetValueNow :=0
        mode := 0
        GetValue('VarTest', mode, WertVarTest)
    end
END

Important

Der Wert der Variablen wird vom TagServer direkt aus dem Prozess gelesen. Wenn die Variable vorher im Skript benutzt wurde, steht der Wert normalerweise noch nicht im Prozess zur Verfügung, es sei denn es wurde z.B. ein WriteToProcess() durchgeführt

Beispiel
BEGIN
    (*-- The variable "myVar" in the process has the value 1 --*)

    (*-- in the script: --*)

    myVar:= 3
    GetValue(‚myVar‘, 0, myVarValue)

    (*-- -> myVarValue has the value 1 --*)


    myVar:=3
    WriteToProcess()
    GetValue(‚myVar‘, 0, myVarValue)

    (*-- -> myVarValue has the value 3 --*)
END

SetValue

Funktion zum Setzen eines Variablenwertes über den Variablennamen, der auch dynamisch zusammengebaut werden kann. Befindet sich die Variable NICHT in der aktuellen Anforderungsliste, wird sie automatisch für den Zeitraum der Ausführung in die Anforderungsliste übernommen.

Array-Elemente können über die komplette Angabe inklusive Arrayindex erfragt werden, z.B. ‚TestNumArr[3]‘ erfragt das 4. Element des Arrays ‚TestNumArr‘.

Attention

Werden Prozessvariablen ausschließlich im Skripting über die dynamischen Funktionen GetValue(), SetValue(), GetTagProperty() und SetTagProperty() verwendet und sonst NIRGENDWO anders im Projekt, werden sie vom Designer als nicht referenziert erkannt, da der Zugriff bei diesen Funktionen dynamisch zur Laufzeit über den Namen funktioniert und NICHT über eine feste Referenz.

Dies kann man erkennen, wenn man sich alle Referenzen der Prozessvariable anzeigen lässt und diese sind dann leer und somit wird die Variable nicht für die Laufzeit exportiert. Das führt zur Laufzeit zum Returnwert -2 bei den oben genannten Funktionen.

Funktionsdefinition: SetValue(TagName: string, Mode: integer, VarNameResult: undef) : integer

Parameter:

TagName

Name der zu erfragenden Variable

Numerische, Logische Prozessvariable oder Textvariable als Stringkonstante oder Variable

Mode

0 Funktion wird asynchron abgearbeitet, der gerade aktuelle Wert wird zurückgeliefert

1 Funktion wird synchron abgearbeitet, d.h. es wird bei Treibervariablen so lange gewartet, bis ein Fetch-Zyklus abgearbeitet ist

VarNameResult

Wert der zu erfragenden Variablen

Es dürfen nur echte Variablen, keine Instanzen verwendet werden

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Parameterfehler

-2

Prozessvariable nicht gefunden

Beispiel
PROGRAM

var mode : integer

BEGIN
    if SetValueNow then
    begin
        SetValueNow :=0
        mode := 0 (* ohne Verzögerung *)
        SetValue('VarTest', mode, VarWertNeu)
    end
END

Sonderfunktionen (nur SCADA)

Special

Funktion zum Auslösen von Sonderfunktionen aus dem Eventcode heraus. Es sind die Sonderfunktionen möglich welche auch auf Symbolen und Buttons möglich sind.

Attention

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: Special(Picture, Number : integer) : integer

Parameter:

Picture

Nummer des Bildes mit der die Funktion aufgerufen wird

Number

Nummer der Sonderfunktion

Rückgabewerte

0

wenn Funktion ausgeführt wurde

Beispiel
PROGRAM

var BildNummer : integer

Function UserMgm(mode : integer) : integer

var BildNummer : integer
Begin
    BildNummer := Picture(0)
    if (mode = 1) then
    begin
        (* Benutzer anmelden *)
        Special(BildNummer, 203)
    end

    if (mode = 2) then
    begin
        (* Benutzer abmelden *)
        Special(BildNummer, 205)
    end
End

BEGIN
    UserMgm(1)
END

Externer Funktionsaufruf / Programmstart (nur SCADA)

WinExec

Funktion zum Ausführen eines anderen Windows-Programms aus dem Ereigniscode. Auf dem Server können hiermit nur Hintergrunddienste gestartet werden. Ein Programm wie z.B. Notepad kann daher nur auf dem Client geöffnet werden. Bei der Verwendung dieser Funktion muss beachtet werden, dass das auszuführende Programm auch tatsächlich vom Betriebssystem gestartet werden kann. Dazu muss es sich entweder im aktuellen Arbeitsverzeichnis befinden oder in einem der Windows-Suchpfade. Außerdem müssen zum Zeitpunkt des Programmstarts die Windows-Ressourcen ausreichen.

Attention

Da die Kommandozeilenparameter für den Programmaufruf mit Leerzeichen getrennt werden, werden keine Pfadangaben mit Leerzeichen unterstützt.

Attention

Die Ausführung des Programms erfolgt im Benutzerkontext des PROCON-WEB - Dienstes, das ist normalerweise der lokale Systemaccount. Es sollten daher keine Programme mit Bedienoberfläche aufgerufen werden die eine Benutzerinteraktion erfordern.

Funktionsdefinition: WinExec(CommandLine: string) : integer

Parameter:

CommandLine

Kommandozeile für den Programmaufruf inklusive der Startparameter

Rückgabewerte:

0

wenn ok

< 0

wenn Fehler

-1

Parameter nicht definiert

-2

Systemressourcen nicht ausreichend um Kommando auszuführen

-3

EXE-Datei hat falsches Format

-4

Datei nicht gefunden

-5

Pfad nicht gefunden

-6

undefinierter Fehler

Beispiel
PROGRAM

function fktOpenFile(File: string) : integer

begin
    (* the program Notepad is used for editing       *)
    (* started with the desired file                 *)
    WinExec ('C:\Windows\System32\NOTEPAD.EXE ' + File)
end

BEGIN
    fktOpenFile('info.txt')
END

Sonstige Funktionen (nur SCADA)

Delay

Mit dieser Funktion kann das auszuführende Skript um die übergebene Anzahl von Millisekunden verzögert werden. Das Skript stoppt seine Ausführung für die angegebene Zeit und fährt nach Ablauf der Zeit wieder mit dem Skript fort.

Bevor das Skript angehalten wird, werden alle vom Skript modifizierten Prozessvariablen zum Tagserver geschrieben. Bevor das Skript weiterläuft wird der aktuelle Prozessvariablenhaushalt vom Tagserver gelesen. D.h. das Prozessabbild für das Skript kann sich, während das Skript angehalten ist, verändert haben.

Da normalerweise nur zu Beginn und Ende eines Skripts eine Prozesskommunikation stattfindet kann so auch an einer definierten Stelle im Skript ein Prozessvariablenaustausch vorgenommen werden. Die Prozesskommunikation kann natürlich einen Performance-Overhead darstellen, z.B. bei der Verwendung der Funktion innerhalb einer Schleife.

Funktionsdefinition: Delay(Milliseconds : integer) : integer

Parameter:

Milliseconds

Zeit in Millisekunden, um die das Skript verzögert wird

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

Beispiel
PROGRAM

FUNCTION Nochmal: integer

var p : integer

begin
    for p:=21 downto 0 do
    begin
        while XY_Feld[p] > 0 do
            XY_Feld[p] := XY_Feld[p] - 1
        (* Values are now immediately written to the process *)
        Delay(0)
    end
end

BEGIN
    Nochmal()
END

LogEventString

Funktion zum Schreiben eines Strings in das Logbuch.

Funktionsdefinition: LogEventString(var StrSrc: string) : integer

Parameter:

StrSrc

Name des Strings (max. 255 Zeichen )

Rückgabewerte:

>= 0

wenn geschrieben

< 0

wenn nicht geschrieben

Beispiel
PROGRAM

BEGIN
    LogEventString('Erster Eintrag in Logbuch')
    LogEventString('Zweiter Eintrag in Logbuch')
END

SetLanguage

Funktion zum Setzen der aktuellen Bediensprache.

Besonderheit: Das Setzen der Bediensprache führt zu einem neuen Bildaufbau. Ein Bildevent (Bildformel) wird nach dem Befehl beendet und neu gestartet!

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: SetLanguage(Country : string) : integer

Parameter:

Country

Länderkennung der neuen Bediensprache

(z.B. 044 für England)

Rückgabewerte:

0

wenn die Funktion erfolgreich durchlaufen wurde

-1

Parameterfehler

-2

Sprachkennung nicht vorhanden in Projekt

Beispiel
PROGRAM

(* The identifier of the national language is in the "Country code" variable *)
(* to switch to                                                              *)

FUNCTION SetLang: INTEGER

BEGIN
    SetLanguage(Landeskennung)
END

BEGIN
    SetLang()
END

Random

Funktion zum Erstellen einer Zufallszahl. Mit der Funktion „Randomize“ wird der Zufallszahlengenerators initialisiert. Wird der Zufallszahlen-Generator nicht initialisiert erzeugt die Funktion „Random“ nach Start des Programms immer die gleiche Folge von Zufallszahlen.

Funktionsdefinition: Random(Range : integer) : integer

Parameter:

Range

Bereichsangabe für die Zufallszahl 0 <= Ergebnis < Range

Rückgabewerte:

Zufallszahl

0 <= Ergebnis < Range

Beispiel
PROGRAM

function CheckCondition() :integer

var hilfsvar, i :integer

begin
    hilfsvar := Zufall_oben
    Zufall_ist := Random(hilfsvar)
    for i := 0 to 3 do
    begin
        if (Zufall_ist = Vorgabe[i]) then
        begin
            Alert(1,645)    (* Alert: Browse *)
            Alert(2,645)
        end
    end
end

(*------------------------------------------------------------*)
(* So that the same number combination does not always appear *)
(* the function Randomize must be called once                 *)
(*------------------------------------------------------------*)
function Init() :integer
begin
    Randomize()
End

BEGIN
    Init()
    CheckCondition()
END

Note

Wenn beispielsweise eine Zufallszahl zwischen 70 und 80 erzeugt werden soll, so muss man eine Zufallszahl zwischen 0 und 10 erzeugen und einen Offset von 70 addieren.

Randomize

Funktion zum Initialisieren des Zufallszahlengenerators. Wird der Zufallszahlengenerator nicht initialisiert, erzeugt die Funktion Random nach Start des Programms immer die gleiche Folge von Zufallszahlen.

Funktionsdefinition: Randomize() : integer

Note

Siehe auch Random; Muss nach Projektstart nur einmalig gestartet werden (z. B. in der Initialisierung ).

ChangeProject

Funktion zum Ändern des aktuellen Projekts, die Runtime wird mit dem neuen Projekt neu gestartet.

Funktionsdefinition: ChangeProject(ProjectName: string) : integer

Parameter:

ProjectName

Name des Projekts das gestartet werden soll

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

< 0

Bei Fehler

Beispiel
PROGRAM

BEGIN
    ChangeProject('MesseDemo')
END

GetLanguage

Funktion zum Erfragen der aktuellen Bediensprache.

Funktionsdefinition: GetLanguage(var SprachIdentifikation, Kurzbezeichnung, Laenderkennung : string) : integer

Parameter:

SprachIdentifikation

ID der Sprache, z.B. „de“ für Deutsch, „en“ für Englisch wie im Designer ausgewählt

Kurzbezeichnung

Kurzbezeichnung der Sprache wie im Designer vergeben

Laenderkennung

Länderkennung der aktuellen Bediensprache

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Parameterfehler

Beispiel
FUNCTION makro4005 : INTEGER

var Name,
    Shortcut,
    Country : string

BEGIN
    makro4005 := GetLanguage(Name, Shortcut, Country)
END

(*  The variables then have the following content, for example:
        Name:           de
            Shortcut:   D.
            Country:    049
*)

OpenBrowser

Funktion zum Öffnen der übergebenen URL in einem neuen Browser-Tab oder einem neuen Browser-Fenster. Grund hierfür ist, dass man bestimmte Seiten wie z.B. Google nicht in iFrames – wie es das WebBrowser-Control benutzt - anzeigen lassen kann.

Important

Dieser Befehl funktioniert nur für angemeldete Clients, d.h. in einem lokalen Skript! Insbesondere wird dieser Befehl nicht in einem Skript funktionieren das zum Systemstart ausgeführt wird, da zu dem Zeitpunkt der WebServer noch keine Client-Anfragen entgegen nimmt!

Funktionsdefinition: OpenBrowser(Url : string, tab : integer) : integer

Parameter:

URL

URL, die aufgerufen werden soll

Tab

0 = neues Browserfenster 1 = neuer Tab

Laenderkennung

Länderkennung der aktuellen Bediensprache

Rückgabewerte:

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Parameterfehler (Tab < 0 oder Tab > 1)

Beispiel
PROGRAM

BEGIN
    OpenBrowser('http://www.google.de/', 1)
END

DIN 8743 Funktionen (nur SCADA)

CalculateDIN8743

Hinweise siehe Kapitel Maschinenzeiten

Funktionsdefinition CalculateDIN8743(int Aktion, string Auftrag, string AuftragID, string Unitname, real Start, real Ende, real Modus, real Gutteile, real Schlechtteile)

Parameter

Bedeutung

Aktion 0

Berechnungsstart

1

Abbruch der Berechnung

2

Fortschrittsabfrage der Berechnung

3

Statusabfrage der Berechnung

Die nachfolgenden Parameter werden nur bei Aktion 0 (Berechnungsstart ausgewertet):

Auftrag: Name des Auftrags (Benutzerdefinierter Text zur Kennzeichnung der Berechnung)

AuftragID: ID des Auftrags (Benutzerdefinierter Text zur Kennzeichnung der Berechnung)

Unitname: eindeutiger Name der zu berechnenden Unit z.B. ’Anlagenstruktur.Anlage.Linie1.Unit1‘)

Start: Startzeitpunkt der Auswertung in Sek. seit 1970

Ende: Endzeit der Auswertung in Sek. seit 1970

Modus: DIN-Berechnungsmodus 0 = absolute Zeit (Ende-Start) als Berechnungsgrundlage 1 = Maschinenarbeitszeit tW als Berechnungsgrundlage

Mit den beiden letzten Parametern können die Anzahl der Gut- oder der Schlechtteile aus der Loggertabelle überschrieben werden. Werte >=0 überschreiben oder ersetzen die ermittelten Werte aus der Loggertabelle.

Gutteile, Anzahl der Gutteile innerhalb des Berechnungszeitraums

Schlechtteile, Anzahl der Schlechtteile innerhalb des Berechnungszeitraums

Returnwerte bei Aktion Statusabfrage:

Bedeutung

-1

Fehler

0

OK oder fertig

1

Berechnung läuft

2

Berechnung abgebrochen

Returnwerte bei Aktion Fortschrittsabfrage:

Bedeutung

-1

Fehler oder Berechnung abgebrochen

0 – 100

Fortschrittsangabe

Sonstige Returnwerte:

Bedeutung

-2

unbekannter Unitname

-3

falsche Berechnungszeitparameter Start und Ende

-4

aktuell wird schon eine Berechnung ausgeführt

-5

interner Berechnungsfehler (falsche Parameter in der Unit-Definition, usw.)

-6

AlertService ist im Moment blockiert (z.B.: Online-Projektupdate)

CalculateStatistic

Hinweise siehe Kapitel Maschinenzeiten

Funktionsdefinition CalculateStatistic(int Aktion, string Auftrag, string AuftragID, string Länderkennung, real Start, real Ende)

Parameter

Bedeutung

Aktion 0

Berechnungsstart

1

Abbruch der Berechnung

2

Fortschrittsabfrage der Berechnung

3

Statusabfrage der Berechnung

Die nachfolgenden Parameter werden nur bei Aktion 0 (Berechnungsstart ausgewertet):

Auftrag: Name des Auftrags (Benutzerdefinierter Text zur Kennzeichnung der Berechnung)

AuftragID: ID des Auftrags (Benutzerdefinierter Text zur Kennzeichnung der Berechnung)

Länderkennung: gewünschte Sprache der Alarmtexte in der Ergebnistabelle (z.B.: de-DE)

Start: Startzeitpunkt der Statistikberechnung in Sek. seit 1970

Ende: Endzeit der Statistikberechnung in Sek. seit 1970

Returnwerte bei Aktion Statusabfrage:

Bedeutung

-1

Fehler

0

OK oder fertig

1

Berechnung läuft

2

Berechnung abgebrochen

Returnwerte bei Aktion Fortschrittsabfrage:

Bedeutung

-1

Fehler oder Berechnung abgebrochen

0 – 100

Fortschrittsangabe

Sonstige Returnwerte:

Bedeutung

-3

falsche Berechnungszeitparameter Start und Ende

-4

aktuell wird schon eine Berechnung ausgeführt

-5

interner Berechnungsfehler (falsche Parameter in der Unit-Definition, usw.)

-6

AlertService ist im Moment blockiert (z.B.: Online-Projektupdate)

StatisticClose

Wird nicht mehr unterstützt

Druckerhandling

Important

Die Scriptfunktionen zum Druckerhandling werden IMMER auf dem Server ausgeführt, somit beziehen sich diese auch immer auf die Drucker am Server-System.

GetPrinterCount

Mit dieser Funktion kann die Anzahl der Drucker aus dem System ausgelesen werden.

Funktionsdefinition: GetPrinterCount() : integer

Rückgabewerte

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Drucker können nicht ausgelesen werden

Beispiel
PROGRAM

BEGIN
    DruckerListe := ''
    DruckerCount := GetPrinterCount()
    for i:= 0 to DruckerCount - 1 do
    begin
        GetPrinterName(i, printer)
        if (i = 0) then DruckerListe := printer
        else DruckerListe := DruckerListe + ';' + printer
    end

    GetDefaultPrinterByIndex(DruckerIndex);
    GetDefaultPrinterByName(SelectedDrucker)
END

GetPrinterName

Liest den Namen eines Druckers aus, der Index muss zwischen 0 und GetPrinterCount() – 1 liegen.

Funktionsdefinition: GetPrinterName(integer: index, name : var type string) : integer

Parameter

Bedeutung

index

Index des Druckers ( muss zwischen 0 und GetPrinterCount() – 1 liegen)

name

Name des Druckers

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Drucker wurde nicht gefunden

Beispiel
PROGRAM

BEGIN
    DruckerListe := ''
    DruckerCount := GetPrinterCount()
    for i:= 0 to DruckerCount - 1 do
    begin
        GetPrinterName(i, printer)
        if (i = 0) then DruckerListe := printer
        else DruckerListe := DruckerListe + ';' + printer
    end

    GetDefaultPrinterByIndex(DruckerIndex);
    GetDefaultPrinterByName(SelectedDrucker)
END

GetDefaultPrinterByIndex

Liest den Default Drucker aus

Funktionsdefinition: GetDefaultPrinterByIndex(var integer: index) : integer

Parameter

Bedeutung

index

Index des Druckers

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Drucker wurde nicht gefunden

Beispiel
PROGRAM

BEGIN
    DruckerListe := ''
    DruckerCount := GetPrinterCount()
    for i:= 0 to DruckerCount - 1 do
    begin
        GetPrinterName(i, printer)
        if (i = 0) then DruckerListe := printer
        else DruckerListe := DruckerListe + ';' + printer
    end

    GetDefaultPrinterByIndex(DruckerIndex);
    GetDefaultPrinterByName(SelectedDrucker)
END

GetDefaultPrinterByName

Liest den Default Drucker aus

Funktionsdefinition: GetDefaultPrinterByName(var string: name) : integer

Parameter

Bedeutung

index

Index des Druckers

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Drucker wurde nicht gefunden

Beispiel
PROGRAM

BEGIN
    DruckerListe := ''
    DruckerCount := GetPrinterCount()
    for i:= 0 to DruckerCount - 1 do
    begin
        GetPrinterName(i, printer)
        if (i = 0) then DruckerListe := printer
        else DruckerListe := DruckerListe + ';' + printer
    end

    GetDefaultPrinterByIndex(DruckerIndex);
    GetDefaultPrinterByName(SelectedDrucker)
END

SetDefaultPrinterByIndex

Ändert den Default Drucker

Funktionsdefinition: SetDefaultPrinterByIndex(integer: index) : integer

Parameter

Bedeutung

index

Index des Druckers ( muss zwischen 0 und GetPrinterCount() – 1 liegen)

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Drucker wurde nicht gefunden

Beispiel
PROGRAM

BEGIN
    SetDefaultPrinterByName(DruckerIndex)
END

SetDefaultPrinterByName

Ändert den Default Drucker

Funktionsdefinition: SetDefaultPrinterByName(string: name) : integer

Parameter

Bedeutung

index

Index des Druckers ( muss zwischen 0 und GetPrinterCount() – 1 liegen)

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

Default Drucker konnte nicht gesetzt werden

Beispiel
PROGRAM

BEGIN
    SetDefaultPrinterByName(SelectedDrucker)
END

Struktur-Funktionen

Strukturen kopieren

Strukturen werden im Skripting durchgehend, wie C# Referenz behandelt. Dies bedeutet, dass beim Kopieren von Strukturen eine Referenz zugewiesen wird, nicht jedoch die Werte selbst. Dies kann in der Skriptkonfiguration aktiviert werden.

kopieren

Beim Schreiben auf Tag Strukturen muss das kopieren immer über eine Skriptfunktion erfolgen. Geschieht dies nicht, so wird ein Systemalarm ausgelöst, der darauf hinweist.

CopyStruct

Kopiert alle Elemente der Quellstrutkur sowie deren Unterstruktur auf die Zielstruktur. Die Länge wird standardmäßgi nicht verändert, kann aber über den Parameter „overrideLength“ angepasst werden.

Funktionsdefinition: CopyStruct(target: struct, source: struct, [overrideLength]:boolean) : integer

Parameter

Bedeutung

target

Name der Zielstruktur

source

Name der Quellstruktur

overrideLength

Legt fest, ob Arraylänge beibehalten wird oder nicht

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn Ziel und Quellstruktur verschiedene Typen haben

GetStructValue

Funktion zum Erfragen von Strukturwerten über den Namen der Strukturinstanz, der auch dynamisch zusammengebaut werden kann. Es kann auch auf Unterstrukturen zugegriffen werden, wenn diese mit einem Punkt angegeben werden. Ebenso kann auf Arrays als Ganzes oder einzelne Elemente davon abgefragt werden.

Funktionsdefinition: GetStructValue(structName: string, mode: integer, structValue: struct)

Parameter

Bedeutung

structName

Name der zu erfragenden Struktur

mode 0

Funktion wird asynchron abgearbeitet, der gerade aktuelle Wert wird zurückgeliefert

mode 1

Funktion wird synchron abgearbeitet, d.h. es wird bei Treibervariablen so lange gewartet, bis ein Fetsch-Zyklus abgearbeitet ist

structValue

Wert der zu erfragenden Strukturen

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn Ziel und Quellstruktur verschiedene Typen haben

-2

wenn aufgrund des optimierten Prozessvariablenexports keine Variable gefunden wird

Beispiel
(*Triangle
string Name
real[3]  Colors
Point   Anchor
Point[3] Vertices
ChildTriangle   First
ChildTriangle[3] All

ChildTriangle
string Name
real[3]  Colors
Point   Anchor
Point[3] Vertices

Point
integer X
integer Y
*)

    PROGRAM

    BEGIN
    GetStructValue(„Tri“, 0, localTriVar)
    GetStructValue(„TriArray[0]“, 0, localTriVar)
    GetStructValue(„TriArray“, 0, localTriVarAsArray)
    GetStructValue(„Tri.First.Point“, 0, localPointVar)
    END

SetStructValue

Funktion zum Schreiben von Strukturwerten über den Namen der Strukturinstanz, der auch dynamisch zusammengebaut werden kann. Es kann auch auf Unterstrukturen zugegriffen werden, wenn diese mit einem Punkt angegeben werden. Ebenso kann auf Arrays als Ganzes oder einzelne Elemente davon abgefragt werden. Die Länge des Arrays kann nicht verändert werden

Funktionsdefinition: SetStructValue(structName: string, mode: integer, structResult: struct)

Parameter

Bedeutung

structName

Name der zu erfragenden Struktur

mode 0

Funktion wird asynchron abgearbeitet, der gerade aktuelle Wert wird zurückgeliefert

mode 1

Funktion wird synchron abgearbeitet, d.h. es wird bei Treibervariablen so lange gewartet, bis ein Fetsch-Zyklus abgearbeitet ist

structResult

Wert der zu beschreibenden Strukturen

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn Ziel und Quellstruktur verschiedene Typen haben

-2

wenn aufgrund des optimierten Prozessvariablenexports keine Variable gefunden wird

Beispiel
(*Triangle
string Name
real[3]  Colors
Point   Anchor
Point[3] Vertices
ChildTriangle   First
ChildTriangle[3] All

ChildTriangle
string Name
real[3]  Colors
Point   Anchor
Point[3] Vertices

Point
integer X
integer Y
*)

    PROGRAM

    BEGIN
    SetStructValue(„Tri“, 0, localTriVar)
    SetStructValue(„TriArray[0]“, 0, localTriVar)
    SetStructValue(„TriArray“, 0, localTriVarAsArray)
    SetStructValue(„Tri.First.Point“, 0, localPointVar)
    END

GetStructInstances

Funktion zum Erfragen der Namen aller Instanzen einer Struktur, der auch dynamisch zusammengebaut werden kann. Die Länge des übergebenenn Arrays wird automatisch angepasst.

Funktionsdefinition:

GetStructInstances(structTypeName: string, instances: array of string): integer

Parameter

Bedeutung

structTypeName

Name der zu erfragenden Instanzen

mode 0

Funktion wird asynchron abgearbeitet, der gerade aktuelle Wert wird zurückgeliefert

mode 1

Funktion wird synchron abgearbeitet, d.h. es wird bei Treibervariablen so lange gewartet, bis ein Fetsch-Zyklus abgearbeitet ist

structValue

Wert der zu erfragenden Strukturen

Rückgabewerte:

Bedeutung

0

wenn Funktion erfolgreich ausgeführt wurde

-1

wenn die Struktur nicht gefunden werden konnte

Dynamische Strukturen

Bei Skripten die von einem Client aus gestartet werden und nicht z.B. bei Start der Visu automatisch, kann mit „DynStruct.<StructClassName> auf dynamische Strukturen zugegriffen werden. Das funktioniert bei AOs mit Strukturzuweisung und bei Bildern, die von einem AO mit Struktur geöffnet worden sind. Wird eine Struktur verwendet, bei der zur Laufzeit keine passende Instanz ermittelt werden kann, so wird vor der Skriptausführung die Struktur auf eine neue leere Instanz gesetzt.

Skript-Debugger

Allgemein

Die Skript-Komponente des PROCON-WEB Designer wurde um die Funktionalität eines Debuggers erweitert. Der Debugger ist in der Lage in einer Simulationssitzung einzelne Skripte zu debuggen oder es besteht die Möglichkeit, sich an einen lokalen SkriptServer zu verbinden (attach) um dessen Live-Ablauf zu debuggen. Die Funktionen des Skript-Debuggers sind über die Skript-Toolbar erreichbar, wenn das zu debuggende Skript im Designer geöffnet wird:

Toolbar

Die folgenden Funktionen stehen zum Starten einer Debug-Session zur Verfügung:

Toggle Breakpoint (F9) Hiermit kann an der aktuellen Codestelle (Stelle im Skript, an der der Eingabecursor positioniert ist) ein Haltepunkt (Breakpoint) gesetzt oder gelöscht werden. Existiert an der Stelle kein Haltepunkt wird einer gesetzt, existiert bereits ein Haltepunkt, wird dieser gelöscht.

Breakpoints können sowohl vor einer Debug-Session, als auch während einer Debug-Session gesetzt bzw. weggenommen werden. Zu Beachten ist allerdings, dass der Start einer Debug-Session ohne vorher gesetzte Haltepunkte dazu führen kann, dass die Skripte bereits vor dem Setzen eines Breakpoints abgearbeitet sind und somit der Haltepunkt nicht erreicht wird.

Start Simulation (F6) Startet eine Debug-Session innerhalb eines Skript-Simulationsablaufs.

Dabei wird im Hintergrund eine Simulationsumgebung gestartet, die jedes Skript einmalig abarbeitet. In dieser Simulation findet keinerlei Runtime-Kopplung zu Serverkomponenten statt. Alle Skript-Sonderfunktionen werden so behandelt, als würde deren Abarbeitung als Ergebnis 1 (S_OK) zurückliefern.

Attach SkriptServer (Ctrl-F6) Startet eine Debug-Session in dem sich der Debugger mit dem tatsächlich laufenden Skript-Server einer lokalen Laufzeitumgebung verbindet.

Mit dieser Funktion können die gerade live in der Runtime laufenden Skripte gedebuggt werden. In diesem Szenario sind einige Besonderheiten zu beachten, die fundamentalen Einfluss auf das Laufzeitsystem haben können!

Important

Bei Live-Kopplung werden alle im Debugger modifzierten Variablen (Prozessvariable oder lokale Skriptvariable) direkt in den SkriptServer des Runtimesystems geschrieben und können somit den Prozess und die Abarbeitung der Skripte beeinflussen!

Important

Lange Debugsitzungen in einem Breakpoint können bei Live-Kopplung zu Timeouts innerhalb des Laufzeitsystems führen, so das z.B. Client-Skripte zu dieser Zeit nicht korrekt ausgeführt werden bzw. Serverkommunikationen aufgrund der Timeouts abbrechen und nicht neu gestartet werden.

Important

Da der Debugger bei Live-Kopplung direkt den Prozess des SkriptServers im Eingriff hat, kann dieser nach Beenden einer Debug-Session in einem Zustand zurückbleiben, der ein korrektes Weiterlaufen der Skripte nicht sicherstellt. Sicherheitshalber sollte daher nach einer SkriptServer-Debug-Session der SkriptServer neu gestartet werden.

Während einer Debug-Sitzung stehen die folgenden Funktionen zur Verfügung:

Continue Simulation (F6) Sollte die Sitzung in einem Breakpoint stehen, kann die Abarbeitung mit F6 fortgesetzt werden. Dies funktioniert sowohl für Simulations-Sessions als auch für Live-Sessions gegen den Skript Server. Hier ist die Funktion Continue Simulation (F6) und Continue SkriptServer (CTRL-F6) identisch.

Continue SkriptServer (CTRL-F6) Siehe „Continue Simulation (F6)

Step In (F11) Nur Verfügbar, wenn die Debug-Session in einem Haltepunkt steht. Springt in die nächste Skriptzeile. Ist diese ein Funktionsaufruf, wird in diese Funktion verzweigt, ansonsten verhält sich Step In wie Step Over (F10).

Step Over (F10) Nur Verfügbar, wenn die Debug-Session in einem Haltepunkt steht. Springt in die nächste Skriptzeile.

Step Out (CTRL-F11) Nur Verfügbar, wenn die Debug-Session in einem Haltepunkt steht. Springt aus der aktuellen Funktion in die darüberliegende. Befindet sich die aktuelle Codezeile in der Hauptfunktion (PROGRAM) verhält sich Step Out wie Step Over (F10)

Toggle Breakpoint (F9) Selbe Funktionalität wie vor dem Start einer Debug-Session (siehe oben)

Stop (Shift-F6) Beendet die Debug-Session. Wurde eine Simulations-Session gestartet wird diese beendet. Wurde eine live SkriptServer-Session gestartet wird versucht, den Debugger vom SkriptServer zu trennen (Detach), so dass der SkriptServer normal weiterläuft. Dies kann jedoch nicht in allen Situationen 100% garantiert werden (siehe oben)

Breakpoints

Es können in beliebigen Skripten beliebig viele Breakpoints gesetzt werden. Diese werden in einer Liste im unteren Bereich des Skript-Editors des Designers angezeigt.

Breakpoints

Breakpoints werden als rote Kreise im Editor angezeigt und die Zeile wird rot hinterlegt.

Ansicht

Breakpoints können mit F9 aktiviert / deaktiviert werden oder durch einen Mausklick in dem Bereich des Skript-Editors in dem die roten Kreise angezeigt werden.

Watchliste

Während einer Debug-Session werden die jeweils verwendeten Variablen (Prozessvariablen und lokale Variablen) des Skripts, in dem die Debug-Session gerade steht, angezeigt. Die Werte der Variablen können zu Testzwecken entsprechend verändert werden.

OptionWatchlisten

Note

Es können nur Variablenwerte angezeigt werden, wenn die Debug-Session in einem Haltepunkt steht.

Hintergrundinformationen

Hier einige Hintergrundinformationen die evtl. zum besseren Verständnis des Ablaufs von Debug-Sessions und dem Verhalten des Debuggers dienen:

  • Das PROCON-WEB Skript, dessen Syntax an die Programmiersprache PASCAL angelehnt ist, wird beim Export eines Projektes vom PROCON-WEB Designer in C# .NET-Code umgewandelt und in eine .NET Assembly kompiliert. Diese Dll (GTI.ProjectSpecificSkripts.dll) wird dann zur Laufzeit vom SkriptServer geladen und der Code dieser Dll direkt als .NET-Code ausgeführt.

  • Die Debugger-Funktionalität die nun zum Einsatz kommt, ist dieselbe Technologie wie eines „normalen“ Debuggers auf einer Windows-Maschine. Beim Debuggen wird immer ein „Mapping“ des aktuell ausgeführten C# .NET Codes auf die möglichst passende PROCON-WEB Skript Programmzeile durchgeführt. Da sich der PASCAL-ähnliche funktionsorientierte Code deutlich vom objektorientieten .NET C# Code unterscheidet, kann es in gewissen Fällen dazu führen, dass die Codezeile nicht eindeutig bestimmt werden kann.

  • Durch den Einsatz normaler Debug-Technologie bei einer Debug-Session können daher besonders beim Anhängen (Attach) an einen aktuell laufenden SkriptServer die oben aufgeführten Probleme entstehen. Daher ist ein Live-Debugging besonders bei einem produzierenden Runtimesystem eine sehr heikle Angelegenheit, bei der man damit rechnen muss, das Laufzeitsystem nach Beendigung der Debug-Session neu zu starten.

  • Um festzulegen, welche Session einen Debug-Aufruf triggert, kann in der Script-Konfiguration eine Reihe von Teilnehmern definiert werden, bei denen ein Breakpoint beim Debuggen getriggert wird.

Der Eintrag muss in der ServerConfigs.xml im Runtime-Verzeichnis vorgenommen werden in der Zeile

<special key ="DebugSessions" value ="localhost;ScriptServer"/>

Mögliche Einträge:

Teilnehmer

Beschreibung

Localhost

Der locoalhost-Client

ScriptServer

ScriptServer-Session für globale Tasks

ScriptServer-TaskName

ScriptServer-Session für einen speziellen Task

Nondedicated

Nicht dedizierte Client

ACHTUNG: dadurch triggern ALLE nicht dedizierte Clients den Breakpoint

Teilnehmername

Der Name eines geteachten Clients (nicht case sensitiv)

Net DLL in Skript nutzen (nur SCADA)

Allgemeines

In PROCON-WEB Skripten können nun auch CLR-Klassen importiert werden. Dabei muss eine in einer .NET Sprache (z.B. C#) geschriebenen Assembly innerhalb des Designers ausgewählt werden. Nachdem die Assembly bekannt gemacht wurde, kann in einem Skript ein beliebiger Namespace dieser Assembly importiert werden. Anschließend sind alle unterstützten Klassen im Skript verwendbar.

Entscheidend für die Verwendbarkeit einer CLR-Methode in einem Skript ist die Methodensignatur. Diese muss einigen Einschränkungen entsprechen. Es werden ausschließlich öffentliche (public) und statische (static) Methoden unterstützt. Außerdem dürfen die Typen der Parameter und der Rückgabetyp nur skriptkompatible Typen darstellen. Nicht unterstützt werden generische Methoden, ref/out-Parameter oder überladene Methoden.

Gültige (C#) Rückgabetypen

Gültige (C#) Parametertypen

bool

int

float

double

bool[]

int[]

float[]

double[]

Void

string[]

Sollen Strukturen an eine CLR Methode übergeben werden, kann das dynamic Keyword in C# verwendet werden oder es kann die vom Designer generierte Dll „GTI.ProjectSpecific.Skripts.Types.dll“ verwendet werden, die für alle TagStrukturen entsprechende Interfaces generiert. Beispiel 1: Verwendung von CLR

program
import Testassembly
var x, y : integer
begin
y := 3
x := MyClass.MyStaticFuncWithInteger(y)
end

Projektbaum

Projektbaum

Im Projektbaum gibt es einen neuen Eintrag im Bereich Skript (.Net Dll).

Ansichten

Die Anzeige der im Projekt enthaltenen Dlls (und pdb-Dateien) gliedert sich in zwei Bereiche

Ansichten

Im linken Bereich sind die Dlls in einem Grid aufgelistet. Erzeugen, bearbeiten etc. funktioniert genauso wie aus dem Bereich Dateiverwaltung bekannt. Im rechten Bereich werden die Methoden mit Parametern und Rückgabewert angezeigt, die aufgerufen werden können. Dazu muss man die gewünschte Dll im linken Bereich selektieren.

Alle für das Skript benötigten Dateien werden nun im Projektverzeichnis in den Unterordner „SkriptDllsDesigner“ exportiert.

Vorgehensweise

Hier wird exemplarisch die .NET Dll „GTI.SampleDotNet“ in ein Projekt eingebunden. Weitere Informationen hierzu können über den Support per E-Mail support@gti.de angefordert werden.

Die Dll stellt eine exemplarische Auftrags-Klasse (OrderHandling) zur Verfügung, die eine Ankopplung an ein externes Order-Management-System simulieren soll.

Sie stellt Funktionen zur generierung einer OrderID, eines Order-Namens zur Verfügung und eine Funktion, die eine passende PROCON-WEB TagStruktur-Instanz typsicher übernimmt und initialisiert zurückliefert. Die Beispielstruktur sieht folgendermaßen aus:

Beispielstruktur

Es wurde eine Ordnerstruktur definiert mit den Elementen: ID (Num) SollStueck (Num) IstStueck (Num) Name (String) Comment (String)

Und eine Instanz Namens „OrderInst“ zu der Struktur angelegt.

Anschließend wird das Projekt kompiliert und erzeugt, dadurch entsteht die Datei: „GTI.ProjectSpecific.Skripts.Types.dll“ im Projekt-Unterordner  SkriptDllsDesigner.

Diese Dll wird in der exemplarischen .NET Dll referenziert (Visual Studio 2015, C# Class Library, .NET Framework 4):

DLL

Die Klasse OrderHandling bietet u.a. die folgende Schnittstelle (TagStrukturen werden immer als Referenz übergeben und können in der Methode modifiziert werden.)

// type safe GetOrder Function
public static void GetOrder(GTI.ProjectSpecificSkripts.IOrder order)
{
order.ID = GetNewOrderId();
order.Name = GetProduct();
order.SollStueck = GetStueckzahl();
order.Comment = "Generated by GTI.SampleDotNet.dll C# Code";
}

Diese Dll wird nun wiederum im Designer unter .NET Dlls angemeldet:

anmeldung

Damit wird eine übergebene Order initialisiert und zurückgegeben. Das zugehörige Pascal-Skript, mit dem die OrderInst – Instanz initialisiert wird sieht so aus:

PROGRAM
import GTI.SampleDotNet (\* .NET Namespace of the used class \*)
BEGIN
(\* OrderHandling is the name of the class
InitOrder() is the public static method of the class
OrderInst is the Tag-Structur-Instanz \*)
OrderHandling.InitOrder( OrderInst )
END

Das Skript wird im Projekt über einen Button getriggert und initialisiert den Auftrag.