FUNCTION "DatenOut" : Void TITLE = Datenlisten-Modul { S7_Optimized_Access := 'FALSE' } AUTHOR : IBAE FAMILY : DLISTE NAME : DatenIn VERSION : 0.1 //COPYRIGHT by Ingenieurbüro A.Emmert //Ortsstr.33, D-869925 Fuchstal (Germany) //Tel.: 0049(0)8243-1254 //Version: P&O / 10.2024 //Version: ILS2100 / 06.11.2009 // //Datenblock in Datenliste suchen / löschen //SSDB: Datenlisten-DB //SSDW: Datenlisten-1.DW //SEARCHDATEN: Pointer, wo einzutragende Daten stehen (P#DB1.DBX0.0, P#M220.0) //AUFTRAG: XXYY // XX: 00 = angegebenen Datensatz suchen // 02 - 80 = Stammdaten beginnen ab angegebenen Datenwort // E1 = angegebenen Datensatz suchen + austragen! // F1 = 1.Datensatz lesen // FF = nächsten vorhandenen Eintrag lesen (ab letzten Zugriff) // YY: 01 - 09 = Anzahl der Stammdaten (falls abweichend vom Datenlistenkopf!) //(Achtung, nur mit P#M220.0 oder speziellen DB suchen!) // //OUTDATEN: Pointer, wohin ausgelesene Daten übergeben werden (P#DB1.DBX0.0, // P#M220.0) //RE_VAL: Rückmeldungen: // Bit0: Kein Datenlistenbereich / falscher Kopfinhalt / Endekennung // Bit1: SFC20-Aufruf mit Fehler // Bit2: Listenende ist erreicht // Bit3: Falscher Parameter bei Aufruf // Bit4: Undefinierte Stammdaten zum Suchen // Bit5: Undefinierte OUT-Daten // Bit6: Datensatz ist nicht vorhanden // Bit7: Datensatz ist vorhanden // VAR_INPUT SSDB : Int; // Datenlisten-DB SSDW : Int; // Datenlisten-1.DW PARA : Word; // Aufrufparameter (Auftrag / Anzahl Zusatzdaten) SEARCHDATEN : Pointer; // Such-Daten-Schnittstelle END_VAR VAR_OUTPUT RE_VAL : Byte; // Rückmeldung OUTDATEN : Pointer; // OutDaten-Schnittstelle Position : Int; // Daten stehen an angegebener Position in Datenbank END_VAR VAR_TEMP Quelle : Any; // Zeiger, wo Rein-Daten sind Ziel : Any; // Zeiger, FIFO-Stelle Kopf : Byte; // Datenliste-Kennnung (DA) Datensatzlaenge : Byte; // Datensatzlänge in Word (01 - F0) F0=128 Listenlaenge : Int; // Länge der Datenliste (maximale Anzahl der Datensätze) Stammdaten : Int; // Stammdatenlänge in Word (1 - 9) IndDB : Word; // Indizierter DB (nur bei Stammdaten = 1 erlaubt !!!) IndDB_Laenge : Int; // Länge des indizierten DB in Einträge (nur bei Stammdaten = 1 erlaubt !!!) IndDaten_FC : Int; // FC zum Wandeln der indizierte Daten (nur bei Stammdaten = 1 erlaubt !!!) Suchzeiger : Int; // Speicherung des letzten Zugriffs / Suchzeiger Belegt14 : Int; // reserviert von Sort-Datenliste AnzahlEintraege : Int; // Anzahl der eingetragenen Datensätze (nicht bei ind.Zugriff!) Reserve18 : Int; // Reserve Para1 : Byte; // 1.Aufrufparameter Para2 : Byte; // 2.Aufrufparameter DBDatenliste : Word; // Datenlisten-DB OffsetDaten_1 : Int; // Stammdaten beginnen ab hier SFC_RET_VAL : Int; // Rückmeldung SFC-Aufruf SFC_DB_LENGTH : Word; // Rückmeldung SFC-Aufruf Datenlisten_Ende : Int; // Ende der Datenliste AR2_Speicher : DWord; // Adress-Register 2 zwischenspeichern Schleife : Word; // Loopzähler DBSuchDaten : Word; // Such-Daten-DB, falls angegeben SuchDaten_Pointer : DWord; // Such-Daten-Pointer: Kennung, Adresse SuchDaten_Startpunkt : Word; // Such-Daten-Startpunkt: Adresse DBOutDaten : Word; // Out-Daten-DB, falls angegeben OutDaten_Pointer : DWord; // Out-Daten-Pointer: Kennung, Adresse OutDaten_Startpunkt : Word; // Out-Daten-Startpunkt: Adresse IndPointer : DWord; // Zeiger für IndDB Daten_1 : Word; // 1.Datenwort der Indaten Daten_2 : DWord; // 1+2.Datenwort der Indaten (falls ind.Suchen mit Stammdaten 2) Datenblock_inBytes : Word; // Datenblocklänge in Bytes Suchstelle : Word; // Bei angegebenen Datensatz suchen SFC_WRITE_PROT : Bool; // Rückmeldung SFC-Aufruf Indok : Bool; // Indizierung möglich IndZeiger_ok : Bool; // Indizier-Zeiger angegeben Weitersuchen : Bool; // Weitersuchen ist aktiv Offsetsuchen : Bool; // Offsetsuchen ist aktiv Sortliste : Bool; // Sortliste wird durchsucht WandelFC : Bool; // Wnadel-FC für ind.Suchen vorhanden tRE_VAL : Byte; // Rückmeldung AR1Zeiger : DWord; // Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) DB_Länge : Int; NichtCopy : Int; // Datenmenge, die nicht vorschoben wird LoeschPos : Word; // Lösch-Position Wandel_FC : Word; // Wandel-FC END_VAR BEGIN NETWORK TITLE = Schnittstellen-DB sinnvoll ? TAR2; T #AR2_Speicher;//AR2 zwischenspeichern L #SSDB; T #DBDatenliste; CALL "TEST_DB_TO_ATTR_DB" ( DB_Number := #DBDatenliste , RetVal := #SFC_RET_VAL , DB_Length := #SFC_DB_LENGTH , Write_Prot := #SFC_WRITE_PROT ); CALL "BCD (4stellig)_to_INT" ( BCD_Wert := #SFC_DB_LENGTH , Int_Wert := #DB_Länge ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000; <>I; O #SFC_WRITE_PROT;//schreibgeschützt SPB Err0;//kein Datenlisten-Bereich NETWORK TITLE = Datenlistekopf holen //Quelle-Pointer erzeugen: L 16#1004;//Kennung 10 + Word=04 T %LW0;//Any-Kennung, Datentyp L 16#000A;//10 Dw´s holen T %LW2;//Wiederholungen L #SSDB; T %LW4;//DB_Nummer L #SSDW;//Adresse SLD 3; L 16#8400_0000;//Kennung: Daten OD; T %LD6;//Kennung, Adresse CALL BLKMOV//1.-10.DW Datenliste holen {blk_type := 'Variant'} ( SRCBLK := #Quelle , RET_VAL := #SFC_RET_VAL , DSTBLK := P#L20.0 WORD 10 ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000; <>I; SPB Err1; NETWORK TITLE = Zeigerüberprüfung L #Kopf;//Datenliste-Kopf L 16#DB;//= Sort-Datenlistekennung ? ==I;//Ja ! = #Sortliste;//Sortliste wird durchsucht SPB w030; TAK; L 16#DA;//= Datenlistekennung ? <>I;//Nein ! SPB Err0;//kein Datenlistebereich w030: L 1; L #Datensatzlaenge;//Datenblocklänge >I; SPB Err0;//kein Datenlistebereich L 128; >I; SPB Err0;//kein Datenlistebereich L 1; L #Listenlaenge;//Max.Anzahl von Datenblöcken >I; SPB Err0;//kein Datenlistebereich L 1; L #Stammdaten;//Anzahl der Stammdaten >I; SPB Err0;//kein Datenlistebereich L 9; >I; SPB Err0;//kein Datenlistebereich L #Stammdaten;//Anzahl der Stammdaten L #Datensatzlaenge;//Datenblocklänge >I; SPB Err0;//kein Datenlistebereich L #Listenlaenge;//Länge der Datenliste L #Datensatzlaenge;//Datenblocklänge *I; L 2 ;//DB byteorientiert *I; + 20 ;//Speichern ab 10.DW L #SSDW; +I; T #Datenlisten_Ende; ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) AUF DB[ #DBDatenliste]; L #Datenlisten_Ende; L #DB_Länge; >I ;//Datenlisten-DB ist zu kurz! SPB Err0;//kein Datenlisten-Bereich L DBW[ #AR1Zeiger]; L 16#DAEE ;//Datenliste-Endekennung ? <>I;//Nein ! U(; TAK; L 16#DBEE;//Sort-Datenliste-Endekennung ? <>I;//Nein ! ); SPB Err0;//kein Datenlisten-Bereich L #Datensatzlaenge;//Datenblocklänge L 2; *I; T #Datenblock_inBytes;//Datenblocklänge in Bytes NETWORK TITLE = Auftrag kontrollieren SET; R #Indok;//Indizierung möglich R #IndZeiger_ok;//Indizier-Zeiger angegeben R #Weitersuchen;//Weitersuchen ist aktiv R #Offsetsuchen;//Offsetsuchen ist aktiv L 0;//Vorerst kein Offset T #OffsetDaten_1; L #PARA; T %LW40 ;//Aufrufparameter zwischenspeichern L 16#00;//XX = 00 ? L #Para1; ==I;//Ja! SPB W401; L 16#E1;//XX = E1 ? ==I;//Ja! U #Sortliste;//Sortliste wird durchsucht SPB Err3;//Falscher Aufrufparameter (austragen nicht erlaubt !) TAK; L 16#E1;//XX = E1 ? ==I;//Ja! SPB W401; L 16#F1;//XX = F1 ? L #Para1; <>I;//Nein ! SPB W400; L #Para2; L 16#00; <>I; O #Sortliste;//Sortliste wird durchsucht SPB Err3;//Falscher Aufrufparameter SET; S #Weitersuchen; L #SSDW; + 20; T #Suchzeiger; SPA Nw08;//OutDaten ok ? W400: L 16#FF;//XX = FF ? <>I;//Nein ! SPB W403; L #Para2; L 16#00; <>I; O #Sortliste;//Sortliste wird durchsucht SPB Err3;//Falscher Aufrufparameter SET; S #Weitersuchen; L #Suchzeiger;//Alter Suchzeiger L #Datenblock_inBytes;//Datenblocklänge in bytes +I;//Nächsten Datensatz suchen T #Suchzeiger;//Neuer Suchzeiger L #Datenblock_inBytes;//Datenblocklänge in bytes L #Listenlaenge;//Alle möglichen Einträge *I;//Gesamtlänge L #SSDW;//Startpunkt +I; + 20;//Offset 1.Daten L #Suchzeiger;//Schreibzeiger >I ;//Noch nicht am Ende ! SPB Nw08;//OutDaten ok ? SPA Err2;//Listenende erreicht W403: L 16#02;//XX < 02 ? L #Para1; >I;//Ja! SPB Err3;//Falscher Aufrufparameter L 16#80;//XX > 80 ? >I;//Ja! SPB Err3;//Falscher Aufrufparameter TAK; L #Datensatzlaenge;//XX > Datensatzlänge >I;//Ja! SPB Err3;//Falscher Aufrufparameter TAK; + -1;//Angegebener Offset -1 L 2;//DB byteorientiert *I; T #OffsetDaten_1;//Richtiger Offset der 1.Stammdaten L 0; T #Suchzeiger;//Suche ab Anfang SET; S #Offsetsuchen; W401: L 16#00;//=0 ? L #Para2;//2.Aufrufparameter ==I;//Ja ! SPB W402; T #Stammdaten;//Anzahl der Stammdaten L #Datensatzlaenge;//Datenblocklänge >I; SPB Err3;//Falscher Aufrufparameter L 1; L #Stammdaten;//Anzahl der Stammdaten >I; SPB Err3;//Falscher Aufrufparameter L 9; >I; SPB Err3;//Falscher Aufrufparameter W402: UN #Offsetsuchen; SPB Nw05; L #Para1;//Offset + -1; L #Stammdaten; +I;//Letzte Stammdaten zu groß ? L #Datensatzlaenge; >I;//Ja! SPB Err3;//Falscher Aufrufparameter NETWORK TITLE = Suchdaten definiert ? //Such-DATEN-Pointer übernehmen: Nw05: L 0; T #Suchzeiger;//Suchzeiger L P##SEARCHDATEN; LAR2; L W[ AR2, P#0.0]; T #DBSuchDaten;//Suchdaten-DB L D[ AR2, P#2.0];//Kennung, Adresse T #SuchDaten_Pointer; L #DBSuchDaten;//Suchdaten-DB L 0;//Angegeben ? ==I;//Nein SPB W501; CALL "TEST_DB_TO_ATTR_DB" ( DB_Number := #DBSuchDaten , RetVal := #SFC_RET_VAL , DB_Length := #SFC_DB_LENGTH , Write_Prot := #SFC_WRITE_PROT ); CALL "BCD (4stellig)_to_INT" ( BCD_Wert := #SFC_DB_LENGTH , Int_Wert := #DB_Länge ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000;//Fehler vorhanden ? <>I;//Ja ! SPB Err4;//Undefinierte Stammdaten L D[ AR2, P#2.0];//Kennung, Adresse L 16#00FF_FFFF;//Ohne Kennung UW; SRW 3;//Ohne Bit T #SuchDaten_Startpunkt; L #Datensatzlaenge;//Datenblocklänge L 2;//DB byteorientiert *I; L #SuchDaten_Startpunkt; +I; L #DB_Länge; >I;//Suchdaten-DB ist zu kurz SPB Err4;//Undefinierte Stammdaten W501: L #SuchDaten_Pointer; LAR2; L #DBSuchDaten;//Suchdaten-DB L 0;//Angegeben ? ==I;//Nein SPB W502; AUF DB[ #DBSuchDaten]; W502: L W[ AR2, P#0.0];//Suchdaten überprüfen T #Daten_1;//1.Suchdaten speichern L D[ AR2, P#0.0] ;//Suchdaten überprüfen T #Daten_2 ;//1.Suchdaten speichern L #Stammdaten; L500: T #Schleife; L #DBSuchDaten;//Suchdaten-DB L 0;//Angegeben ? ==I;//Nein SPB W503; AUF DB[ #DBSuchDaten]; W503: L W[ AR2, P#0.0];//Suchdaten überprüfen L 0;//Etwas angegeben ? <>I;//Ja ! SPB Nw06;//Weiter +AR2 P#2.0; L #Schleife; LOOP L500; SPA Err4;//Undefinierte Stammdaten NETWORK TITLE = Indiziert suchen ? Nw06: L #IndDB;//Indizierter DB L 0;//=0 ? ==I;//Kein indizierter DB ! O #Offsetsuchen; O #Sortliste;//Sortliste wird durchsucht SPB Nw07; CALL "TEST_DB_TO_ATTR_DB" ( DB_Number := #IndDB , RetVal := #SFC_RET_VAL , DB_Length := #SFC_DB_LENGTH , Write_Prot := #SFC_WRITE_PROT ); CALL "BCD (4stellig)_to_INT" ( BCD_Wert := #SFC_DB_LENGTH , Int_Wert := #DB_Länge ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000; <>I; O #SFC_WRITE_PROT; SPB Nw07;//kein Indizier-DB vorhanden L #IndDB_Laenge;//Länge des Indizierten DB überschritten ? L DINT#2 ;//DB byteorientiert *D; L #DB_Länge; >I;//Indizier-DB ist zu kurz SPB Nw07;//Zeiger ausserhalb Ind.DB L #Stammdaten;//Stammdaten L 3 ;//zu viele Stammdaten ? >=I ;//Ja ! SPB Nw07;//ohne Indizierung weiter L #IndDaten_FC;//Offset zum Abziehen T #Wandel_FC; L 0;//Parameter vorhanden ? <=I;//Nein SPB NoFC;//Bei diesem Schritt weiter L #Daten_1 ;//Stammdaten (1.DW) T "MW90";//übergeben L #Daten_2 ;//Stammdaten (2.DW) T "MD94" ;//übergeben UC FC[ #Wandel_FC];//Beeinflussung der Weiterfahrt L "MW92";//Rückwert von FC SPA Ret; NoFC: L #Daten_1;//Stammdaten Ret: T #IndPointer;//Stelle, wo Zeiger hinterlegt ist L 0; I;//Suchzeiger nicht im Raster ! SPB W700;//Suche bei 1.Datensatz beginnen L 0;//Bei angegebener Stelle suchen T #Suchstelle;//Such bei X-ten Datensatz SPA W701; W700: L 1;//Suche bei 1.Datensatz beginnen T #Suchstelle;//Such bei X-ten Datensatz SET; R #IndZeiger_ok;//Indizier-Zeiger angegeben L #SSDW; + 20;//Offset für 1.Daten T #Suchzeiger;//Suchzeiger W701: L #Suchzeiger;//Suchzeiger L #OffsetDaten_1;//Richtiger Offset der 1.Stammdaten +I; ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) L #SuchDaten_Pointer; LAR2; L #Stammdaten;//Anzahl der Stammdaten L700: T #Schleife; L #DBSuchDaten;//Suchdaten-DB L 0;//Angegeben ? ==I;//Nein SPB W702; AUF DB[ #DBSuchDaten]; W702: L W[ AR2, P#0.0] ;//Suchdaten überprüfen mit AUF DB[ #DBDatenliste]; L DBW[ #AR1Zeiger] ;//Datenliste-Daten lesen <>I ;//nicht identisch ! SPB W703; L #AR1Zeiger; SRD 3; L DINT#2; +D; SLD 3; T #AR1Zeiger; +AR2 P#2.0; L #Schleife; LOOP L700; L 2#0000_0000_1000_0000;//Daten sind vorhanden T #tRE_VAL;//Ok-Status SPA Nw08;//Datensatz ist in Liste enthalten W703: L 0;//Suche bei 1.Datensatz begonnen L #Suchstelle;//Such bei X-ten Datensatz ==I;//Nein ! SPB W700; L #Suchstelle;//Such bei X-ten Datensatz + 1; T #Suchstelle;//Such bei X-ten Datensatz L #Listenlaenge;//Anzahl aller Daten in Datenliste <=I;//Alle Datensätze sind durchsucht SPB W705;//Nein ! SPA Err6;//Datensatz ist nicht vorhanden W705: L #Datenblock_inBytes;//Datenblocklänge in bytes L #Suchzeiger;//Suchzeiger +I; T #Suchzeiger;//Suchzeiger SPA W701; NETWORK TITLE = Outdaten ok ? //Out-DATEN-Pointer übernehmen: Nw08: L P##OUTDATEN; LAR2; L W[ AR2, P#0.0]; T #DBOutDaten;//Outdaten-DB L D[ AR2, P#2.0];//Kennung, Adresse T #OutDaten_Pointer; L #DBOutDaten;//Outdaten-DB L 0;//Angegeben ? ==I;//Nein SPB Nw09; CALL "TEST_DB_TO_ATTR_DB" ( DB_Number := #DBOutDaten , RetVal := #SFC_RET_VAL , DB_Length := #SFC_DB_LENGTH , Write_Prot := #SFC_WRITE_PROT ); CALL "BCD (4stellig)_to_INT" ( BCD_Wert := #SFC_DB_LENGTH , Int_Wert := #DB_Länge ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000;//Fehler vorhanden ? <>I;//Ja ! SPB Err5;//Undefinierte Outdaten L D[ AR2, P#2.0];//Kennung, Adresse L 16#00FF_FFFF;//Ohne Kennung UW; SRW 3;//Ohne Bit T #OutDaten_Startpunkt; L #OutDaten_Startpunkt; L #DB_Länge; >I;//Outdaten-DB ist zu kurz SPB Err5;//Undefinierte Outdaten NETWORK TITLE = Daten aus Datenliste lesen (in OUTDaten übergeben) //Quelle-Pointer erzeugen: Nw09: L 16#1004;//Kennung 10 + Word=04 T %LW0; T %LW10;//Any-Kennung, Datentyp L #Datensatzlaenge;//Datenwords speichern T %LW2; T %LW12;//Wiederholungen //DATEN-Pointer übernehmen: L #SSDB; T %LW4;//DB_Nummer L #Suchzeiger;//Adresse SLD 3; L 16#8400_0000;//Kennung: Daten OD; T %LD6;//Kennung, Adresse //Ziel-Pointer erzeugen: //Kennung + Datenbytes s.o. L #DBOutDaten; T %LW14;//DB_Nummer L #OutDaten_Pointer; T %LD16;//Kennung, Adresse CALL BLKMOV//Datenliste-Daten speichern {blk_type := 'Variant'} ( SRCBLK := #Quelle , RET_VAL := #SFC_RET_VAL , DSTBLK := #Ziel ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000; <>I; SPB Err1; U #SFC_WRITE_PROT;//Datenliste kann nicht beschrieben werden SPB Nw10; L #SSDW; + 12;//Offset letzter Zugriff ITD; SLD 3;//Pointer erzeugen T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) L #Suchzeiger;//Suchzeiger AUF DB[ #DBDatenliste]; T DBW[ #AR1Zeiger];//Speicherung letzter Zugriff L #Suchstelle;//Such bei X-ten Datensatz T #Position ;//Übergabe nach außen NETWORK TITLE = Daten aus Datenliste löschen ? (nicht indiziert!) Nw10: L 16#E1;//Daten löschen ? L #Para1;//1.Aufrufparameter <>I;//Nein ! O #SFC_WRITE_PROT;//Datenliste kann nicht beschrieben werden SPB Nw11; U #Indok ;//Indizierung möglich SPB X010;//Bei ind.Zugriff nur löschen, nicht verschieben, keine Anzahl! //Gemeinsame Daten für Pointer erzeugen: L 16#1004;//Kennung 10 + Word=04 T %LW0; T %LW10;//Any-Kennung, Datentyp L #Suchzeiger;//Stelle, wo gelöscht werden soll + -20; L #SSDW; -I; L #Datenblock_inBytes;//Datenblocklänge in bytes /I; + 1;//Stelle, die gelöscht werden soll T #LoeschPos;//Lösch-Position L #Listenlaenge;//Länge der Datenliste (Letzter Eintrag zum Löschen ?) ==I;//Ja ! SPB Last;//Ohne Verschieben letzten Eintrag löschen L #LoeschPos;//Lösch-Position L #Datensatzlaenge;//Datenblocklänge *I;//Gesamtdatenlänge in Words T #NichtCopy;//Datenmenge, die nicht vorschoben wird L #Listenlaenge;//Länge der Datenliste L #Datensatzlaenge;//Datenblocklänge *I;//Gesamtdatenlänge in Words L #NichtCopy;//Datenmenge, die nicht vorschoben wird -I;//abziehen T %LW2; T %LW12;//Wiederholungen L #SSDB; T %LW4; T %LW14;//DB_Nummer //Quelle-Pointer erzeugen: L #Suchzeiger;//Stelle, wo gelöscht werden soll L #Datenblock_inBytes;//Datenblocklänge in Bytes +I; SLD 3; L 16#8400_0000;//Kennung: Daten OD; T %LD6;//Kennung, Adresse //Ziel-Pointer erzeugen: L #Suchzeiger;//Stelle, wo gelöscht werden soll SLD 3; L 16#8400_0000;//Kennung: Daten OD; T %LD16;//Kennung, Adresse //Daten verschieben: CALL BLKMOV//DatenSortliste-Daten verschieben {blk_type := 'Variant'} ( SRCBLK := #Quelle , RET_VAL := #SFC_RET_VAL , DSTBLK := #Ziel ); L #SFC_RET_VAL; L 2#0000_0000_0000_0000; <>I; SPB Err1; //Letzte Daten löschen: Last: L #Datenlisten_Ende;//Ende des Datenbereichs L #Datenblock_inBytes;//Datenblocklänge in Bytes -I;//Ab hier löschen ! ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) L #Datensatzlaenge;//Datensatzlänge L080: T #Schleife; AUF DB[ #DBDatenliste]; L 0;//Daten löschen T DBW[ #AR1Zeiger]; L #AR1Zeiger; SRD 3; L 2;//nächstes DW +D; SLD 3; T #AR1Zeiger; L #Schleife; LOOP L080; //Speicherung letzter Zugriff: L #SSDW; + 12;//Offset letzter Zugriff ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) AUF DB[ #DBDatenliste]; L 0;//löschen T DBW[ #AR1Zeiger];//Speicherung letzter Zugriff T #Suchzeiger;//Suchzeiger SET; R #IndZeiger_ok;//Indizier-Zeiger angegeben //Anzahl Einträge: L #SSDW; + 16 ;//Offset Anzahl Einträge ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) AUF DB[ #DBDatenliste]; L DBW[ #AR1Zeiger];//Anzahl der Einträge + -1;//-1 T DBW[ #AR1Zeiger];//Anzahl der Einträge L 0; >=I; SPB w080; T DBW[ #AR1Zeiger];//Minimum übergeben w080: SPA Nw11; NETWORK TITLE = Daten aus Datenliste löschen ? (indiziert) X010: L 16#E1 ;//Daten löschen ? L #Para1;//1.Aufrufparameter <>I;//Nein ! SPB Nw11; L #Suchzeiger;//Suchzeiger ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) AUF DB[ #DBDatenliste]; L #Datensatzlaenge; LA00: T #Schleife; L 0; T DBW[ #AR1Zeiger]; L #AR1Zeiger; SRD 3; L DINT#2; +D; SLD 3; T #AR1Zeiger; L #Schleife; LOOP LA00; L #SSDW; + 12; ITD; SLD 3; T #AR1Zeiger;///Statt AR1 (ging nur bis DB-Länge <= 8191 Bytes) L 0;//Löschen T #Suchzeiger;//Suchzeiger T DBW[ #AR1Zeiger]; SET; R #IndZeiger_ok;//Indizier-Zeiger angegeben NETWORK TITLE = Weitersuchen aktiv ? Datensatz vorhanden oder 0 ? Nw11: UN #Weitersuchen; SPB Nw12; L #OutDaten_Pointer; LAR2; L #Datensatzlaenge; L110: T #Schleife; L #DBOutDaten;//Outdaten-DB L 0;//Angegeben ? ==I;//Nein SPB W111; AUF DB[ #DBOutDaten]; W111: L W[ AR2, P#0.0];//Outdaten überprüfen L 0;//Etwas angegeben ? <>I;//Ja ! SPB W112;//Ok +AR2 P#2.0; L #Schleife; LOOP L110; L 2#0000_0000_0100_0000;//Daten sind nicht vorhanden T #tRE_VAL;//Ok-Status SPA Ende; W112: L 2#0000_0000_1000_0000;//Daten sind vorhanden T #tRE_VAL;//Ok-Status SPA Ende; NETWORK TITLE = Indizierung ok ? Nw12: UN #Indok;//Indizierung möglich O #IndZeiger_ok;//Indizier-Zeiger angegeben SPB Ende; AUF DB[ #IndDB];//Indizierter DB L #Suchzeiger;//Suchzeiger T DBW[ #IndPointer]; AUF DB[ #DBDatenliste];//Datenliste DB NETWORK TITLE = Fehlerausgabe / RET_VAL Ende: SET;//VKE = 1 ohne Fehler !!! L #tRE_VAL;//Ok-Status SPA Ok; Err0: L 2#0000_0000_0000_0001;//Kein Datenlistebereich SPA Err; Err1: L 2#0000_0000_0000_0010;//SFC20-Aufruf mit Fehler SPA Err; Err2: L 2#0000_0000_0000_0100;//Listenende ist erreicht SPA Err; Err3: L 2#0000_0000_0000_1000;//Falscher Parameter bei Aufruf SPA Err; Err4: L 2#0000_0000_0001_0000;//Undefinierte Suchdaten SPA Err; Err5: L 2#0000_0000_0010_0000;//Undefinierte OUTDaten SPA Err; Err6: L 2#0000_0000_0100_0000;//Datensatz nicht vorhanden Err: CLR;//VKE = 0 bei Fehler !!! Ok: T #tRE_VAL; SAVE;//VKE in BIE-Bit speichern L #AR2_Speicher;//AR2 zurückspeichern LAR2; NETWORK TITLE = Ende L #tRE_VAL; T #RE_VAL; END_FUNCTION