ARRAY nach aktuellem Datum durchsuchen und löschen

Ossi64

Level-1
Beiträge
34
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Mitglieder,

ich habe zum ersten mal ein ARRAY erstellt in Form von einem STRUCT,

in der 10 Urlaubstermine gespeichert werden sollen.

Die Eingabe, Urlaubsanfang und Urlaubsende werden über einer VISU eingegeben

was soweit auch funktioniert.


Mein Problem:

Das ARRAY soll mit dem aktuellen Datum verglichen werden und die abgelaufene

Urlaubsangaben automatisch gelöscht werden.
Z. B. Anfang=22.12.2014 Ende=27.12.2014 sollen am 28.12.2014 gelöscht werden.

Ich habe keinen Schimmer wie ich das bewerkstelligen soll.

Der Aufbau ist folgendermaßen:

TYPE Urlaubsliste :
STRUCT
Url_Anfang:STRING(13);
Url_Ende:STRING(13);
END_STRUCT
END_TYPE

VAR
Daten:Urlaubsliste;
ST_Urlaubsliste: ARRAY [1..10] OF Urlaubsliste;
index: INT:=1;
END_VAR

Für eine Lösung wäre ich sehr Dankbar

Freundliche Grüße
Ossi64

 
Programmiert fuer Beckhoff

PROGRAM MAIN
VAR
Daten:ARRAY[0..9] OF Urlaubsliste;(*Dein Array; bitte das Datum in Format TT.MM.JJJJ eigeben*)
fbTime : FB_LocalSystemTime := ( bEnable := 1, dwCycle := 1 );(*Sehe Lib*)
logTimer : TON := ( IN :=1, PT := T#1000ms );(* 1s Clock for logging Timebase *)
Timestring:STRING(25);(*Systemtime*)
Sys_Data_Y:STRING(5);
Sys_Data_M:STRING(3);
Sys_Data_D:STRING(3);
Urlaub_Y:STRING(5);
Urlaub_M:STRING(3);
Urlaub_D:STRING(3);
i:INT;
_loeschen:BOOL;
END_VAR
##################################################
(*aktuelle Zeit besorgen*)
fbTime();
logTimer( IN := fbTime.bValid );
IF logTimer.Q THEN
logTimer( IN :=0 ); logTimer( IN := fbTime.bValid );
Timestring:=SYSTEMTIME_TO_STRING(fbTime.systemTime);(*Output local Time*)
Sys_Data_Y:=MID(STR:=Timestring,LEN:=4,POS:=1);(*Kopiere in die Variable 4 Zeichen ab Pos 1 aus dem Time String*)
Sys_Data_M:=MID(STR:=Timestring,LEN:=2,POS:=6);
Sys_Data_D:=MID(STR:=Timestring,LEN:=2,POS:=9);
END_IF;

i:=0;
WHILE i < 10 DO(*alle 10 Array Item abarbeiten in einer Schleife*)

Urlaub_Y:=MID(STR:=Daten.Url_Ende,LEN:=4,POS:=7);(*Urlaub Jahr besorgen*)
Urlaub_M:=MID(STR:=Daten.Url_Ende,LEN:=2,POS:=4);
Urlaub_D:=MID(STR:=Daten.Url_Ende,LEN:=2,POS:=1);

_loeschen:=0;(*Wenn True dann wird ein Item geloescht*)
_loeschen:=STRING_TO_INT(Sys_Data_D) > STRING_TO_INT(Urlaub_D);(*Tag pruefen, wenn groesser dann alles hinfaellig*)
_loeschen:=_loeschen OR( STRING_TO_INT(Sys_Data_M) > STRING_TO_INT(Urlaub_M));(*Monat pruefen*)
_loeschen:=_loeschen OR( STRING_TO_INT(Sys_Data_Y) > STRING_TO_INT(Urlaub_Y));(*Jahr pruefen*)
IF _loeschen THEN(*Urlaub abgelaufen*)
Daten.Url_Ende:='';(*Nullstring schreiben*)
Daten.Url_Anfang:='';
END_IF;
i:=i+1;
END_WHILE;


Lib:
TcUtilities
TcSystem
TcBase

Irek
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo ihr beiden,
das Beispiel von Irek gefiel mir, aber ich habe lange lesen müssen wegen der vielen Boolschen vergleiche...

Hatte mich gereizt, das Beispiel nach meinem Datumsdenken zu überarbeiten, voila:

Code:
PROGRAM MAIN
VAR
    Daten:ARRAY[0..9] OF Urlaubsliste ;        (*Dein Array; bitte das Datum in Format TT.MM.JJJJ eigeben*)
    fbTime : FB_LocalSystemTime := ( bEnable := 1, dwCycle := 1 );(*Sehe Lib*)
    logTimer : TON := ( IN :=1, PT := T#1000ms );(* 1s Clock for logging Timebase *)
    Timestring:STRING(25);(*Systemtime*)
    tDatum    : STRING;
    tUrlEnde    : STRING;
    i:INT := 0;
    bInit    : BOOL := TRUE;
END_VAR

IF bInit THEN
    Daten[1].Url_Anfang     := '15.06.2014';
    Daten[1].Url_Ende     := '22.06.2014';
    Daten[2].Url_Anfang     := '15.07.2014';
    Daten[2].Url_Ende     := '22.07.2014';
    Daten[3].Url_Anfang     := '31.12.2014';
    Daten[3].Url_Ende     := '07.01.2015';
    bInit := FALSE;
END_IF

fbTime();
logTimer( IN := fbTime.bValid );
IF logTimer.Q THEN
    logTimer( IN :=0 ); logTimer( IN := fbTime.bValid );
    Timestring:=SYSTEMTIME_TO_STRING(fbTime.systemTime);    (*Output local Time*)
    tDatum := MID(STR:=Timestring,LEN:=4,POS:=1);
    tDatum := CONCAT(tDatum, MID(STR:=Timestring,LEN:=2,POS:=6));
    tDatum := CONCAT(tDatum, MID(STR:=Timestring,LEN:=2,POS:=9));
END_IF;

FOR i:= 0 TO 9 DO;

    tUrlEnde := MID(STR:=Daten[i].Url_Ende,LEN:=4,POS:=7);
    tUrlEnde := CONCAT(tUrlEnde, MID(STR:=Daten[i].Url_Ende,LEN:=2,POS:=4));
    tUrlEnde := CONCAT(tUrlEnde, MID(STR:=Daten[i].Url_Ende,LEN:=2,POS:=1));

    IF tDatum > tUrlEnde THEN        (*Urlaub abgelaufen*)
        Daten[i].Url_Ende:='';        (*Nullstring schreiben*)
        Daten[i].Url_Anfang:='';
    END_IF;

END_FOR;

LG
Shrimps
 
@Shrimps Danke fuer den naechsten Beispiel. Bedenke bitte, dass in Forum auch User ohne Kenntnisse nach Hilfe suchen. Wenn jemand offen schreibt "Ich habe keinen Schimmer wie ich das bewerkstelligen soll.", dann sollte man auch paar Kommentare hinterlassen. Wenn ausser Ossi64 noch andere davon profitieren, dann denke ich haben wir guten Job abgeliefert. Irek
 
Nachtrag:

PROGRAM MAIN
VAR
Daten:ARRAY[0..9] OF Urlaubsliste;(*Dein Array; bitte das Datum in Format TT.MM.JJJJ eigeben*)
fbTime : FB_LocalSystemTime := ( bEnable := 1, dwCycle := 1 );(*Sehe Lib*)
logTimer : TON := ( IN :=1, PT := T#1000ms );(* 1s Clock for logging Timebase *)

_Systemzeit:WORD;
_Urlaubszeit_Ende:WORD;
i: INT;
END_VAR
####################################
fbTime();
_Systemzeit:=fbTime.systemTime.wDay+fbTime.systemTime.wMonth+fbTime.systemTime.wYear;(*Summe bilden*)
FOR i:=0 TO 9 BY 1 DO
(*hier genauso*)
_Urlaubszeit_Ende:=STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=4,POS:=7))+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=4))+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=1));
IF _Systemzeit > _Urlaubszeit_Ende THEN(*und vergleichen*)
Daten.Url_Anfang:='';
Daten.Url_Ende:='';
END_IF;
END_FOR;
#######################################


Irek
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Irek,
sorry, du hast vollkommen Recht.
Als "alter Hase" beim programmieren weiss ich, das Kommentare das wichtigste überhaupt sind.
Habe selber mal gelernt, das mind. 1 Zeile Kommentar pro Codezeile sein sollte...

Beim nächsten mal...

Aber es ist schön anzusehen, wie das nochmals verfeinert hast.
Das hilft mir wiederum die Datentypen von Twincat besser zu erkennen (Word aus Time).

Wobei dir und mir komplexe Zeilen nach kurzer Zeit klar sind und ich deswegen auch z. Teil Hilfsvariablen nutze...
Genau wegen diesen hätte ich ja Kommentare setzen müssen, damit es Einsteigern leichter fällt.

Prima !

Beste Grüße
Shrimps

PS: So macht mir ein Forum Spaß, es kommen lauffähige Konstrukte von Erfahrenen !
Leider habe ich auch sehr oft die Erfahrung von "Oberlehrern" gemacht, die gar keinen einzigen funktionierenden Code rausgeben und nur "verbal" auf besseres hinweisen.
 
_Systemzeit:=fbTime.systemTime.wDay+fbTime.systemTime.wMonth+fbTime.systemTime.wYear;(*Summe bilden*)
...
_Urlaubszeit_Ende:=STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=4,POS:=7))+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=4))+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=1));
...
IF _Systemzeit > _Urlaubszeit_Ende THEN(*und vergleichen*)

Hmm.. Interessante Vorgehensweise mit der Summe aber... hmm... hab ich es jetzt nicht richtig verstanden... was ist wenn:
Systemzeit: 01.07.2014 => 2022
UrlaubEnde: 31.06.2014 => 2051
 
@RONIN
mein Fehler! und Korrektur

fbTime();

FOR i:=0 TO 9 BY 1 DO
_loeschen:=0; (*sonst ist alles weg*)
_loeschen:=fbTime.systemTime.wYear > STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=4,POS:=7));(*Urlaub Jahr vergleichen*)
_loeschen:=_loeschen OR fbTime.systemTime.wMonth > STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=4));(*Urlaub Monat vergleichen*)
_loeschen:=_loeschen OR fbTime.systemTime.wDay > STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=1));(*Urlaub Tag vergleichen*)
IF _loeschen THEN(*wenn Jahr oder Monat oder Tag im System groesser als Urlaub-Ende dann *)
Daten.Url_Anfang:='';(*Nullstring schreiben*)
Daten.Url_Ende:='';
END_IF;
END_FOR;
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
leider Fehler passiert. Manchmal sind einfache Sachen ...
Ich habe das Datum einfach umgewandelt, d.h. 01.10.2015 zu einer INT Zahl 20151001.
(Wegen der Stringumwandlung muss der Tag zweistellig sein, also der erste wird mit 01 eingegeben!)
Damit ist fuer jeden Tag ein eindeutiger Wert gegen.
Wenn das auch mit dem System Zeit passiert, dann haben wir zwei eindeutige Zahlen, die zum Vergleich anstehen.
PROGRAM MAIN
VAR
Daten:ARRAY[0..9] OF Urlaubsliste;(*Dein Array; bitte das Datum in Format TT.MM.JJJJ eigeben*)
fbTime : FB_LocalSystemTime := ( bEnable := 1, dwCycle := 1 );(*Sehe Lib*)
logTimer : TON := ( IN :=1, PT := T#1000ms );(* 1s Clock for logging Timebase *)
i: INT;
_Sys_Time:DINT;
_Urlaubs_Datum:DINT;
_loeschen: BOOL;
END_VAR
############################################
fbTime();
_Sys_Time:=(fbTime.systemTime.wYear*10000)+(fbTime.systemTime.wMonth*100)+fbTime.systemTime.wDay;(*=20141230*)(*ohne Mathe nix los!!*)
FOR i:=0 TO 9 BY 1 DO
_Urlaubs_Datum:=STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=4,POS:=7))*10000;
_Urlaubs_Datum:=_Urlaubs_Datum+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=4))*100;(*Monat hinzuaddieren*)
_Urlaubs_Datum:=_Urlaubs_Datum+STRING_TO_INT(MID(STR:=Daten.Url_Ende,LEN:=2,POS:=1));(*=JJJJMMDD*)(*=20150315*)

IF _Sys_Time > _Urlaubs_Datum THEN(*jetzt nur INT vergleichen*)
Daten.Url_Anfang:='';
Daten.Url_Ende:='';
END_IF;
END_FOR;
 
Zuletzt bearbeitet:
_Sys_Time:DINT;
_Urlaubs_Datum:DINT;
_loeschen: BOOL;

Code:
_Sys_Time: DINT;
_Urlaubs_Datum: DINT;
_loeschen: BOOL;
@Irek. Wenn du hier schon einen Codehaufen nach dem anderen reinklatschst, dann bitte nimm doch die Code-Tags.
[ CODE] [ /CODE] oder das #-Symbol in der Menüleiste.
 
Zuletzt bearbeitet:
Hallo Irek,
wow das ist mehr als ich erwartet hätte.
Vielen Dank für deine Hilfe, ich werde wie ich es zum Laufen bringe.

Beste Grüße
Ossi64
 
Zurück
Oben