TIA Modulo mit TIA 15 mit VB Script

Juergena

Level-2
Beiträge
120
Reaktionspunkte
14
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich würde gerne im VB Script eine Modulo berechnung durchführen. Ich finde beim besten Willen nicht den Grund warumk er das nicht ausführt. Wenn ich das schön im Excel mache geht alles.

der Datensatz 134 ist mit 4294967295 eingegeben. Ich will lediglich die Zahl, was in Sekunden eingegeben ist umrechnen in Jahre, Tage, Minuten usw. Hier mal der Code als Anfang, vielleicht sieht ja jemand gleich den Fehler.

Code:
[FONT=Verdana]Sub Wartungsanzeige_berechnen()

[/FONT]
[FONT=Verdana]Dim Tage, Stunden, Minuten, Sekunden, ModValue_Jahre, ModValue_Tage, ModValue_Stunden, ModValue_Minuten, TestVariable 'Variablen deklarieren

[/FONT]
[FONT=Verdana]Tage=365
Stunden=24
Minuten=60
Sekunden=60

[/FONT]
[FONT=Verdana]'Wartungstimerintervall 1 berechnen
SmartTags("Wartungstimer1_Jahr")=SmartTags("DB_Datensaetze_DS134_Wartung_lesen_schreiben_Nutzdaten_Wartungstimer-Warngrenzwert_1")/Tage/Stunden/Minuten/Sekunden

[/FONT]
[FONT=Verdana]ModValue_Jahre= SmartTags("Wartungstimer1_Jahr")*Tage*Stunden*Minuten*Sekunden

[/FONT]
[FONT=Verdana]SmartTags("Wartungstimer1_Tag")=(SmartTags("DB_Datensaetze_DS134_Wartung_lesen_schreiben_Nutzdaten_Wartungstimer-Warngrenzwert_1") Mod ModValue_Jahre)
[/FONT]

[FONT=Verdana]
End Sub[/FONT]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich finde beim besten Willen nicht den Grund warumk er das nicht ausführt.
Was meinst Du mit "nicht ausführt"?
  • Wird das Skript nicht ausgeführt?
    Wann soll es ausgeführt werden? Bei Wertänderung der Variable "DB_Datensaetze_DS134...Warngrenzwert_1"? Wird die Variable "DB_Datensaetze_DS134...Warngrenzwert_1" verwendet oder ist die Erfassungsart "Zyklisch fortlaufend"?
  • Bricht das Skript irgendwo ab und liefert keine Ergebnisse?
    Hast Du eine Meldeanzeige (x)Meldepuffer für Meldungen der Klasse System? Dann kannst Du Skript-Abbrüche wegen Runtime-Errors sehen.
  • Rechnet das Skript falsch oder kommt ein unerwartetes Ergebnis?
    Welchen Datentyp hat Deine Variable "Wartungstimer1_Jahr"?
    Siehe nachfolgend Deinen VBS-Code ein bisschen verübersichtlicht - ist das das was Du rechnen wolltest? :
Code:
Sub Wartungsanzeige_berechnen()

Const Tage=365, Stunden=24, Minuten=60, Sekunden=60
Dim SekundenProJahr, DS134_Warngrenzwert_1, ModValue_Jahre, ModValue_Tage, ModValue_Stunden, ModValue_Minuten, TestVariable [COLOR="#008000"]'Variablen deklarieren[/COLOR]

SekundenProJahr = Tage * Stunden * Minuten * Sekunden

[COLOR="#008000"]'Wartungstimerintervall 1 berechnen[/COLOR]
DS134_Warngrenzwert_1 = SmartTags("DB_Datensaetze_DS134_Wartung_lesen_schreiben_Nutzdaten_Wartungstimer-Warngrenzwert_1")

SmartTags("Wartungstimer1_Jahr") = DS134_Warngrenzwert_1 / SekundenProJahr

ModValue_Jahre = SmartTags("Wartungstimer1_Jahr") * SekundenProJahr         [COLOR="#008000"]'oder: [COLOR="#0000FF"][B]Int([/B][/COLOR]SmartTags("Wartungstimer1_Jahr")[COLOR="#0000FF"][B])[/B][/COLOR] * SekundenProJahr[/COLOR]

SmartTags("Wartungstimer1_Tag") = DS134_Warngrenzwert_1 Mod ModValue_Jahre


[COLOR="#008000"]'oder etwas kürzer:
' DS134_Warngrenzwert_1 = SmartTags("DB_Datensaetze_DS134_Wartung_lesen_schreiben_Nutzdaten_Wartungstimer-Warngrenzwert_1")
' SmartTags("Wartungstimer1_Jahr") = DS134_Warngrenzwert_1 / SekundenProJahr
' SmartTags("Wartungstimer1_Tag") = DS134_Warngrenzwert_1 Mod (SmartTags("Wartungstimer1_Jahr") * SekundenProJahr)[/COLOR]

End Sub

Harald
 
Genau 136 Jahre z.b.

Mit nicht ausgeführt meine ich das mein Ergebnis in meinem Aufgabenfeld 0 ist. Ich hab die Variablen schon von real über int über dint usw. umgemacht. Nichts half. Fehlermeldung gleich 0. Wenn ich ab den Mod Operator auskommentiere dann zeigt mein Feld was an. Ich habe mir schon den Wolf im Internet und hier bei der Suche gemacht, weil ich zuerst dachte die Syntax stimmt nicht, aber fand keine Lösung.

Gesendet von meinem SM-G975F mit Tapatalk
 
Fehlermeldung gleich 0. Wenn ich ab den Mod Operator auskommentiere dann zeigt mein Feld was an.
Dein Skript wird abgebrochen mit Runtime-Error "Fehler 'Überlauf: '...DS134...Warngrenzwert_1''" bei Mod, weil Mod geht in VBS nur bis 2.147.483.647 (&H7FFFFFFF). Bei größeren Zahlen konvertiert VBS automatisch zu Fließkommazahl und da geht Mod nicht.
Weiteres Problem: wenn Deine Variable "DB_Datensaetze_DS134...Warngrenzwert_1" kleiner als 1 Jahr (31.536.000 = SekundenProJahr) ist, dann wird "Wartungstimer1_Jahr" und ModValue_Jahre = 0 und Du bekommst bei Mod eine 'Division durch Null'

Mache Dir die empfohlene Meldeanzeige in ein Bild und Du wirst über die Runtime-Erros informiert :cool:
  • Bricht das Skript irgendwo ab und liefert keine Ergebnisse?
    Hast Du eine Meldeanzeige (x)Meldepuffer für Meldungen der Klasse System? Dann kannst Du Skript-Abbrüche wegen Runtime-Errors sehen.


PS:
Ich hab die Variablen schon von real über int über dint usw. umgemacht. Nichts half.
"Wartungstimer1_Jahr" muss UDINT oder DINT sein, damit die ganze Rechnung Sinn macht. (Was machst Du mit der Variable?)
"Wartungstimer1_Tag" sollte sinnvollerweise ebenfalls ein Ganzzahl-Datentyp sein.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,

danke für die Erklärung, aber nun steh ich immer noch vor meinem Problem. Die Variable DS134 bekomme ich von meinem Motorstarter ausgelesen leider in (2^32)-1 und wird in Sekunden angezeigt. Damit ich aber den Jungs in der Instandhaltung das Umrechnen sparen will, möchte ich 4 Ausgabefelder unten dran setzen, in der sofort eine Umrechnung in Jahre, Tage, Stunden, Minuten angezeigt wird. Oder gibt´s eine einfachere Lösung und ich denk nur wieder zu kompliziert?

Jürgen
 
Die Variable DS134 bekomme ich von meinem Motorstarter ausgelesen leider in (2^32)-1 und wird in Sekunden angezeigt.
Bekommst Du die zuerst an eine SPS? Welche SPS?
Mach doch die Umrechnung bzw. Formatierung als Zeit-Format in der SPS. Da gibt es vielleicht schon was fertiges.
Du meinst, die Zeit kommt als UDINT 0 bis 4.294.967.295 Sekunden?

Harald
 
Ja ich lese den Datensatz zuerst in einen DB als dword ein. Es ist eine S7-317F. Ok, dann muss ich wohl dort gleich eine Konvertierung vornehmen. Ich schau mal.

Gesendet von meinem SM-G975F mit Tapatalk
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja ich lese den Datensatz zuerst in einen DB als dword ein. Es ist eine S7-317F. Ok, dann muss ich wohl dort gleich eine Konvertierung vornehmen. Ich schau mal.

Gesendet von meinem SM-G975F mit Tapatalk

Mach das gleich in der SPS, wenn die Variable ohnehin dort liegt.
 
Also wie ich das grade sehe gibt es nur einen Baustein von Millisekunden in time. Oder kennt einer von Sekunden in jahre und time? Ansonsten würde ich halt her gehen und zuerst die jahre berechnen und den rest mit 1000 multiplizieren und dann über den baustein Millisekunden in time drüber schieben.

Gesendet von meinem SM-G975F mit Tapatalk
 
Zuletzt bearbeitet:
Also kurzer Zwischenstand: Es geht nun über die SPS. Ich habe es so gemacht wie ich oben geschrieben habe. Zuerst die Jahre berechnet und den Rest dann auf den Baustein Millisecond_to_time gegeben. Dabei aber die Division durch 0 abgefangen bei den Jahren. Dabei habe ich aber festgestellt, wenn die Uhrzeit eigentlich bei Sekunden 0 anzeigen und eigentlich die Minuten um 1 erhöhen sollte, wurden stattdessen bei Sekunden 60 angezeigt und die Minute wurde bei 0 belassen. Was ja eigentlich nicht richtig wäre, ich bin dann her gegangen und habe die Schleife bei der Minutenberechnung im SCL Baustein von Siemens statt >60000 auf >59000 gesetzt und nun macht er alles wie es sein soll. Also, falls wer diesen Baustein benutzt, dann besteht dieser Fehler.

Danke an Euch beiden @PN/DP und @Ralle für die richtige Richtung.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... ich bin dann her gegangen und habe die Schleife bei der Minutenberechnung im SCL Baustein von Siemens statt >60000 auf >59000 gesetzt und nun macht er alles wie es sein soll. Also, falls wer diesen Baustein benutzt, dann besteht dieser Fehler.
>=60000 bzw. >59999 dürfte i.A. vermutlich besser passen. In Deiner Anwendung sind die ms durch die Multiplikation mit 1000 immer 000 ... da fällt der Fehler besonders auf. :ROFLMAO:
 
Also wie ich das grade sehe gibt es nur einen Baustein von Millisekunden in time. Oder kennt einer von Sekunden in jahre und time?
den Rest dann auf den Baustein Millisecond_to_time gegeben. (...) Dabei habe ich aber festgestellt, wenn die Uhrzeit eigentlich bei Sekunden 0 anzeigen und eigentlich die Minuten um 1 erhöhen sollte, wurden stattdessen bei Sekunden 60 angezeigt und die Minute wurde bei 0 belassen.
Wo hast Du den Baustein Millisecond_to_time von Siemens gefunden?

Hier ein Baustein in AWL (Step7 classic):
Code:
FUNCTION "Seconds2Struct" : VOID
TITLE =UDINT Sekunden in Time-Struktur zerlegen
AUTHOR : 'PN/DP'
VERSION : 0.1

VAR_INPUT
  udSeconds : DINT ; //UDINT
END_VAR
VAR_OUTPUT
  TS : STRUCT        //Zeitstruktur
   Years : INT ;     //0..136
   Days : INT ;      //0..364
   Hours : BYTE ;    //0..23
   Minutes : BYTE ;  //0..59
   Seconds : BYTE ;  //0..59
   Reserve : BYTE ;
  END_STRUCT ;
END_VAR
VAR_TEMP
  tmpWork : DINT ;
END_VAR
BEGIN
NETWORK
TITLE =
//max 4.294.967.295 Sekunden = 136Y:70D:6H:28M:15S
//SekundenProJahr = 365 * 24 * 60 * 60 = 31.536.000
      L     #udSeconds;      // UDINT !
      SRD   1;               // UDINT/2, Bit0 --> A1
      U     >0 ;             // A1 in VKE merken
      T     #tmpWork;        // #udSeconds/2 merken
      L     L#15768000;      // SekundenProJahr/2 = 365 * 24 * 60 * 60 / 2
      /D    ;
      T     #TS.Years;       // 0..136

      L     #tmpWork;        // #udSeconds/2
      L     L#15768000;      // SekundenProJahr/2
      MOD   ;                // RestSekunden/2
      SLD   1;               // UDINT * 2
      SPBN  MTS;             // Bit0(A1) war 0?
      +     L#1;             // Bit0(A1) war 1: 1 Sekunde dazu
MTS:  T     #tmpWork;        // RestSekunden (max 31.536.000-1)
      L     60;              // SekundenProMinute
      MOD   ;
      T     #TS.Seconds;     // 0..59

      L     #tmpWork;        // RestSekunden
      L     60;              // SekundenProMinute
      /D    ;                // RestMinuten
      L     60;              // MinutenProStunde
      MOD   ;
      T     #TS.Minutes;     // 0..59

      L     #tmpWork;        // RestSekunden
      L     3600;            // SekundenProStunde (60 * 60)
      /D    ;                // RestStunden (max 8760-1)
      L     24;              // StundenProTag
      /I    ;
      T     #TS.Days;        // 0..364
      SRD   16;              // Divisionsrest AKKU1-H --> AKKU1-L
      T     #TS.Hours;       // 0..23

END_FUNCTION
Harald
 
Zuletzt bearbeitet:
Den Baustein habe ich hier bei Siemens gefunden: [FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]https://support.industry.siemens.com/cs/document/42637538/wie-können-sie-in-step-7-(tia-portal)-die-anzahl-der-millisekunden-in-tage-stunden-minuten-und-sekunden-umwandeln-?dti=0&lc=de-WW

Harald, dein Baustein sieht aber auch nicht schlecht aus.
[/FONT]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sodele, Harald herzlichen Dank für deinen input. Ich bin nun her gegangen und hab mir den Siemens Baustein umgeschrieben für meine genauen Bedürfnisse. Ich hab auch den Input auf Sekunden gemünzt statt Millisekunden. Falls jemand den Baustein auch braucht kann sich gerne melden dann stell ich ihn gerne zur Verfügung.

Danke an alle bisher

Gruß Jürgen

Gesendet von meinem SM-G975F mit Tapatalk
 
Hallo Harald,

ich habe mal die volle Bandbreite bei mir direkt am Motorstarter eingegeben und Online alles berechnen lassen und ich bekam nirgends eine Fehlermeldung und die Berechnung lief richtig durch. Ich habe auch zwischendrin sporadisch getestet und bekam das richtige Ergebnis.

anbei der Baustein:

Code:
FUNCTION_BLOCK "SecToTime"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      dwSeconds : DWord;
   END_VAR


   VAR_OUTPUT 
      years : DInt;
      days : DInt;
      hours : DInt;
      minutes : DInt;
      seconds : DInt;
   END_VAR


   VAR 
      statValue : DInt;
   END_VAR


   VAR_TEMP 
      tempSec : DInt;
   END_VAR




BEGIN
    //Dieses Programm enthält einen Zeitwandler, der einen Sekundenwert in Jahre, Tage, Stunden, Minuten und Sekunden umwandelt.    
    //This program consists a time converter, that converts a value of seconds into years, days, hours, minutes and seconds.
    //
    //Der Eingabewert (in Sekunden) wird in die statische Variable statValue übertragen.
    //The input value (in seconds) will transfer in the static variable statValue.
    #statValue := DWORD_TO_DINT(#dwSeconds);
    
    //Initialisierung / Initialization
    #years := 0;
    #days := 0;
    #hours := 0;
    #minutes := 0;
    #seconds := 0;
    
    //Berechne die Jahre, 1 Jahr = 31536000s
    //Subtrahiere solange einen Tag, bis der Wert < 31536000s.
    //Inkrementiere jeweils die Anzahl der Jahre um 1.
    //Calculate the Years, 1 Year  = 31536000s.
    //Subtrac one year while the value < 31536000s.
    //Increment the number of days with 1.
    WHILE #statValue >= 31536000 DO
        #statValue := #statValue - 31536000;
        #years := #years + 1;
    END_WHILE;
    
    //Berechne die Tage, 1 Tag = 86400s
    //Subtrahiere solange einen Tag, bis der Wert < 86400s.
    //Inkrementiere jeweils die Anzahl der Tage um 1.
    //Calculate the days, 1 day  = 86400s.
    //Subtrac one day while the value < 86400s.
    //Increment the number of days with 1.
    WHILE #statValue >= 86400 DO
        #statValue := #statValue - 86400;
        #days := #days + 1;
    END_WHILE;
    
    //Berechne die Stunden, 1 Stunde = 3600s.
    //Subtrahiere solange eine Stunde, bis der Wert < 3600s.
    //Inkrementiere jeweils die Anzahl der Stunden um 1.
    //Calculate the hours, 1 hour  = 3600s.
    //Subtrac one hour while the value < 3600s.
    //Increment the number of hours with 1.
    WHILE #statValue >= 3600 DO
        #statValue := #statValue - 3600;
        #hours := #hours + 1;
    END_WHILE;
    
    //Berechne die Minuten, 1 Minute = 60s.
    //Subtrahiere solange eine Minute, bis der Wert < 60s.
    //Inkrementiere jeweils die Anzahl der Minuten um 1.
    //Calculate the minutes, 1 minute  = 60s.
    //Subtrac one minute while the value < 60s.
    //Increment the number of minutes with 1.
    WHILE #statValue >= 60 DO
        #statValue := #statValue - 60;
        #minutes := #minutes + 1;
    END_WHILE;
    
    //Berechne die Sekunden, 1 Sekunde = 1s.
    //Subtrahiere solange eine Sekunde, bis der Wert < 1s.
    //Inkrementiere jeweils die Anzahl der Sekunden um 1.
    //Calculate the seconds, 1 second  = 1s.
    //Subtrac one second while the value < 1s.
    //Increment the number of second with 1.
    WHILE #statValue > 0 DO
        #statValue := #statValue - 1;
        #seconds := #seconds + 1;
    END_WHILE;
    
    //Speichere Sekunden / Save the seconds
    #tempSec := #statValue;
END_FUNCTION_BLOCK

Gruß

Jürgen
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
OMG, zu dem Baustein-Code fällt mir nur ein:
War das bei Siemens ein Praktikant, der noch nie was von Division und MOD gehört hat? Wie kann man nur auf die Idee kommen, in schlimmstenfalls hunderten oder tausenden Schleifendurchläufen per stupider Subtraktionen die Sekunden zu zerlegen? :roll: Das ist ja fast wie im Kindergarten: 3 Kinder mit 6 Händen und mindestens 27 Fingern (*) zählen bis 1000 ;)
Wieso hat der Programmierer den Code in einen FUNCTION_BLOCK gepackt anstatt in eine FUNCTION?
(Und anscheinend sind in dem original-Code wohl auch noch Fehler drin, die durch nicht ausreichend Testen noch gar nicht aufgefallen sind?)
Naja, wenigstens ist der Scheixx sehr schön zweisprachig kommentiert... ;)

Harald


(*) PS: es reicht auch 1 Kind mit 10 Fingern, doch das ist für ein Kindergartenkind noch zu schwer :cool:
 
Zuletzt bearbeitet:
[emoji1787][emoji1787][emoji1787] Ich habe ihn zumindest mal soweit umgebaut das es mal das Jahr mit ausspuckt und zumindest die Fehler draußen sind mit 60sek und 0 Minuten usw. Oberhalb war es das gleiche Problem mit stunden und tagen.

Gesendet von meinem SM-G975F mit Tapatalk
 
Zurück
Oben