TIA S7: Keine Benutzer definierte Datentypen bei InOut-Variablen möglich?

Automatinator

Level-1
Beiträge
115
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Kann mir einer erklären wieso ich keine Benutzer definierte Datentypen (UDT) bei FB-I/O Variablen verwenden kann?

Ich kann eine IO-Variable im FB als UDT deklarieren und einsehen (aufklappen), und sie wird nicht rot hinterlegt, auch beim Kompilieren reklamiert er nicht (0 Fehler, 0 Warnungen).
Wenn ich nun aber im Instanz-DB (hat kompiliert auch 0 Fehler, 0 Warnungen) die Variable aufklappen will, funktioniert das nicht (kein Dropdown-Pfeil).
Wenn ich nun die Variable in einem externen Bereich abfragen oder beschreiben will, sagt der Kompiler "Der Zugriff ist ungültig" (Hilfe-Text: "Sie haben versucht, einen Bausteinparameter außerhalb des Bausteinaufrufs zu schreiben.
Der Zugriff auf diesen Bausteinparameter ist nur am Bausteinaufruf möglich. Zugriffe auf Multiinstanzen oder Instanz-DBs sind nicht möglich.")

Wenn es kein Fehler ist, was ist der Grund für das nicht erlauben von UDT's in FB-IO's?

Meine SW-Version: V13.1.6

Vielen Dank schon im Vorraus!
 
Zuletzt bearbeitet:
Du deklarierst eine INOUT mit der UDT, "außen" an den FC/FB legt du eine DB-Variable, die ebenfalls mit dieser UDT deklariert ist.
Zugriffe erfolgen nur von "außen" über diese DB-Variablen und somit über die Schnittstellen des FC/FB.
Zugriffe auf den IDB sind unsauber und sorgen in Step7 V5.5 oft für Probleme und Verwirrung bei Programmierern.
Ich hab es noch gar nicht probiert, weil ich das gundsätzlich nicht mache, aber wenn das in TIA wirklich nicht mehr geht (von außen in IDB greifen), finde ich mal etwas wirklich gut an TIA :)
 
Zugriffe auf den IDB sind unsauber und sorgen in Step7 V5.5 oft für Probleme und Verwirrung bei Programmierern.

Wie meinst du das? Zugriffe auf den IDB sind unsauber? Inwiefern? Ich schreibe ja nicht auf die lokalen FB-Variablen sonder möchte eine Schnittstellenvariablen manipulieren... für das sind die doch da...
Wenn ich die IO-Var nicht als UDT deklariere (also sonst ein Norm-Datentyp), dann reklamiert er nicht mehr. Was hat der Datentyp mir sauber/unsauber zu tun? o_O
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe dich so verstanden, dass du ein INOUT am FB deklarierst, und dann aber keine Variable anlegen willst, sonden direkt auf den IDB schreiben und lesen willst.
Das halte ich für unsauber. Ich hab einfach schon zu viel Mist gesehen, der damit angestellt wurde. Ob das gehen würde hab ich halt noch nicht in TIA ausprobioert, ich halte das für ein NoGo, mach es also nicht.
Du kannst natürlich machen was du willst, aber Programme, in denen wild in IDB rumgepokt wird sind schlecht wartbar und vom Manipulieren der INOUT bis zum Manipulieren anderer IDB-Variablen ist es nur einen Mausklick weit. ;-)

Vielleicht habe ich dich ja falsch verstanden, dann erklär doch bitte noch einmal dein Problem.
 
Ich habe dich so verstanden, dass du ein INOUT am FB deklarierst, und dann aber keine Variable anlegen willst, sonden direkt auf den IDB schreiben und lesen willst.
Das halte ich für unsauber. Ich hab einfach schon zu viel Mist gesehen, der damit angestellt wurde. Ob das gehen würde hab ich halt noch nicht in TIA ausprobioert, ich halte das für ein NoGo, mach es also nicht.
Du kannst natürlich machen was du willst, aber Programme, in denen wild in IDB rumgepokt wird sind schlecht wartbar und vom Manipulieren der INOUT bis zum Manipulieren anderer IDB-Variablen ist es nur einen Mausklick weit. ;-)

Vielleicht habe ich dich ja falsch verstanden, dann erklär doch bitte noch einmal dein Problem.

Ich habe ja bei einer FB-Dekleration folgende Variablentypen: Input, InOutput, Output, Statische, Temporäre und Konstanten.
Jetzt deklariere ich dort (z.B. FB1) eine InOut-Variable: Name: "InOut" vom Typ "udtInOut", wobei "udtInOut" die Variablen "bVar1" und "bVar2" deklariert sind.
Dann habe ich einen IDB (DB1) vom Typ FB1.
Und jetzt reklamiert er, wenn ich ausserhalb schreibe (SCL): DB1.InOut.bVar1 := TRUE; oder IF DB1.InOut.bVar1 THEN ...
Aber eben halt nur bei UDT-IO-Vars...
Vorallem die Abfrage sollte doch zulässig sein oder nicht?
Und ich frag mich hier auch wieso er Norm-Datentypen-IDB-Var-Manipulation zulässt :O
 
Zuletzt bearbeitet:
Ich bin nicht ganz sicher, aber ich glaube, zusammengesetzte Datentypen, also auch UDT an INOUT werden per Referenz übergeben und sind somit gar nicht im IDB repräsentiert, sprich vorhanden.
Auch sonst sag ich noch einmal, übergib die Daten nicht direkt an den IDB, sondern häng außen an den FB eine Datenstruktur und manipuiere die (Findet man wenigstens ein wenig besser im Querverweis). Ich habs noch nie probiert, geht ein Aufruf alá FB1. ...
Schau noch mal nach, ob InOut vielleicht ein geschütztes Keyword in TIA ist.

PS: Ehrlich, ein SCL-Programm in dem du so auf den IDB zugreifst, würde ich dir niemals abnehmen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So wie Ralle schon schreibt, das hat damit zu tun, daß der UDT bei INOUT als Referenz übergeben wird - ein Zugriff "DB1.InOut.bVar1" kann nicht funktionieren. In C müßtest Du schreiben "DB1.InOut->bVar1" oder "DB1.(*InOut).bVar1" - so eine Dereferenzierung gibt es aber nicht in SCL. Der SCL-Compiler macht das aber automatisch/versteckt.

Der FB selber kann problemlos auf seine INOUT-UDTs zugreifen: #InOut.bVar1
Von außerhalb des FB kann man nur den zu übergebenden UDT selber manipulieren (z.B. DB2.UDT1.bVar1), aber nicht den INOUT-Bausteinparameter.

Harald
 
Es gibt gewisse Programmierregeln, an die man sich halten sollte, genau wie ich z.B. meine Hausinstallation nach bestimmten Regeln ausführe. Ich ziehe meine Leitungen ja auch nicht diagonal quer durch den Raum, obwohl das rein technisch natürlich auch funktionieren würde. IN/OUT/INOUT sind als Schnittstellen zum Datenaustausch mit einem FB gedacht und nur über diese Schnittstellen sollte man auch mit dem FB arbeiten. Auf IDBs wird überhaupt nicht zugegriffen, weder lesend noch schreibend, auch wenn das technisch natürlich möglich ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Es gibt gewisse Programmierregeln, an die man sich halten sollte, genau wie ich z.B. meine Hausinstallation nach bestimmten Regeln ausführe. Ich ziehe meine Leitungen ja auch nicht diagonal quer durch den Raum, obwohl das rein technisch natürlich auch funktionieren würde. IN/OUT/INOUT sind als Schnittstellen zum Datenaustausch mit einem FB gedacht und nur über diese Schnittstellen sollte man auch mit dem FB arbeiten. Auf IDBs wird überhaupt nicht zugegriffen, weder lesend noch schreibend, auch wenn das technisch natürlich möglich ist.
Ja das ist klar, aber wir reden ja hier von INOUT Variablen.
 
Vielleicht einmal zum besseren Verständnis der bisherigen Einwände :
Ein Baustein hat eine Schnittstelle (IN, INOUT , OUT). Über diese Schnittstelle wird die Verbindung von "innen im Baustein" nach "außerhalb von Baustein" hergestellt. Das heißt, dass alle Variablen, die der Baustein benötigt ihm über die IN- und INOUT-Schnittstelle zur Verfügung gestellt werden. Des gleichen stellt er seine Ergebnisse über die OUT- und INOUT-Schnittstelle nach aussen zur Verfügung.
Wenn du ein sauberes Programm erstellen möchtest dann hältst du dich an diese doch recht einfache Regel. Man könnte dazu auch sagen "best practise" ...

Natürlich hast du recht : man kann bei einem FB auch auf alle diese Variablen (und zusätzlich über den STAT-Bereich des internen Speichers) auch über den zugehörigen Instanz-DB zugreifen - sowohl lesend wie auch schreibend. Wenn du eine richtig tolles, für uneingeweihte (und irgendwann auch für dich) schwer nachvollziehbares Programm erstellen möchtest dann ist dies genau der Weg ... und das ist auch der Grund, warum manch einer (mich eingeschlossen) diese Vorgehensweise nicht so toll findet.
Aber wie du schon schreibst - es geht - also mach es und werde glücklich damit ...

Gruß
Larry
 
Vielleicht einmal zum besseren Verständnis der bisherigen Einwände :
Ein Baustein hat eine Schnittstelle (IN, INOUT , OUT). Über diese Schnittstelle wird die Verbindung von "innen im Baustein" nach "außerhalb von Baustein" hergestellt. Das heißt, dass alle Variablen, die der Baustein benötigt ihm über die IN- und INOUT-Schnittstelle zur Verfügung gestellt werden. Des gleichen stellt er seine Ergebnisse über die OUT- und INOUT-Schnittstelle nach aussen zur Verfügung.
Wenn du ein sauberes Programm erstellen möchtest dann hältst du dich an diese doch recht einfache Regel. Man könnte dazu auch sagen "best practise" ...

Natürlich hast du recht : man kann bei einem FB auch auf alle diese Variablen (und zusätzlich über den STAT-Bereich des internen Speichers) auch über den zugehörigen Instanz-DB zugreifen - sowohl lesend wie auch schreibend. Wenn du eine richtig tolles, für uneingeweihte (und irgendwann auch für dich) schwer nachvollziehbares Programm erstellen möchtest dann ist dies genau der Weg ... und das ist auch der Grund, warum manch einer (mich eingeschlossen) diese Vorgehensweise nicht so toll findet.
Aber wie du schon schreibst - es geht - also mach es und werde glücklich damit ...

Wie gesagt, ich rede von INOUT-Variablen. Keine Statischen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie gesagt, ich rede von INOUT-Variablen. Keine Statischen.
Es ist doch ganz einfach:
Einen Speicher den es im IDB nicht gibt, kannst du auch nicht Lesen/Schreiben.
Der UDT wird als InOutVar nur als Pointer übergeben, und folglich steht im IDB auch nur eine Adresse (der außen angelegten passenden Variable) im PointerFormat, nicht jedoch die Daten des UDTs ansich.
 
Das fällt aber auch auf wenn man das Programm ohne beschalteten INOUT auf die CPU runterläd wenn man INOUT als erweiterten Datentyp deklariert.

Dann geht die CPU auf Stop bzw ruft einen zugriffsfehlerOB auf.

mfG René
 
Es ist doch ganz einfach:
Einen Speicher den es im IDB nicht gibt, kannst du auch nicht Lesen/Schreiben.
Der UDT wird als InOutVar nur als Pointer übergeben, und folglich steht im IDB auch nur eine Adresse (der außen angelegten passenden Variable) im PointerFormat, nicht jedoch die Daten des UDTs ansich.
Jup, das weiss ich jetzt auch, ist trotzdem schade das es so ist...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also in InstanzDBs rumgrapschen ist ganz pfui, da schliesse ich mich meinen Vorrednern an.

Wenn du in den Stat Variablen des FB die UDT als Variable deklarierst, kannst du dann im Anweisungsteil die I/O Variable in die Stat Variable kopieren und das dann auch im IDB anschauen. Wenn es das ist was du willst.
 
Also in InstanzDBs rumgrapschen ist ganz pfui, da schliesse ich mich meinen Vorrednern an.

Wenn du in den Stat Variablen des FB die UDT als Variable deklarierst, kannst du dann im Anweisungsteil die I/O Variable in die Stat Variable kopieren und das dann auch im IDB anschauen. Wenn es das ist was du willst.

In InstanzDBs rumgrapschen ist 'pfui', das ist so, dass ist klar und ne stat Var anlegen vom gleichen Typ ist auch klar, nevertheless könnt auch die INOUT eine normale, nicht-pointer Variable sein...
 
Zuletzt bearbeitet:
Zurück
Oben