TIA Kalenderwoche errechnen

Zuviel Werbung?
-> Hier kostenlos registrieren
Seit dem 30.03.2017 ist bei Siemens die V3.0.0 der "Bibliothek mit generellen Funktionen (LGF) für STEP 7 (TIA Portal) und S7-1200 / S7-1500" online, die jetzt neben anderen netten Dingen auch die Berechnung der Kalenderwoche enthält:

Verdammt diese Bibliothek kannte ich noch gar nicht. Hab erst letzten Monat Meine Astronomische Uhr S7-1500 Kompatibel gemacht. Dabei hätte es ja ne fertige Funktion gehabt direkt von Siemens. *arglhaareausreiss*

mfG René
 
Hi,

ich weiß, der Fred hier ist eigentlich schon tot (knapp drei Jahe alt), aber ich frage mich, warum man das so kompliziert macht. Ich musste mal das Problem mittels VBScript lösen, da war das viel Übersichtlicher, als das, was hier von Seiten Siemens geboten wird. Ich habe dieses VB-Script "einfach" mal in SCL umgeschrieben. Die Berechnung erfolgt Übrigens nach EU-Standard (ISO 8601).

TIA-SCL S7-1200/1500er CPU:
Code:
FUNCTION "CalendarWeek" : Int
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_TEMP 
      "void" : Int;   // don't need a return value
      UInt_Date : UInt;   // Aktuelles Datum als Zahlenwert
      UInt_Diff : UInt;   // Jahresanfang als ZahlenWert
      Slide : UInt;   // Wochentagsverschiebung
      DT_ref {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // Referenzierter Zeitstempel
   END_VAR


BEGIN
	(*  Funktionsweise
	    ~~~~~~~~~~~~~~
	    Der Code dieses Bausteins ist von folgendem VBScript inspiriert:
	    
	    Option Explicit
	    Dim Slide, KW
	    Slide = (Date - 2) Mod 7
	    KW = Fix((Date - DateSerial(Year(Date + 3 - Slide), 1, Slide - 9)) / 7)
	    
	    Bei VBScript beginnt das Format "Date" am 30.12.1899 (CLng(CDate("30.12.1899")) = 0) und in Step7 am 01.01.1990 (DATE_TO_INT(DATE#1990-01-01) = 0).
	    Aus diesem Grund entfaellt in Step7 das (Date - 2).
	    Ferner ueberspringt DateSerial den den 0.01. bei der Berechnung mit negativen Werten (Slide - 9 kann -2..-9 betragen), weshalb die Berechnung in
	    Step7 auf #Slide - 10 angepasst werden muss, um am Ende das gleiche Differenzergebnis #UInt_Dat - UInt_Diff zu erhalten.
	*)
	
	//Systemzeit (als Lokalzeit) einlesen
	#void := RD_LOC_T(#DT_ref);
	
	//Systemzeit als Zahlenwert
	#UInt_Date := DATE_TO_UINT(DTL_TO_DATE(#DT_ref));
	
	//Wochentagsverschiebeung
	#Slide := #UInt_Date MOD 7;
	
	//Verschiebung auf Systemzeit aufrechnen
	#DT_ref := DATE_TO_DTL(UINT_TO_DATE(#UInt_Date + 3 - #Slide));
	
	//Datum auf den 01.01. des resultierenden Jahres aufrechnen
	#DT_ref.MONTH := 1;
	#DT_ref.DAY := 1;
	
	//Resultierendes Datum als Zahlenwert mit Wochentagsverschiebung
	#UInt_Diff := DATE_TO_UINT(DTL_TO_DATE(#DT_ref)) + #Slide - 10;
	
	//Ausgabe der Kalenderwoche
	#CalendarWeek := UINT_TO_INT(#UInt_Date - #UInt_Diff) / 7;
	
END_FUNCTION

TIA-SCL S7-300/400er CPU:
Code:
FUNCTION "CalendarWeek" : Int
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_TEMP 
      "void" : Int;   // don't need a return value
      DINT_Date : DInt;   // Aktuelles Datum als Zahlenwert
      DINT_Diff : DInt;   // Jahresanfang als ZahlenWert
      Slide : DInt;   // Wochentagsverschiebung
      DT_ref : Date_And_Time;   // referenzierter Zeitstempel
      DT_ref_bytes AT DT_New : Struct   // aufgesplitteter zeitstempel
         YY : Byte;   // Jahr
         MO : Byte;   // Monat
         DD : Byte;   // Tag
         hh : Byte;   // Stunde
         mm : Byte;   // Minute
         ss : Byte;   // Sekunde
         dc : Byte;   // Dezi- und Centisekunde
         md : Byte;   // Millisekunde und DayCode
      END_STRUCT;
   END_VAR


BEGIN
	(*  Funktionsweise
	    ~~~~~~~~~~~~~~
	    Der Code dieses Bausteins ist von folgendem VBScript inspiriert:
	    
	    Option Explicit
	    Dim Slide, KW
	    Slide = (Date - 2) Mod 7
	    KW = Fix((Date - DateSerial(Year(Date + 3 - Slide), 1, Slide - 9)) / 7)
	    
	    Bei VBScript beginnt das Format "Date" am 30.12.1899 (CLng(CDate("30.12.1899")) = 0) und in Step7 am 01.01.1990 (DATE_TO_DINT(DATE#1990-01-01) = 0).
	    Aus diesem Grund entfaellt in Step7 das (Date - 2).
	    Ferner ueberspringt DateSerial den den 0.01. bei der Berechnung mit negativen Werten (Slide - 9 kann -2..-9 betragen), weshalb die Berechnung in
	    Step7 auf #Slide - 10 angepasst werden muss, um am Ende das gleiche Differenzergebnis #DInt_Dat - DInt_Diff zu erhalten.
	*)
	
	//Systemzeit einlesen
	#void := RD_SYS_T(#DT_ref);
	
	//Systemzeit als Zahlenwert
	#DINT_Date := DATE_TO_DINT(DT_TO_DATE(#DT_ref));
	
	//Wochentagsverschiebeung
	#Slide := #DINT_Date MOD 7;
	
	//Verschiebung auf Systemzeit aufrechnen
	#DT_ref := CONCAT_DATE_TOD(IN1 := DINT_TO_DATE(#DINT_Date + 3 - #Slide), IN2 := TOD#00:00:00);
	
	//Datum auf den 01.01. des resultierenden Jahres aufrechnen
	#DT_ref_bytes.MO := 1;
	#DT_ref_bytes.DD := 1;
	
	//Resultierendes Datum als Zahlenwert mit Wochentagsverschiebung
	#DINT_Diff := DATE_TO_DINT(DT_TO_DATE(#DT_ref)) + #Slide - 10;
	
	//Ausgabe der Kalenderwoche
	#CalendarWeek := DINT_TO_INT(#DINT_Date - #DINT_Diff) / 7;
	
END_FUNCTION

Step7 5.x-SCL:
Code:
FUNCTION CalendarWeek : INT

TITLE=    'CalendarWeek'          
AUTHOR:   Holli    
FAMILY:   TIME_FCT    
NAME:     CalWeek
VERSION:  '0.1'

   VAR_TEMP 
      RETVAL : Int;   // don't need a return value
      DINT_Date : DInt;   // Aktuelles Datum als Zahlenwert
      DINT_Diff : DInt;   // Jahresanfang als ZahlenWert
      Slide : DInt;   // Wochentagsverschiebung
      DT_ref : Date_And_Time;   // Referenzierter Zeitstempel
      DT_ref_bytes AT DT_ref : Struct   // aufgesplitteter Zeitstempel
         YY : Byte;   // Jahr
         MO : Byte;   // Monat
         DD : Byte;   // Tag
         hh : Byte;   // Stunde
         mm : Byte;   // Minute
         ss : Byte;   // Sekunde
         dc : Byte;   // Dezi- und Centisekunde
         md : Byte;   // Millisekunde und DayCode
      END_STRUCT;      
BEGIN
    (*  Funktionsweise
        ~~~~~~~~~~~~~~
        Der Code dieses Bausteins ist von folgendem VBScript inspiriert:
    
        Option Explicit
        Dim Slide, KW
        Slide = (Date - 2) Mod 7
        KW = Fix((Date - DateSerial(Year(Date + 3 - Slide), 1, Slide - 9)) / 7)
        
        Bei VBScript beginnt das Format "Date" am 30.12.1899 (CLng(CDate("30.12.1899")) = 0) und in Step7 am 01.01.1990 (DATE_TO_DINT(DATE#1990-01-01) = 0).
        Aus diesem Grund entfaellt in Step7 das (Date - 2).
        Ferner ueberspringt DateSerial den den 0.01. bei der Berechnung mit negativen Werten (Slide - 9 kann -2..-9 betragen), weshalb die Berechnung in
        Step7 auf #Slide - 10 angepasst werden muss, um am Ende das gleiche Differenzergebnis #DInt_Date - DInt_Diff zu erhalten.
    *)

    //Systemzeit einlesen
    RETVAL := READ_CLK(CDT := DT_ref);
    
    //Systemzeit als Zahlenwert
    DINT_Date := DATE_TO_DINT(DT_DATE(DT_ref));
    
    //Wochentagsverschiebeung
    Slide := DINT_Date Mod 7;
    
    //Verschiebung auf Systemzeit aufrechnen
    DT_ref := D_TOD_DT(IN1 := DINT_TO_DATE(DINT_Date + 3 - Slide), IN2 := TOD#00:00:00);
    
    //Datum auf den 01.01. des resultierenden Jahres aufrechnen
    DT_ref_bytes.MO := 1;
    DT_ref_bytes.DD := 1;
    
    //Resultierendes Datum als Zahlenwert mit Wochentagsverschiebung
    DINT_Diff := DATE_TO_DINT(DT_DATE(DT_ref)) + Slide - 10;
    
    //Ausgabe der Kalenderwoche
    CalendarWeek := DINT_TO_INT(DINT_Date - DINT_Diff) / 7;
END_FUNCTION

Tests, in denen ich die Ausgabe mit dem PC-Kalender über "Jahre" (pro Sekunde ein Tag) verglichen habe, ergaben keine Abweichungen.

Ich hoffe, doch dem einen oder anderen damit geholfen zu haben.

Gruß,

Holli
 
Zurück
Oben