# Format Date and Time einer KW zuordnen



## skyvan (8 Dezember 2009)

Hallo an alle

ich habe in einem DB 1000 Realwerte gespeichert in einem 2ten DB 1000 Datensätze mit dem Zeitstempel wann die dazugehörigen Realwerte abgespeichert wurden. Jetzt komm ich zu meinem Problem ich möchte die KW auswählen können und die Daten plus Zeitstempel angezeigt bekommen die in der jeweiligen KW gespeichert wurden. Ich hoffe ihr hab eine Idee wie man es lösen kann.

Gruß und besten Dank Marco


----------



## Ralle (8 Dezember 2009)

Was genau ist dein Problem, die Berechnung der KW? dazu gibt es bei Wikipedia Artikel. Wenn ich recht erinnere, hat auch die Oscat-Library dazu etwas zu bieten.


----------



## marlob (8 Dezember 2009)

Ralle schrieb:


> Was genau ist dein Problem, die Berechnung der KW? dazu gibt es bei Wikipedia Artikel. Wenn ich recht erinnere, hat auch die Oscat-Library dazu etwas zu bieten.


Ich glaube er will die KW angeben und will dann das Anfangsdatum und Endedatum dieser KW erhalten.
Der Baustein in der Oscat-Bibliothek macht es genau andersherum


----------



## skyvan (8 Dezember 2009)

nein das ist nicht mein Problem, sondern eher ich möchte über ein OP Listenfeld (1-53) auswählen können was angezeigt wird. Das heisß ich muß erst alle Zeitwerte im DB nach dem passenden durchsuchen, markieren und dann anzeigen + Realwerte aus dem 1ten DB

Gruß MArco

Edit: Marlob hat es fast genau auf den Punkt gebracht, nur will ich alle Datenwerte aus dem 1ten DB die z.B. aus KW 3 sind angezeigt bekommen

unsere Messwerte erstrecken sich bis zu einem Jahr.


----------



## marlob (8 Dezember 2009)

Kann dein OP Scripte?
Dann könntest du etwas in VB programmieren
Hier mal ein Beispiel in Visual Basic
Evtl. musst du das noch anpassen
http://www.aboutvb.de/khw/artikel/khwweekdayinweek.htm

Oder mal nach "Datum aus Kalenderwoche berechnen" googlen.
Da finden sich einige Codebeispiele


----------



## skyvan (8 Dezember 2009)

nein leider, habe nur ein normales OP177B wird auch kein anderes eingebaut werden. 

Gruß Marco


----------



## Ralle (8 Dezember 2009)

Ich würde dann vielleicht aus der angewählten KW das Anfangs- und das Enddatum errechnen und den DB nach den Werten durchsuchen. Die gefundenen Werte in einen "Anzeige-DB" kopieren (macht alles die SPS), dessen Variablen auf dem OP dargestellt werden.


----------



## marlob (8 Dezember 2009)

skyvan schrieb:


> nein leider, habe nur ein normales OP177B wird auch kein anderes eingebaut werden.
> 
> Gruß Marco


das von mir genannte Script sollte sich aber auch nach SCL oder notwalls AWL konvertieren lassen. Einfach mal probieren


----------



## skyvan (8 Dezember 2009)

hi marlob

normalerweise probiere ich allein mein Zeug nur bin ich im Moment ein wenig unter Zeitdruck. HAst du evtl ein Link für mich oder besser noch einen Lösungsansatz.

Ich möchte keine komplette Lösung von Dir/Euch

Gruß und Danke Marco


----------



## Larry Laffer (9 Dezember 2009)

Hallo,
ich hatte mir dafür mal eine SCL-Routine erstellt - vielleicht habe ich die hier sogar schon mal gepostet ...
Wenn du damit etwas anfangen kannst - der FC zerlegt dir ein Datum in seine Bestandteile :
	
	



```
FUNCTION FC431 : VOID            
Title   = 'UP Date nach TTMMJJ umwandeln'  
AUTHOR  : 'Larry'
VERSION : '1.1'     
 
VAR_INPUT 
   IN_Date : DATE ;                 // Datum für Umwandlung 
      w_Date AT IN_Date : WORD ; 
END_VAR
VAR_IN_OUT 
END_VAR
VAR_OUTPUT
   Jahr              : INT ;       // Jahr des Vorgabe-Date's
   Monat             : INT ;       // Monat des Vorgabe-Date's
   Tag               : INT ;       // Tag des Vorgabe-Date's
   Wochentag         : INT ;       // Wochentag des Vorgabe-Date's  [1=So - 7=Sa]
   Schaltjahr        : INT ;       // Schaltjahr des Vorgabe-Date's
   Jahrestag         : INT ;       // Tag im Jahr des Vorgabe-Date's
   Kalenderwoche     : INT ;       // Kalenderwoche des Vorgabe-Date's
END_VAR
VAR_TEMP
   c_Date : DINT ; 
   Anz_SJ : INT ; 
   Diff_J : INT ;
   JTag   : INT ;
END_VAR
 
BEGIN
   c_Date := 1 + WORD_TO_DINT(w_Date) ;
   Diff_J := DINT_TO_INT(c_Date / 366) ;
   Jahr := Diff_J + 1990 ;
   Schaltjahr := 0 ; IF (Jahr MOD 4) = 0 THEN Schaltjahr := 1 ; END_IF ;
   
   Anz_SJ := (Diff_J + 2) / 4 ;
   Jahrestag := Schaltjahr - Anz_SJ + DINT_TO_INT(c_Date - (INT_TO_DINT(Diff_J) * 365)) ;
   Wochentag := DINT_TO_INT(c_date MOD 7) + 1 ;
   Kalenderwoche := (Jahrestag + 7 + 3 - Wochentag) / 7 ;
  
   JTag := Jahrestag ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 1 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= (28 + Schaltjahr)) THEN 
      Monat := 2 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 28 - Schaltjahr ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 3 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= 30) THEN 
      Monat := 4 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 30 ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 5 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= 30) THEN 
      Monat := 6 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 30 ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 7 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 8 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= 30) THEN 
      Monat := 9 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 30 ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 10 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 31 ;
   IF (JTag > 0) AND (JTag <= 30) THEN 
      Monat := 11 ; Tag := JTag ;
   END_IF ; 
   JTag := JTag - 30 ;
   IF (JTag > 0) AND (JTag <= 31) THEN 
      Monat := 12 ; Tag := JTag ;
   END_IF ; 
  
END_FUNCTION
```
Nachsatz:
Auf Anregung von Ingeborg, die da in dem Script noch einen Bug (!!!) entdeckt hat, habe ich das Ganze noch einmal überarbeitet.
Es arbeitet nun bis zum 31.12.2099 (nach menschlichem Ermessen) fehlerfrei. Danach nicht mehr, da Siemens ab 2099 mit dem DATE-Format einen Fehler macht.


----------



## skyvan (9 Dezember 2009)

@Larry Laffer

dank dir das hilf schon einmal weiter. Wenn ich fragen haben sollte meld ich mich noch einmal.

Danke und Gruß Marco


----------



## skyvan (10 Dezember 2009)

*DB nach KW Durchsuchen*

Hallo nochmal

so jetzt hab ich alles, nur ist jetzt das nächste Problem aufgetreten.
Mein DB sieht folgendermaßen aus (1 Datensatz)
DBW0    Kalenderwoche
DBD2     Rate-Wert
DBW6    Jahr
DBW8    Monat
DBW10  Tag

das ganze sind 500 Datensätze

jetzt muß ich wenn ich nur die Daten der KW 49 haben möchte den ganzen DB nach der passenden KW durchsuchen und den passenden Satz in einen anderen transferieren ( es können x Datensätze der selben KW auftauchen).

Vielen Dank für eure Unterstützung

Gruß Marco


----------



## Larry Laffer (10 Dezember 2009)

skyvan schrieb:


> ... so jetzt hab ich alles, nur ist jetzt das nächste Problem aufgetreten.


 
Hallo Marco,
welches Problem ist denn aufgetreten ? Es liest sich doch alles erstmal gut ...

Gruß
LL


----------



## skyvan (10 Dezember 2009)

@Larry Laffer

ja ich hab das jetzt hinbekommen das alles soweit passt (reihenfolge, bei trigger neues Datenfach usw.) ich hab aber das Problem das nicht alle Datensätze angezeigt werden können (macht kein sinn für mich da es sich um 500 Sätze handelt a 12Byte). Ich möchte nunmehr eine Auswahl treffen (Kalenderwoche) die mein DB durchsucht und zutreffende in ein Anzeige DB speichert (gesamten Block 12 Byte / x Blöcke) und genau da liegt jetzt mein Problem ich bekomme es einfach nicht hin. Ich verrenne mich immer ab der selben stelle den ersten gefundenen Datensatz speichert er ab und der wird mit dem nächsten wieder überscchrieben. 

da ich nicht wirklich ein ansatz habe, 


> AUF #Wertespeicher // DB öffnen
> L #Datenanfang
> T #Suchwert
> L 0
> ...


 

please Help 

Gruß Marco


----------



## Ralle (10 Dezember 2009)

Das ist nicht der komplette Code oder?
Wo machst du den Transfer in den "Anzeige"-DB?


----------



## skyvan (10 Dezember 2009)

Hi Ralle

genau da ist ja mein Problem da ich die 12 Byte (wenn Übereinstimmung der KW) in den Anzeige DB schieben möchte (das können bis zu 30 Blöcke sein pro KW). Ich häng da mir fehlt irgendwie wie ich den Zeiger schreibe :-(

Gruß Marco


----------



## Larry Laffer (10 Dezember 2009)

Also ...
du brauchst hier 2 Pointer :
einen auf die Quell-Einlese-Adresse und einen auf die nächste Ziel-Schreib-Adresse. Beide Pointer musst du natürlich, wenn du eine Übereinstimmung gefunden hast, um 12 erhöhen (wegen Datenblock-Breite = 12 Byte), aber sie zeigen ja auf vollkommen unterschiedliche Datenbereiche.

Ich würde so vorgehen :
Die Quell-Liste durchsuchen bis zur ersten Übereinstimmung, diese dann in den Lokal-Datenbereich des Bausteins übertragen und den Lese-Pointer erhöhen. Dann den Lokal-Datenbereich auf den Ziel-Pointer übertragen und den erhöhen. Und so weiter ...
Hilfreich ist es auf jeden Fall, die Anzahl der schon durchsuchten Datensätze und die der gefundenen Datensätze irgendwo mitzuschreiben.

Bekommst du die Routine dafür nun hin ?

Gruß
LL


----------



## skyvan (10 Dezember 2009)

Hallo Larry Laffer

ich werd es mal probieren (wär cool wenn du morgen nochmal reinschaust).

von aussen werd ich wohl die max Anzahl der Blöcke vorgeben die sich in dem DB befinden können als loop. 

Auf jedenfall bin ich dankbar für eure Unterstützung (brauch manchmal ein schupps in die richtige Richtung ).

Danke euch


----------



## Larry Laffer (10 Dezember 2009)

skyvan schrieb:


> wär cool wenn du morgen nochmal reinschaust


kein Problem ...


----------



## Ralle (10 Dezember 2009)

Hm, 30*12 Byte, das würde ich nicht unbedingt auf den Lokalstack packen, sondern schon in einen 2. DB, in welchem die Ergebnisse landen. Oder hab ich dich falsch verstanden Larry?


----------



## Larry Laffer (10 Dezember 2009)

@Ralle:
hast du ...
Ich wollte nur das eine jeweils gefundene auf den L-Stack packen, damit er beim Kopieren nicht dir Register verwurschteln muss.
Also :
gefundener_Eintrag -> Lokal -> Ziel-Speicher
weiter mit Schleife ...

Gruß
LL


----------



## skyvan (11 Dezember 2009)

hallo

ich komm hier jetzt nicht mehr weiter. Habt ihr ein Tip wie 12Byte zu übertragen sind am Stück. Ich muß mir eingestehen das es alles eine Ewigkeit her ist.


```
UN    #Start
      SPB   ende
      CLR   
      =     #HM_Clear
      L     0
      T     #index
loop: NOP   0
      SLD   3
      LAR1  
      AUF   #Wertespeicher
      L     DBW [AR1,P#0.0]
      L     #Suchwert                   // Bsp 50 für KW 50
      ==I   
      SPB   weit
// lade 12Byte aus wertspeicher
// transferiere in Lokal
 
weit: L     12
      L     #index
      +I    
      T     #index                      //index erhöhen
// lade lokale 12 Byte
// transferiere 12 Byte in Anzeige
// addiere 12byte zum Pointer Anzeige DB
      L     #index
      L     11988                       //letztes dbw
      >=I   
      SPB   exit
      TAK                               //neuen index zurückholen
      SPA   loop
end:  NOP   0
      L     #index                      //gefunden in dbw x
      T     #index
ende: NOP   0
```
 
Gruß Marco


----------



## Ralle (11 Dezember 2009)

12 Byte kann man mit 3 DBD übertragen, da brauchst du nicht einmal eine Schleife! Eine Möglichkeit wäre auch der Baustein Blockmove, aber das ist hier nicht unbedingt nötig.

Du lädst die erste Adresse (Start) der 12 Byte in das AR1

Dann kannst du mittels 

L DBD[AR1, P#0.0]
T ...
L DBD[AR1, P#4.0]
T ...
L DBD[AR1, P#8.0]
T ...

die 12 Byte abgreifen.

Umgekehrt geht das natürlich dann genauso, also von lokal laden und über AR1 und die Offsets (P#0.0, P#4.0. P#8.0) die Daten transferrieren. Alternativ ginge natürlich auch 12x 1 Byte mit jeweils Offset um 1.0 erhöhen , aber das ist vom Code her länger.


----------



## skyvan (11 Dezember 2009)

gut wenn ich es aber variabel benötige würde sich doch eine Schleife in der Schleife anbieten oder? in der Schleife würde ich dann jeweils um 1 hoch zählen

Gruß Marco


----------



## Larry Laffer (11 Dezember 2009)

klar ... aber das macht es von der Erstellung her nicht eben leichter.
Wie wäre es denn, diese Aufgabe mittels SCL zu programmieren ? Das wäre dann deutlich einfacher zu handeln und auch wesentlich flexibler in der Handhabung ...

Gruß
LL


----------



## skyvan (11 Dezember 2009)

ha wie geil du bietest dich an . Hab mit SCL noch nicht allzuviel gemacht. 

Jetzt mal im ernst könntest du es machen?

Gruß Marco


----------



## Larry Laffer (11 Dezember 2009)

ich werde es dir nicht machen, aber wenn du grundsätzlich mit SCL klarkommst, dann kann ich dir schon dabei helfen, das auf dem Wege zu erstellen ... Reicht das auch ?


----------



## skyvan (11 Dezember 2009)

danke dir für das Angebot. Nur wie schon geschrieben, gehen meine Kenntnisse SCL betreffend eher gegen 5% und das reicht einfach nicht um (denke ich zumindest) um das zu realisieren. Ich hab zwar Berger´s KompendiumStep 7 in AWL und SCL hier aber so irre Beispiele sind dan nicht drin. Hab halt null Plan wie ich da anfangen soll.

So wie sich das anhört ist ja SCL wesentlich flexibler als AWL und Co. Sind Schulungen für SCL zu empfehlen oder ist das rausgeschmissenes Geld. HAb mal angefangen was ich benötige, wenn du mir beim Aufbau nochmal helfen könnest?


```
FUNCTION FC1 : VOID            
Title   = 'DB durchsuchen und gefundene Werte verschieben'  
AUTHOR  : 'Marco'
VERSION : '1.0'     
 
VAR_INPUT 
   Start_suchen:  BOOL;              // löst das suchen aus
   suche_KW :     INT ;              // Kalenderwoche 
   Quell_DB :     INT ;              // in dem DB wird gesucht
   Ziel_DB:       INT;               // in den DB wird geschrieben
   länge_Block :  INT;               // wird in Byte angegeben
   Anzahl_Blöcke: INT;               // Anzahl der zu durchsuchenden Blöcke
 
END_VAR
 
VAR_OUTPUT
Kalenderwoche: INT;                 // Kalenderwoche
FTT_Rate:      REAL;                // FTT Rate 
Tag:           INT;                 // Tag
Monat:         INT;                 // Monat
Jahr:          INT;                 // Jahr
END_VAR
 
VAR_TEMP
   Temp_1 : INT ; 
   Temp_2 : INT ;
 
END_VAR
 
//     Anweisungsteil
BEGIN
   END_IF ;
```
 
Gruß Marco


----------



## Larry Laffer (11 Dezember 2009)

Also denn ...
	
	



```
bei VAR_INPUT ändern :
   Quell_DB :     BLOCK_DB ;              // in dem DB wird gesucht
   Ziel_DB:       BLOCK_DB ;               // in den DB wird geschrieben
   
bei VAR_OUTPUT ergänzen :
   Anzahl_gefunden : int ;
 
bei VAR_IN_OUT ergänzen :
   Suche_beendet  : bool ; 
   
bei VAR_TEMP ergänzen :
   i , j , qptr , zptr , qw : INT ;
 
dann im Code-Teil :
 
if Start_suchen and not Suche_beendet  then 
 
Anzahl_gefunden := 0 ;
for i:= 1 to Anzahl_Bloecke by 1 do
   qptr := (i-1) * laenge_Block +1 ;
   qw := word_to_int(Quell_DB.DW[qptr]) ;
   if (qw = suche_KW) then 
      Anzahl_gefunden := Anzahl_gefunden + 1 ;
      zptr := (Anzahl_gefunden -1) * laenge_Block ;
      for j:= 1 to laenge_Block by 1 do
         Ziel_DB.DB[zptr+j-1] := Quell_DB.DB[qptr+j-1] ;
      end_for ;
   end_if ;
end_for ;
 
end_if ;
Suche_beendet  := Start_suchen ;
```
... das habe ich jetzt mal so Quick`n`dirty dahingeschrieben ...
Teste das mal und bau vielleicht auch mal ein bißchen daran rum ...

Gruß
LL


----------



## skyvan (11 Dezember 2009)

ja da seh ich wieder das ich immernoch lerne und das nach etlichen Jahren. Ich danke dir auf jeden Fall schon einmal werde es am WE mal testen.

Bin für Beispiele (die müssen nix mit dem Thema zu tun haben) offen so kann ich mir die Struktur näher bringen.

Danke 

Gruß Marco


----------



## Kai (11 Dezember 2009)

skyvan schrieb:


> ich habe in einem DB 1000 Realwerte gespeichert in einem 2ten DB 1000 Datensätze mit dem Zeitstempel wann die dazugehörigen Realwerte abgespeichert wurden.


 
In welchem Datenformat wird der Zeitstempel gespeichert?

Wird der Zeitstempel im Datenformat DATE oder DATE_AND_TIME gespeichert?

Gruß Kai


----------



## skyvan (11 Dezember 2009)

Hallo Kai

das sind schon alles aufgelöste Werte die Reihenfolge sieht so aus

Kalenderwoche: Int DBW0
Rate:    Real DBD2
Jahr: Int DBW6
Monat: Int DBW8
Tag: Int DBW10

da ich beim abspeichern der Blöcke eine Zykluszeitüberschreitung hatte habe ich die Blöcke auf 500 begrenzt.

und wenn ich die KW suche z.B. 49 sollen alle Werte aus dem DB mit KW 49 in den Anzeige DB kopiert werden max. 30 Blöcke

Gruß Marco


----------



## skyvan (14 Dezember 2009)

Hallo zusammen

@Larry
wenn ich das richtig sehe wird i nach dem laden 0 und wird dann mit Anzahl_Bloecke multipliziert.

hab ich das richtig verstanden?
qptr = Quellpointer
zptr = Zielpointer
qw = Kalenderwoche
i = Offset Pointer
J = Offset Pointer

Gruß Marco


----------



## Larry Laffer (14 Dezember 2009)

Hallo Marco,
in etwa stimmt es ...

Mit dem Setzen des Bit "Suche_starten" initialisiere ich das Notwendige. Eine neue Suche soll ja ggf. neue Ergebnisse bringen ...

In der i-Schleife durchsuche ich den von dir vorgegebenen Datenbereich nach Übereinstimmung. Das Such-DW ist dann "(i-1) * laenge_Block +1" also für den ersten Datensatz := (1-1)*12 +1 := 1 - für den 2.Datensatz := (2-1)*12 +1 := 13 - usw.
Habe ich eine Übereinstimmung (erstes Wort stimmt mit deiner Vorgabe überein, so schreibe ich die Daten in den angegebenen Ziel-Bereich "(Anzahl_gefunden -1) * laenge_Block " als z.B. (1-1) * 12 := 0 oder (2-1)*12 := 12 usw.

Das Ganze läßt sich natürlich noch optimieren ...
Funktioniert es ... oder nicht ?

Gruß
LL


----------



## skyvan (14 Dezember 2009)

Hi Larry

Ja funktioniert musste nur eine kleine Änderung machen da qw den Wert aus DW1 gelesen hat und somit einen Teil meines Real Wertes interpretierte.
Kann man die Werte die nicht übereinstimmen löschen bei suche Starten (Anzeige DB initialisieren)?
Vielen Dank an dieser Stelle.

Hab bei Siemens mal geschaut wegen SCL Kurs was hälst du davon?


```
FUNCTION FC2 : VOID            
Title   = 'DB durchsuchen'  
AUTHOR  : 'LL '
VERSION : '1.0'     
 
VAR_INPUT
   Start_suchen:   BOOL ;              // löst das suchen aus
   suche_KW:       INT ;               // Kalenderwoche 
   Quell_DB:       BLOCK_DB ;          // in dem DB wird gesucht
   Ziel_DB:        BLOCK_DB ;          // in den DB wird geschrieben
   laenge_Block:   INT ;               // wird in Byte angegeben
   Anzahl_Bloecke: INT;               // Anzahl der zu durchsuchenden Blöcke
   END_VAR
 
VAR_OUTPUT
            
Anzahl_gefunden: INT ;             // Anzahl gefundener Blöcke  
END_VAR
   VAR_IN_OUT
   Suche_beendet  : BOOL ; 
   End_var
 
   VAR_TEMP
   Bedingung_erfuellt : BOOL ; 
   i :     INT ;
   j :     INT ; 
   qptr :  INT ; 
   zptr :  INT ; 
   qw :    INT ;
 
END_VAR
 
//     Anweisungsteil
BEGIN
if Start_suchen and not Suche_beendet  then 
qw := 0; 
Anzahl_gefunden := 0 ;
for i:= 1 to Anzahl_Bloecke by 1 do
   qptr := (i-1) * laenge_Block [COLOR=red]+1[/COLOR] ;                              // löschen?
   qw := word_to_int(Quell_DB.DW[qptr]) ;
   if (qw = suche_KW) then 
      Anzahl_gefunden := Anzahl_gefunden + 1 ;
      zptr := (Anzahl_gefunden -1) * laenge_Block ;
      for j:= 1 to laenge_Block by 1 do
         Ziel_DB.DB[zptr+j-1] := Quell_DB.DB[qptr+j-1] ;
      end_for ;
   end_if ;
end_for ;
 
end_if ;
Suche_beendet  := Start_suchen ;
end_function
```
 
Gruß und nochmals vielen Dank Marco


----------



## Larry Laffer (14 Dezember 2009)

Hallo Marco,


skyvan schrieb:


> Kann man die Werte die nicht übereinstimmen löschen bei suche Starten (Anzeige DB initialisieren)?


Na klar ... da gibt es z.B. einen SFC Fill (21). Den könntest du im SCL-Script starten und ihm sagen, dass er den Ziel-DB zunächst löschen soll. Oder du machst dafür eine eigene Schleife, in der du die überzähligen Werte auf "0" setzt ...



skyvan schrieb:


> Hab bei Siemens mal geschaut wegen SCL Kurs was hälst du davon?


Das mußt du wissen. Wenn du schon Programmiersprachen-Kenntnisse hast, dann kannst es es mit einn paar Fragen hier und da auch so schaffen ... wenn nicht, dann ist das sicher sinnvoll.

Gruß
LL


----------



## skyvan (14 Dezember 2009)

Hi Larry

ich arbeite seit einigen Jahren mit Step7 und früher noch Step5 aber hochsprachen hab ich noch nicht gemacht und das wenige ist ewig her.

ja an Fill hab ich auch schon gedacht.

Gruß Marco


----------



## skyvan (29 Januar 2010)

*Erweiterung*

Hallo an alle

ich hab von User Larry Lafer folgenden Code erhalten den ich ein klein wenig abgeändert habe. Was ich noch benötige ist (jetzt) nicht nur die KW sondern auch das Jahr. Ich hoffe ihr könnt mir weiter helfen. Ich weiß es nicht genau aber ich glaube die von mir markierte Zeile müsste noch geändert bzw erweitert werden.


```
FUNCTION FC3 : VOID            
Title   = 'DB durchsuchen'  
AUTHOR  : 'Test'
VERSION : '1.0'     
 
VAR_INPUT
   Start_suchen:   BOOL ;              // löst das suchen aus
   suche_KW:       INT ;               // Kalenderwoche
   suche_Jahr      INT ;               // Jahr
   Quell_DB:       BLOCK_DB ;          // in dem DB wird gesucht
   Ziel_DB:        BLOCK_DB ;          // in den DB wird geschrieben
   laenge_Block:   INT ;               // wird in Byte angegeben
   Anzahl_Bloecke: INT;                // Anzahl der zu durchsuchenden Blöcke
   END_VAR
 
   VAR_OUTPUT
   Anzahl_gefunden: INT ;             // Anzahl gefundener Blöcke  
   END_VAR
   VAR_IN_OUT
   Suche_beendet  : BOOL ; 
   END_VAR
 
   VAR_TEMP
   Bedingung_erfuellt : BOOL ; 
   i :     INT ;
   j :     INT ; 
   qptr :  INT ; // Quelle Pointer week
   zptr :  INT ; // Ziel Pointer 
   qw :    INT ; // Quelle Week
   qj :    INT ; // Quelle Year
  
   END_VAR
 
//     Anweisungsteil
BEGIN
if Start_suchen and not Suche_beendet  then 
qw := 0;
qj := 0; 
Anzahl_gefunden := 0 ;
for i:= 1 to Anzahl_Bloecke by 1 do
   qptr := (i-1) * laenge_Block  ;
   [COLOR=red]qw := word_to_int(Quell_DB.DW[qptr]) ;
[/COLOR]   IF (qw = suche_KW) AND (qj = suche_Jahr)THEN 
      Anzahl_gefunden := Anzahl_gefunden + 1 ;
      zptr := (Anzahl_gefunden -1) * laenge_Block ;
      for j:= 1 to laenge_Block by 1 do
         Ziel_DB.DB[zptr+j-1] := Quell_DB.DB[qptr+j-1] ;
      end_for ;
   end_if ;
end_for ;
 
end_if ;
Suche_beendet  := Start_suchen ;
end_function
```
 
Gruß Marco


----------



## Larry Laffer (29 Januar 2010)

Hallo Marco,
nicht geändert ... du mußt für qt natürlich auch noch den Wert aus deiner DB-Matrix laden. Alles andere sieht erstmal OK aus ...

also z.B. :
qt := word_to_int(Quell_DB.DW[qptr +2]) ;


Gruß
LL


----------



## skyvan (29 Januar 2010)

Hi Larry

werd es gleich mal probieren meld mich dann noch einmal.

Gruß Marco


----------



## Larry Laffer (29 Januar 2010)

Hallo Marco,
ich habe jetzt allerdings nicht nachgesehen, ob Ptr+2 der richtige Platz in deiner Matrix ist ...!


----------



## skyvan (29 Januar 2010)

hi Larry

das ist schon ok das bekomme ich alleine hin ;-)

Danke hat alles super geklappt

Gruß Marco


----------

