Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 24 von 24

Thema: SCL Stringvergleich indirekt aus DB

  1. #21
    Registriert seit
    06.10.2004
    Ort
    Kopenhagen.
    Beiträge
    4.639
    Danke
    377
    Erhielt 803 Danke für 644 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    @Ralle. Das ist klar.

    Aber sehr oft ist ein dynamischer zugriff gar nicht notwendig. Wie es von MFreiberger beschrieben ist, hat er 2 DBS die sicherlich feste sind.
    Meine erfahrung ist, das wenn man von unnötige Parameter-übertragungen verzichtet, denn vereinfacht sich das kodieren sehr viel.
    Keep It Simple.
    Jesper M. Pedersen

  2. #22
    Registriert seit
    06.10.2004
    Ort
    Kopenhagen.
    Beiträge
    4.639
    Danke
    377
    Erhielt 803 Danke für 644 Beiträge

    Standard

    So jetzt habe ich es mit Parameter transfer.
    UDT_StringArray enthält ein "Strings" ARRAY[0..99] of STRING[20]

    Code:
    FUNCTION FC3 : VOID
    VAR_INPUT
      strSearch : STRING ;
      strRecipe : UDT_StringArray ;
    END_VAR
    VAR_OUTPUT
      biMatchFound: BOOL ;
      iMatchIndex: INT ;
    END_VAR
    VAR_TEMP
      i: INT;
      strCompare1 : STRING ;
      strCompare2 : STRING ;
    END_VAR
        
        biMatchFound := FALSE ;
        iMatchIndex := 0 ;
        i := 0 ;
        strCompare1 := strSearch  ;
        WHILE biMatchFound = FALSE AND i < 100  DO
            strCompare2 := strRecipe.Strings[i] ;
            biMatchFound := EQ_STRNG(S1 := strCompare1 , S2 := strCompare2 );
            i := i + 1 ;
        END_WHILE;
        IF biMatchFound = TRUE THEN iMatchIndex := i ; END_IF ;
        
    END_FUNCTION
    Jesper M. Pedersen

  3. #23
    MFreiberger ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    06.11.2008
    Beiträge
    135
    Danke
    13
    Erhielt 6 Danke für 6 Beiträge

    Standard

    Hallo,

    hab einiger Zeit habe ich noch eine brauchbare Lösung gefunden:

    Code:
    FUNCTION_BLOCK FB50
     
    (*Variablendeklaration
    ***************************************************************************************************)
    VAR_INPUT                                                                                           //Eingangsvariablen
        IN_suchen:BOOL;
        IN_DBNR:INT;
        IN_DBM:INT; 
        IN_Zyklen:INT;
        IN_Loop:INT;
        IN_DSlen:INT;
        IN_Stringlaenge:INT;
        IN_Artikel:STRING;
    END_VAR
    VAR_OUTPUT                                                                                          //Ausgangsvariablen
        OUT_busy:BOOL;
        OUT_gefunden:BOOL;
        OUT_DB:INT; 
        OUT_DBB:INT; 
    END_VAR
    VAR                                                                                                 //Statische Variablen
        STAT_suchen:BOOL;
        STAT_busy:BOOL;
        STAT_gefunden:BOOL;;
        STAT_DBB:INT;
        STAT_Loop:INT;
        STAT_Zyklus:INT;
        STAT_DSNR:INT;
        STAT_DBNR:INT;
        STAT_DBM:INT;
        STAT_For_Min:INT;
        STAT_For_Max:INT;   
        STAT_Zyklen:INT;
        STAT_LoopSoll:INT;
        STAT_DSlen:INT;
        STAT_Stringlaenge:INT;
        STAT_DB_Artikel:STRING;
    END_VAR
    VAR_TEMP                                                                                            //Temoräre Variablen
           TEMP_Source : ANY;                                                                           //Any Quellzeiger
        VON AT TEMP_Source: STRUCT                                                                      //AT-Befehl: Die einzelnen Bestandteile der vorhergehenden Variablen werden in einer Struktur aufgeschlüsselt
        ID  : WORD;
        NBR : INT;
        DBN : INT;
        PTR : DWORD;
        END_STRUCT;
           TEMP_DESTIN : ANY;                                                                           //Any Zielzeiger
        NACH AT TEMP_DESTIN: STRUCT                                                                     //AT-Befehl: Die einzelnen Bestandteile der vorhergehenden Variablen werden in einer Struktur aufgeschlüsselt
        ID  : WORD;
        NBR : INT;
        DBN : INT;
        PTR : DWORD;
        END_STRUCT;
            TEMP_DB_Artikel:STRING;                                                                     //Vergleichsstring
        Aufbau AT TEMP_DB_Artikel: STRUCT
        MAXlen:BYTE;
        ISTlen:BYTE;
        Zeichen:ARRAY[1..254] OF BYTE;
        END_STRUCT;
        TEMP_SFC_Err:INT;
        TEMP_Faktor:DINT;
        TEMP_Produkt:DINT;
    END_VAR
     
    (*Initialisierung
    ****************************************************************************************************)
    STAT_Zyklen := IN_Zyklen;                                                                           //Eingangswerte an statische Variablen übergeben
    STAT_LoopSoll := IN_Loop;
    STAT_Stringlaenge := IN_Stringlaenge;
    STAT_DSlen := IN_DSlen;
    STAT_DBM := IN_DBM;
    (*Programmcode
    ****************************************************************************************************)
    IF (STAT_busy = false) AND (IN_suchen <> STAT_suchen) AND (IN_suchen = true) THEN                   //Suche Starten wenn nicht aktiv und Startflanke
        STAT_busy := true; 
        STAT_gefunden := false;                                                                             //Suche aktiv setzen
        STAT_Zyklus := 0;                                                                               //Zyklusanzahl initialisieren
        STAT_DBNR := IN_DBNR;     
    END_IF;
    IF (STAT_busy = true) AND (STAT_Zyklus < STAT_Zyklen) AND (STAT_DBNR < (IN_DBNR + STAT_DBM))THEN    //Bedingung: Suchen gestartet und Anzahl Zyklen und DB´s < SOLL
     
                STAT_For_Min := STAT_Zyklus * STAT_LoopSoll;                                            //FOR-Schleife Minimum = Suchzyklus * Anzahl der Durchläufe pro Zyklus
                STAT_For_Max := STAT_For_Min + STAT_LoopSoll;                                           //FOR-Schleife Maximum = Minimum + Anzahl der Durchläufe pro Zyklus
     
                FOR STAT_Loop := STAT_For_Min TO STAT_For_Max DO                                        //FOR-Schleife von Minimum bis Maximum. STAT_Loop: Wert des aktuellen Durchlaufs    
     
                    STAT_DSNR := STAT_Zyklus + STAT_Loop;                                               //Die aktuelle Datensatznummer ergibt sich aus der Anzahl der Zyklen und Loops
                    TEMP_Faktor := 8 * STAT_DSlen;                                                      //Faktor: 8 (für Bit) * Datensatzlänge in BYTE        
                    TEMP_Produkt := STAT_DSNR * TEMP_Faktor;                                            //TEMP_Produkt: Offset des aktuellen Datensatzes
     
                    VON.ID := w#16#1002;                                                                //10: "Siemens"; 02: Datentyp BYTE
                    VON.NBR := (STAT_Stringlaenge + 2);                                                 //Anzahl der zu Übertragenden Bytes
                    VON.DBN := STAT_DBNR;                                                               //aktuelle Datenbausteinnummer
                    VON.PTR := DINT_TO_DWORD(TEMP_Produkt) OR 16#8400_0000;                             //keine Berechnung für DINT_TO_DWORD, deshalb Berechnung vorher 84: Speicherbereich Datenbaustein
     
                    NACH.ID := w#16#1002;                                                               //10: "Siemens"; 02: Datentyp BYTE
                    NACH.NBR := (STAT_Stringlaenge + 2);                                                //Anzahl der zu Übertragenden Bytes
                    NACH.DBN := 0;                                                                      //"0", da Instanzdatenbaustein
                    NACH.PTR := INT_TO_WORD(302 * 8) OR 16#8500_0000;                                   //Achtung: Offset abhängig von IDB-Aufbau; 85: Speicherbereich Instanzdatenbaustein
     
                    TEMP_SFC_Err := BLKMOV(SRCBLK := TEMP_Source, DSTBLK := TEMP_DESTIN);               //SFC20 "Blockmove" Quellzeiger in Zielzeiger. Rückgabewert: Bearbeitungsfehler
                    TEMP_DB_Artikel := STAT_DB_Artikel;                                                 //von Any "NACH" wird auf STAT_DB_Artikel gezeigt und dieser dann in TEMP_DB_Artikel geschrieben
                    Aufbau.ISTlen := INT_TO_BYTE(STAT_Stringlaenge);                                    //Istlänge des Strings wird beschrieben damit der Vergleich korrekt durchgeführt wird.
     
                    IF IN_Artikel = TEMP_DB_Artikel THEN                                                //Stringvergleich (benötigt FC10 "EQ_STRING" Bibliothek: IEC)
                        STAT_gefunden := true;                                                          //Bei "TRUE":   -Artikel gefunden
                        STAT_busy := false;                                                             //              -Suche beenden        
                        OUT_DBB := STAT_DSlen*STAT_DSNR;                                                //              -Offsetwert des Speicherbereichs im DB
                        OUT_DB := STAT_DBNR;                                                            //              -Datenbausteinnummer  
                        EXIT;                                                                           //              -Schleife beenden
                    ELSE                                                                                
                        STAT_gefunden := false;                                                         //Bei "FALSE":  -Artikel nicht gefunden
                    END_IF;
                END_FOR;
                STAT_Zyklus := STAT_Zyklus + 1;                                                         //Zyklus durchlaufen: 1 Zyklus addieren
    ELSE
     
        STAT_busy := false;                                                                             //Suche beenden
    END_IF;
    IF STAT_Zyklus >= STAT_Zyklen THEN                                                                  //Alle Datensätze dieses DB´s geprüft
     
        STAT_Zyklus := 0;                                                                               //Zykluszähler resetten
        STAT_DBNR := STAT_DBNR + 1;                                                                     //DB durchlaufen: 1 Db addieren        
    END_IF;
     
    STAT_suchen := IN_suchen;                                                                           //Flankenmerker zum Suchstart neu beschreiben
    (*Ausgaben
    ***********************************************************************************************)
    OUT_busy := STAT_busy;                                                                              //Ausgang suche läuft
    OUT_gefunden := STAT_gefunden;                                                                      //Ausgang STRING gefunden
     
    END_FUNCTION_BLOCK
    _____________________________________________
    "Von nichts kommt was" von B. Trüger
    Zitieren Zitieren Idee mit "Any"  

  4. #24
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.794
    Danke
    398
    Erhielt 2.417 Danke für 2.013 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,
    schön, wenn du jetzt eine für dich brauchbare Lösung hast ...
    Trotzdem kann ich es mir nicht verkneifen ... die Sache mit dem Any-Pointer und dem BlockMove sowie die ganze fest indizierte Programmierung hättest du dir ersparen können, wenn du meinen Vorschlag aufgegriffen hättest. Dort wäre es für dich möglich gewesen, auf die Elemente des "externen" DB's direkt (symbolisch) zuzugreifen. Möglicherweise wäre das auch von der Bearbeitungszeit günstiger ausgefallen ...

    Gruß
    LL

Ähnliche Themen

  1. SCL: Stringvergleich funktioniert nicht
    Von Scanda im Forum Simatic
    Antworten: 11
    Letzter Beitrag: 07.08.2011, 11:12
  2. Stringvergleich FC10
    Von rr_zx im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 17.07.2011, 18:34
  3. SCL indirekt Adressieren
    Von Nafura im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 19.05.2011, 21:42
  4. ComboBox indirekt?
    Von SPSKILLER im Forum Hochsprachen - OPC
    Antworten: 6
    Letzter Beitrag: 01.09.2008, 15:25
  5. Problem beim Stringvergleich EQ_STRNG
    Von BohneM im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 28.11.2007, 23:23

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •