Any an FC

baggerandy

Level-1
Beiträge
12
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
hallo Leidensgenossen,
habe vor einen FC zu schreiben, mit dem die in einem String tatsächlich benutzte Anzahl von Zeichen ausgelesen werden kann. Der String steht in einem DB.
im FC wurde ein IN-Variable vom typ Any deklariert und nun als erstes die definierte Anzahl an Maximal verwendbaren Zeichen ausgelesen. Aber genau da hakts.
im FC:
L ##IN_STRING (In-Variable vom Typ Any)
Lar1

L B[ar1,p#0.0]
T #max_char (variable vom Typ byte)

es wird zwar eine Zahl ausgelesen, die hat aber nicht das entfernteste mit dem zu tun, was eigentlich drin steht. Kann mir da einer weiter helfen?

Gruß
Andy
 
das geht anderst....

das geht anderst, du krigts von ausen den any, den musst du nun zerlegen wenn du an deinen string kommen willst, oder den string mit blockmove in die lokaldaten kopieren...

Bsp:

Code:
//Any auf Quelldaten
      L     P##IN_STRING
      LAR1  
      L     W [AR1,P#4.0]  //DB-Nummer
      T DBNR
      L      D [AR1,P#6.0]  /Adressse
      LAR1

      L DBNR
      L 0
      ==I
      SPB noDB
      AUF DB[DBNR]
noDB: L  B[AR1,P#0.0]

denke das sollte gehen!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus,

bevor du hier wild mit Pointern um dich schmeisst, solltest du dir vielleicht erst mal den Aufbau der Pointer genauer anschauen ;)

Du musst den Any-Pointer erstmal in seine Bestandteile zerlegen, damit du damit arbeiten kannst. Weiterhin sollte man auch das AR1 sichern und wieder zurücksichern, wenn man selber damit arbeitet.

Probier das ganze mal so in etwa:

Code:
TAR1  #SaveAr1            //temporäre DWord-Variable zum sichern des AR1

L     P##IN_STRING                  //load Any-Pointer 
LAR1          

L     W [AR1,P#0.0]               //Get Datatype
T     #Datatype                    //temp WORD

L     W [AR1,P#2.0]               //Get Repeatfactor
T     #Repeatfactor               //temp WORD

L     W [AR1,P#4.0]               //Get DB-Number
T     #DbNr                          //temp WORD

L     D [AR1,P#6.0]               //Get Startadress
T     #Adress                      //temp DWord


AUF DB[#DbNr]                   //open DB

L      #Adress                 //Pointer to Startadress
LAR1


L      DBB [AR1,P#0.0]
T     #max_Char


......


LAR1  #SaveAr1              //Resave Adressregister
 
Zuletzt bearbeitet:
Hallo,
danke vielmals. Das mit dem AR1 bzw im FB AR2 sichern das hab ich. Allerdings daß der übergebene Pointer zuerst in seinen Bestandteilen geladen werden muß war neu. Werde das morgen mal ausprobieren - heute fehlt mir da die Zeit - die Pointer werden nacher erst mal mit Wickie weggespült damit der Kopf wieder klar wird. Vielen dank für Eure Hilfe.

Gruß
Andy
 
die Pointer werden nacher erst mal mit Wickie weggespült damit der Kopf wieder klar wird

Was willst Du wegspülen, du hast die genaue Funktion des Pointers noch nicht richtig verstanden.
Die Jungs vorher haben Dir zwar schön die Lösung geschrieben, aber nicht beschrieben warum man das macht.
In ganz kurzen Worten:
Mit dem Any-Pointer oder Any-Zeiger (auf deutsch) wird auf den Bereich im Speicher gezeigt wo die Daten sind. Dieser Zeiger enthält also keine Daten !.
In diesem Zeiger stehen jetzt quasi nur die Postleitzahl, Strasse und Hausnummer. Du willst aber jetzt ermitteln wieviele Stcokwerke das Haus hat, das steht da nicht drin.

Du willst ja im String die tatsächliche Belegung ermitteln, diese steht ja im String im zweiten byte. Also musst Du wissen wo dieses Byte im Speicher steht, und dies ermittelst Du mit Hilfe des Any-Pointers. Dieser enthält jatzt die Info, ob der String in z.B. einem DB steht und an welcher Stelle der String anfängt (Startadresse) .
 
Zuviel Werbung?
-> Hier kostenlos registrieren
uncle_tom;223875Weiterhin sollte man auch das AR1 sichern und wieder zurücksichern schrieb:
Du bist wirklich vorbildlich!
Also Save und Restore von AR1 findet man ganz selten in Programmen. Auch wenn es eigentlich sinnvoll ist.

Gruß
Dieter
 
Also ich hab dies mittlerweile auch in allen Standart Bausteinen. Wenn man erst mal Fehler gesucht hat weil man dies vergessen hat...
 
Du bist wirklich vorbildlich!
Also Save und Restore von AR1 findet man ganz selten in Programmen. Auch wenn es eigentlich sinnvoll ist.

Ja, ich habe mittlerweile auch an allen Hosen zusätzlich zu Gürtel noch Hosenträger - man weiß ja nie.

Wozu soll das Sichern des AR1 gut sein?

Bei der Verwendung von fremden Bausteinen z.B. aus der Siemens Bibliothek kann ich mir nie sicher sein dass diese irgendwelche Register unangetastet lassen. D.h. ich muss als Aufrufer dafür sorgen, dass ich vorher meine temporären Daten in Sicherheit bringe, bevor ich eine andere Funktion aufrufe. Ich gehe ja auch nicht davon aus, dass der Akku und das Statusregister nach einem Aufruf den gleichen Inhalt haben.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
... z.B. aus der Siemens Bibliothek kann ich mir nie sicher sein dass diese irgendwelche Register unangetastet lassen...


*ROFL*

zeig mir einen baustein der siemens lib der deine register durcheinander brigt...


nichts desto trotz ist das ar1 sichern sicherlich nicht verkehrt!
schließlich schnallst du dich im auto auch an, obwohl du und alle anderen das fahren in einer fahrschule gelernt haben.
 
*ROFL*
zeig mir einen baustein der siemens lib der deine register durcheinander brigt...
Zeig Du mir einen der das nicht macht! ;)
nichts desto trotz ist das ar1 sichern sicherlich nicht verkehrt!
schließlich schnallst du dich im auto auch an, obwohl du und alle anderen das fahren in einer fahrschule gelernt haben.
Absolut.
Du kannst ja auch an jedem Bausteinanfang alle Temporären Daten auf Null setzen. *ROFL*

Bei der Verwendung von fremden Bausteinen z.B. aus der Siemens Bibliothek kann ich mir nie sicher sein dass diese irgendwelche Register unangetastet lassen. D.h. ich muss als Aufrufer dafür sorgen, dass ich vorher meine temporären Daten in Sicherheit bringe, bevor ich eine andere Funktion aufrufe. Ich gehe ja auch nicht davon aus, dass der Akku und das Statusregister nach einem Aufruf den gleichen Inhalt haben.
*ACK*

Endlich mal einer der es auf den Punkt bringt.

Wenn ich in meiner FC / FB das Adressregister für meine Zwecke ändere dann ist es halt so. Der nächste Baustein restauriert ja beim Aufruf wieder sein aktuelles Adressregister.
Anders, wie Thomas auch schreibt, wenn ich zwischendurch auf andere Bausteine oder zusammengesetzte Datentypen zugreife.
Beispiel:
Ich übergebe einer FC einen Zeiger, aus diesem Zeiger soll der DB gelesen werden:
Code:
[COLOR=black][FONT=Verdana]L P##Daten // Any Zeiger[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]LAR1[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]L W [AR1, P#4.0] // DB-Nummer lesen[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]T #DB_Nr[/FONT][/COLOR]
So, jetzt habe ich die DB Nummer und will wissen ob es den Datenbaustein überhaupt gibt und nutze dafür den DB-Test-Baustein von Siemens und rufe den Baustein aus meiner FC aus auf.
Da ich nicht weiß was in diesem Baustein passiert sichere ich mir vor dem Aufruf das AR1, weil ich es später wieder brauche.
Nach dem Testen schreibe ich das AR1 wieder zurück. Alternativ könnte ich jetzt auch noch mal den Zeiger laden, was aber mehr Code bedeutet und eher verwirrender wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Moin,

zum AR1 u.AR2 sichern, bei FB's wird def. das AR2 Register vom System zur Bausteinadressierung verwendet. Und zu Ar1 sagt Siemens selbst, "mann kann ja nie wissen!" Also wenn die das schon sagen, dann sollte man da wohl doch noch zusätzlich die Hosenträger anlegen.

Gruß
Andy
 
Code:
      L     999
      T     MD   100
      LAR1  

      CALL  "CONCAT"
       IN1    :="DB1".str1
       IN2    :="DB1".str2
       RET_VAL:="DB1".str3

      TAR1  
      T     MD   104
      L     MD   100
      <>D   
      S     M     10.0
oder meine Bibliothek ist kaputt

Ja, mit den Stringfunktionen hab ich auch schon feine Erlebnisse gehabt. Mal sehen, wie misconduct das erklärt.

Aber davon abgesehen, nach einem Bausteinaufruf, würde ich eh nie mit einem einfachen TAR1 weitermachen, sondern immer, entweder die Adresse für das AR1 neu berechnen oder diese ohnehin vorher selbst gleich in einer Variablen sichern.
 
System Verwendung AR1,Ar2 u. DI-DB Register

Ar1:
Zugriffe auf Parameter,wenn zusammengesetzt,innerhalb eines FC benutzen
AR1 und DB-Register.
Zugriffe auf IN-OUT Parameter ,wenn zusammengesetzt,innerhalb eines FB benutzen AR1 und DB-Register.
Ar2:
AR2 und DI-Register werden vom System als Basisadressregister für die Adressierung aller Parameter und statischen Variablen innerhalb vob FB`s genutzt.

Für FC`s frei verwendbar AR2 und DI-Register

viele Grüße Bernard
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ar1:
Zugriffe auf Parameter,wenn zusammengesetzt,innerhalb eines FC benutzen
AR1 und DB-Register.

Wobei man sich da schon Mühe geben muss um das AR1 wirklich durcheinanderzubringen, da der Editor beim Laden eines solchen Parameters den Offset im AR1 immer neu berechnet, und auch den DB immer neu öffnet.

Beispiel wo ich in einem FC das AR1 überschreibe, es aber keine Auswirkungen hat:
Code:
VAR_IN_OUT
  struct1 : STRUCT     
   i1 : INT ;    
   i2 : INT ;    
  END_STRUCT ;    
END_VAR


      L     #struct1.i2
      T     MW    50
// AR1 überschreiben
      LAR1  P#999.0
      L     #struct1.i2
      T     MW    52
// Test
      L     MW    50
      L     MW    52
      <>I   
      S     M     10.1
 
Aber davon abgesehen, nach einem Bausteinaufruf, würde ich eh nie mit einem einfachen TAR1 weitermachen, sondern immer, entweder die Adresse für das AR1 neu berechnen oder diese ohnehin vorher selbst gleich in einer Variablen sichern.
Genau mein Rede,

das Adressregister einfach wie eine Temporäre Variable behandeln.
Vor der Verwendung immer sicher stellen das der Inhalt passt.
Und einem Baustein dessen Code man ja gar nicht kennt nicht trauen. ;)
 
Wobei man sich da schon Mühe geben muss um das AR1 wirklich durcheinanderzubringen

Hallo Thomas_V_2_1
Tut mir leid,aber dein Programm enthält Fehler.
1)Pointer sind 32 Bit groß.Deshalb DWORD Befehle .Dadurch blendest du die Bereichskennung aus.
2)Du vergleichst lediglich den Pointer #struct1.i2 mit sich selbst.

Dein Code
Code:
     L     #struct1.i2
      T     MW    50
// AR1 überschreiben
      LAR1  P#999.0
      L     #struct1.i2
      T     MW    52
// Test
      L     MW    50
      L     MW    52
      <>I   
      S     M     10.1
Korregierter Code
Code:
  L     #Struct1.i2                 // Lade Pointer auf struct
      T     MD    50                    // Transver nach Md50

// AR1 überschreiben Ar1 mit P#999.0                    
      LAR1  P#999.0
      TAR1  MD    54
// Test
      L     MD    50
      L     MD    54
      <>D   
      S     M     58.1                  //1= Unterscheidung AR1 vorhanden
Beim Test ergab sich eine Unterscheidung zwischen Md 50 und Md54.
Viele Grüße Bernard
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Thomas_V_2_1
Tut mir leid,aber dein Programm enthält Fehler.
1)Pointer sind 32 Bit groß.Deshalb DWORD Befehle .Dadurch blendest du die Bereichskennung aus.
2)Du vergleichst lediglich den Pointer #struct1.i2 mit sich selbst.

Dein Code
Code:
     L     #struct1.i2
      T     MW    50
// AR1 überschreiben
      LAR1  P#999.0
      L     #struct1.i2
      T     MW    52
// Test
      L     MW    50
      L     MW    52
      <>I   
      S     M     10.1
Korregierter Code
Code:
  L     #Struct1.i2                 // Lade Pointer auf struct
      T     MD    50                    // Transver nach Md50

// AR1 überschreiben Ar1 mit P#999.0                    
      LAR1  P#999.0
      TAR1  MD    54
// Test
      L     MD    50
      L     MD    54
      <>D   
      S     M     58.1                  //1= Unterscheidung AR1 vorhanden
Beim Test ergab sich eine Unterscheidung zwischen Md 50 und Md54.
Viele Grüße Bernard

Er lädt einen Pointer???
Ich sehe, daß er eine Integer aus der Struct lädt (i2). Dann das AR1 mit einem beliebigen Pointer überschreibt und nochmals die Integer aus der Struct lädt. Dann wird verglichen, ob die Inhalte identisch sind. Das zeigt erstmal schon, daß AR1 bei laden der Struct korrekt wiederhergestellt wird.
 
Bernard, ich glaube du hast nicht verstanden was tom uns zeigen will.
er läd einen Wert aus einer Struktur, spielt am Pointer herum und läd
dann den nächsten wert aus der Struktur. Dann vergleicht er die werte
miteinander.
Die werte in der Struktur sind INT werte, also bietet es sich an die auch
in ein MW zu speichern.
 
Zurück
Oben