TIA Kalenderwoche errechnen

TIAISM

Level-1
Beiträge
100
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hey SPS Forum Team,

ich stehe gerade vor einer Herausforderung und benötige eure Hilfe :)

Wie ermittle ich die Kalenderwoche (KW) mit dem TIA Portal V13 SP1 UPD8.

Gibt es eine einfache Formel oder eventuell sogar Funktion mit der ich die Kalenderwoche ermitteln kann.

Es wäre schön, wenn es eine Lösung in KOP gäbe. SCL, AWL hilft mir leider nicht weiter :)

siehe Anhang/ Screenshot
Diese Daten lese ich bereits aus. Leider ist keine KW dabei

Danke
 

Anhänge

  • Date&Time.png
    Date&Time.png
    38,4 KB · Aufrufe: 150
Zuviel Werbung?
-> Hier kostenlos registrieren
Das wäre zB eine Möglichkeit welche ich mal in Excel gemacht habe


Code:
Public Function Kalenderwoche(XDatum As Variant, fModus As Boolean) As String
' Gibt Ein Datum als "ww\jjjj" String zurück
' Wenn eine Wochennummer in ein unterschiedliches Jahr fällt,
' so wird dies berücksichtigt
' d.h. 31.12.2002 = 01\2003 bzw. 1.1.1999 = 53\1998
    Dim x, y, Z
   
    Kalenderwoche = ""
    If Not IsDate(XDatum) Then Kalenderwoche = "": Exit Function
    XDatum = CDate(XDatum)
    x = Year(XDatum)
    y = Month(XDatum)
    Z = CInt(Format(XDatum, "ww", vbMonday, vbUseSystem))
    If Z > 52 Then
        If Format(XDatum + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then Z = 1
    End If
    If y = 12 And Z < 40 Then x = x + 1
    If y = 1 And Z > 10 Then x = x - 1
    If fModus = True Then
        Kalenderwoche = Right("00" & Z, 2) & "/" & Right("0000" & x, 4)
      Else
        Kalenderwoche = Right("00" & Z, 2)
    End If
End Function
 
Ich habe jetzt mal den SCL Code aus dem SIMATIC Projekt eingefügt.
Allerdings bekomme ich den nicht kompatibel. Habe leider nicht so vie SCL Erfahrung..

Ich stehe jetzt mit dem SUpport mit Siemens in Kontakt. Ich halte euch auf dem laufenden.

Danke



Danke
 
Ich habe jetzt mal den SCL Code aus dem SIMATIC Projekt eingefügt.
Allerdings bekomme ich den nicht kompatibel.
Hatte die KW-Berechnung mal für 'ne S7-1200 vom Siemens-Baustein für Classic auf TIA umgesetzt, weil ich das gleiche Problem hatte.

Die aktuelle Version gibt's jetzt etwas weiter unten im Post#8.



PS: Kann mir bitte jemand erklären, wie ich den SCL-Baustein unter TIA exportieren kann?
 
Zuletzt bearbeitet:
Kannst du mir das Backup von dem Projekt zu schicken??
Nein, das ganze Projekt gibt's nicht. ;)

Aber Dank Volker konnte ich den Baustein nun exportieren.
Hier also nochmal die komplette Quelle:

Code:
FUNCTION "FC CWD EU" : Int
TITLE = Calendar Week/Day (EU)
{ S7_Optimized_Access := 'TRUE' }

AUTHOR : Hall
FAMILY : TIME_FCT
NAME : CWD_EU
VERSION : 1.1
//Transmission to S7-1200 by Hucki

   VAR_INPUT 
      CPU_Clock : Bool;                                                                                    // Datum der CPU verwenden
      "Date" : Date;                                                                                       // Datum übergeben
   END_VAR

   VAR_OUTPUT 
      Week : Int;                                                                                          // KW (EU) des Datums
      Day : Int;                                                                                           // Tag des Jahres
   END_VAR

   VAR_TEMP 
      Date_int {OriginalPartName := 'DTL'; LibVersion := '1.0'} : DTL;                                     // zu verwendene Datum
      Date_ref {OriginalPartName := 'DTL'; LibVersion := '1.0'} : DTL;                                     // Referenz-Datum (01.01. oder 31.12.)
      Day_corr : DInt;                                                                                     // Tagesnummer für KW-Berechnung
      WD_Jan1 : Int;                                                                                       // Wochentag des 01.01.
      WD_Dez31 : Int;                                                                                      // Wochentag des 31.12.
      tValue : Int;                                                                                        // Zwischenergebnisse KW-Berechnung
   END_VAR


BEGIN
    //Für das Datum, den Eingangsparameter "Date" oder CPU_Clock nutzen. 
    IF #CPU_Clock THEN
        #"FC CWD EU" := RD_LOC_T(OUT => #Date_int);                                                         // Datum aus CPU auslesen
        IF ABS(#"FC CWD EU") > 1  THEN                                                                      // Wenn Fehler beim Auslesen 
            RETURN;                                                                                         // Baustein abbrechen
        END_IF;
        #Date_int := DATE_TO_DTL(DTL_TO_DATE(#Date_int));                                                   // Wochentag korrigieren
    ELSE
        #"FC CWD EU" := 0;
        #Date_int := DATE_TO_DTL(#Date);                                                                    // Datum vom Input übertragen
    END_IF;
    
    // 1.Januar des Jahres
    #Date_ref := #Date_int;                                                                                 // Datum übernehmen
    #Date_ref.DAY := 1;                                                                                     // Erste des Monats einstellen
    #Date_ref.MONTH := 1;                                                                                   // Januar einstellen
    #Date_ref:= DATE_TO_DTL(DTL_TO_DATE(#Date_ref));                                                        // Wochentag korrigieren
    #WD_Jan1 := #Date_ref.WEEKDAY;                                                                          // Wochentag des 01.01.
    
    // Tag des Jahres
    #Day:= DINT_TO_INT(DATE_TO_DINT(DTL_TO_DATE(#Date_int)) - DATE_TO_DINT(DTL_TO_DATE(#Date_ref)) + 1);    // Differenz bestimmen
    
    //Korrektur der Tagesnummer entsprechend dem Wochentag des 1. Januars zur KW-Ermittlung 
    CASE #WD_Jan1 OF                                                                                        // Je nach Wochentag 
        1:  // Sonntag
            #Day_corr := #Day - 2;
        2:  // Montag
            #Day_corr := #Day - 1;
        3:  // Dienstag
            #Day_corr := #Day;
        4:  // Mittwoch
            #Day_corr := #Day + 1;
        5:  // Donnerstag
            #Day_corr := #Day + 2;
        6:  // Freitag
            #Day_corr := #Day - 4;
        7:  // Samstag
            #Day_corr := #Day - 3;
    END_CASE;
    
    // Kalenderwoche
    IF #Day_corr < 0 THEN                                                                                   // Wenn KW zum Vorjahr gehört
        //Bei negativem "Day_corr", letzte KW des letzten Jahres nehmen.  
        #Date_ref.YEAR := MAX(IN1 := #Date_ref.YEAR - 1, IN2 := 0);                                         // Vorjahr einstellen
        #Date_ref := DATE_TO_DTL(DTL_TO_DATE(#Date_ref));                                                   // Wochentag korrigieren
        #WD_Jan1 := #Date_ref.WEEKDAY;                                                                      // Wochentag des 01.01.
        #Date_ref.MONTH := 12;                                                                              // Dezember einstellen
        #Date_ref.DAY := 31;                                                                                // Letzte des Monats einstellen
        #Date_ref := DATE_TO_DTL(DTL_TO_DATE(#Date_ref));                                                   // Wochentag korrigieren
        #WD_Dez31 := #Date_ref.WEEKDAY;                                                                     // Wochentag des 31.12.
        //Nur wenn der 1. Januar oder der 31. Dezember des Vorjahres ein Donnerstag war,
        //ist der aktuelle Tag in der KW53 des Vorjahres,
        //sonst ist er in der KW52 des Vorjahres
        #Week := SEL(G := #WD_Jan1 = 5 OR #WD_Dez31 = 5, IN0 := 52, IN1 := 53);                             // zw. KW52 oder KW53 entscheiden
    ELSE
        //Bei positiven "Day_corr", diesen Wert zur Berechnung der KW benutzen
        #tValue := DINT_TO_INT(#Day_corr / 7 + 1);
        IF (#tValue = 53) THEN                                                                              // Wenn KW schon im nächsten Jahr sein könnte
            //Nur wenn der 1. Januar oder der 31. Dezember des aktuellen Jahres ein Donnerstag war/ist,
            //ist der aktuelle Tag in der KW53 dieses Jahres,
            //sonst ist er in der KW1 des nächsten Jahres
            #Date_ref.MONTH := 12;                                                                          // Dezember einstellen
            #Date_ref.DAY := 31;                                                                            // Letzte des Monats einstellen
            #Date_ref := DATE_TO_DTL(DTL_TO_DATE(#Date_ref));                                               // Wochentag korrigieren
            #WD_Dez31 := #Date_ref.WEEKDAY;                                                                 // Wochentag des 31.12.
            #Week := SEL(G := #WD_Jan1 = 5 OR #WD_Dez31 = 5, IN0 := 1, IN1 := 53);                          // zw. KW1 oder KW53 entscheiden
        ELSE
            #Week := #tValue;                                                                               // KW entspricht dem berechnetem Wert
        END_IF;
    END_IF;
    
END_FUNCTION

und auch wieder als Download:
 

Anhänge

  • KW S7-1200.zip
    1,7 KB · Aufrufe: 232
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Lieber TE

Neben der eigentlichen Rechnerei noch ein paar Dinge die du beachten solltest:
1. ) Bitte kläre vorher genau wie die Kalenderwoche berechnet werden soll. Es gibt da unterschiedliche Ansätze (vgl auch hier ) dafür wann eine Woche überhaupt beginnt (So oder Mo), ob die erste KW immer die ist die den 01.01. enthält oder die erste vollständige Woche ist usw. Daraus ergeben sich auch rechnerisch Probleme dass es mal eine KW53 gibt oder auch nicht. Das ist ein sehr wichtiger Punkt da ein Mißverständnis hier immer nur einmal im Jahr zu Problemen führt und entsprechend nervig ist.
2.) Ich empfehle abzuklären ob wirklich die Kalenderwoche benötigt wird oder die Wochen des Geschäftsjahres, die sich bei Jahreswechsel auch wiederrum auf ganz ganz kuriose Weisen berechnen lassen. Wenn es um die Geschäftswochen geht würde ich unbedingt einen Buchhalter/Controller des Kunden um die Definition fragen.
3.) Wenn es um die Zuordnung von Verbauchs- Prozess- oder Chargenwerten geht ist auch noch immer ein Dauerbrenner inwieweit die Daten angefangener Produkte/Chargen noch zur letzten oder nächsten Woche zählen.
 
Hey,

vielen Dank für die Hilfe!
Ich habe den obigen SCL Code von hucki verwendet.

Leider wird mir gerade die KW20 ausgegeben. Allerdings befinden wir uns in der KW21.
Okay, also beim 23.05.2016 wird mir KW20 ausgegeben obwohl KW21 ist.
Sobald ich das Datum auf den 24.05.2016 ändere wird mir die KW 21 ausgegeben.
Ich denker da ist was verschoben.. Mir wird auch ausgegeben, dass heute Tag 143 ist. Dabei ist heute Tag 144, oder?

Was kann ich da noch machen?

Vielen vielen Dank :)
 
Zuletzt bearbeitet:
Wenn ich das Datum auf den 24.05.2016 ändere ist meine Kalenderwoche richtig.
KW =21. Es scheint so, als wäre es um ein Tag verschoben.

Danke
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn ich das Datum auf den 24.05.2016 ändere ist meine Kalenderwoche richtig.
KW =21. Es scheint so, als wäre es um ein Tag verschoben.
So, hab' mir gerade noch mal den Original-Code für die S7-300 angesehen und siehe da, da hab' ich doch glatt eine "+ 1" vergessen :oops::
Code:
    #Day:= DINT_TO_INT(DATE_TO_DINT(DTL_TO_DATE(#Date_int)) - DATE_TO_DINT(DTL_TO_DATE(#Date_ref)) [B][COLOR=#00FF00]+ 1[/COLOR][/B]);    // Differenz bestimmen

Ist mir noch gar nicht aufgefallen.
Danke!


PS: Hab' obigen Code aktualisiert.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Klappt es auch irgendwie wieder mit dem Importieren ?

Wie geht man hierzu vor ?
Im Projektverzeichnis auf der linken Seite gibt es einen Ordner "Externe Quellen" (über den PLC-Variablen).
Der erste Punkt ist "Neue externe Datei hinzufügen".
Wenn die Datei eingefügt ist, mit Rechtsklick darauf "Baustein aus Quelle generieren".
 
Hallo hucki,

ich habe mir gerade einmal deinen Baustein angeschaut. Super das du ihn mit uns geteilt hast, hierfür erst einmal ein großes Lob!!!

Mir ist allerdings ein Punkt aufgefallen.
IF #CPU_Clock THEN
#"FC CWD EU" := RD_LOC_T(OUT => #Date_int);
IF #"FC CWD EU" <> 0 THEN

In der fett markierten Zeile überprüfst du ob die Funktion "Lokalzeit lesen" korrekt gearbeitet hat oder ob es einen Fehler gab. Hierzu prüfst du auf ungleich 0. Es gibt aber auch noch folgenden "Fehlercode":
0001 - Kein Fehler. Lokalzeit wird als Sommerzeit ausgegeben.

Bei Sommerzeit wird also keine Kalenderwoche ausgegeben. Eine Möglichkeit wäre es zusätzlich auf ungleich 1 abzufragen.

IF #"FC CWD EU" <> 0 AND #"FC CWD EU" <> 1 THEN

Viele Grüße

Anubis
 
Hallo hucki,

ich habe mir gerade einmal deinen Baustein angeschaut. Super das du ihn mit uns geteilt hast, ...
Die Lorbeeren "mein Baustein" gebühren mir nicht. Ich hab' lediglich Halls Baustein auf die S7-1200 übertragen.
Deshalb habe ich auch kein Problem damit, ihn zu teilen.


Ich nehme Deinen Hinweis aber gerne mit auf.
Ich würde es dann aber etwas abwandeln:
Code:
[COLOR=#333333]IF ABS ( #"FC CWD EU") > 1 THEN[/COLOR]
Lt. Hilfe sollten zwar keine negativen Werte ausgegeben werden, aber wer weß schon, was noch so kommt?



PS: Hab's mal oben eingefügt, damit hier nicht noch mehr Varianten rumschwirren.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
TIA hat noch'ne Warnung ausgegeben, weil die Umwandlung von DINT nach INT an einer Stelle nicht explizit angegeben war. Könnt' den ein oder anderen je nach TIA-Einstellungen noch stören.

Deshalb hab' ich das oben im Post#8 auch noch korrigiert:
Code:
#tValue := [B][COLOR=#008000]DINT_TO_INT[/COLOR][/B](#Day_corr / 7 + 1);
 
Ich würde es dann aber etwas abwandeln:
Code:
[COLOR=#333333]IF ABS ( #"FC CWD EU") > 1 THEN[/COLOR]
Lt. Hilfe sollten zwar keine negativen Werte ausgegeben werden, aber wer weß schon, was noch so kommt?

Das ist auch eine Möglichkeit. Mir gings bei meinem Vorschlag wie dir, keine Ahnung ob alle Möglichkeiten in der Hilfe stehen :D
 
Zurück
Oben