# Chargendokumentation in WINCC



## dumens_de (27 Juni 2011)

Hallo Leute
Ich hab ein laufendes WINCC-Projekt, da werden Daten mit hilfe von Tag-Logging und Trendcontrol bereits mitgeschrieben. Jetzt brauche ich da eine Chargendokumentation.
Das bedeutet dass ein Report erstellt werden muss der Von der Startzeit der Charge bis zum Ende alle Meldungen und auch eine Kurve der Analogwerte ausdruckt.
Idealerweise sollte man die Chargen auch später noch abrufen können.
Ich hab mir überlegt die Startzeit abzuspeichern und dann mit der Meldung Chargenende alle Meldungen und Analogwerte zwischen den beiden Zeiten zu Exportieren und dann diese Datei(en) auszuwerten bzw. zu Drucken.

Gibt es da ein Beispielprojekt von Siemens oder so was. Ich finde da nix.

Simatic Batch Control ist wahrscheinlich zu teuer.


----------



## pylades (27 Juni 2011)

Moin,

da ist PM-Quality das ideale Werkzeug:
http://www.industrysolutions.siemen...x.asp?menu=2&cont=2_9&rel=support&Index=entry

Listenpreis Standard Version(eine Produktionseinheit) 2.100,00 €

Kann ich Dir nur empfehlen

Pylades


----------



## sailor (27 Juni 2011)

Du könntest das evtl. auch mit den Report-Designer von WINCC machen. 
- Im Reportdesigner ein Layout mit allen was Du brauchst anlegen
- einen Druckauftrag anlegen
- über C-Script RPTJobPrint(pszJobName) Druckauftrag ereignisgesteuert über eine externe Variable starten und im Druckauftrag sowohl auf den Drucker als auch in eine Datei ausdrucken. Name und Speicherort der Datei
kannst Du im Druckauftrag festlegen.

Gruß
Sailor


----------



## dumens_de (27 Juni 2011)

Das mit dem  PM-Quality hab ich auch gefunden, ist aber zu teuer.

Das mit dem RPTJobPrint(pszJobName) Druckauftrag hab ich schon erfolglos getestet. Das wäre aber absolut ausreichend für meine Anwendung.
Allerdings finde ich keine Beschreibung wie das zu machen ist, Startzeit Endezeit müssten gesetzt werden und das ganze an den Druckauftrag (der z.Zt. nur Tabellenkopf und X-Y-Achse druckt) übergeben werden.
Das müsste doch alles in dieses C-Skript rein, aber genau dafür finde ich nichts.


----------



## B.Dom (27 Juni 2011)

Naja, dass du eine Lösung findest die genau auf dein Problem zugeschnitten ist ist wohl auch eher unwahrscheinlich, aber mit ein paar C-Grundkenntnissen lässt sich da doch schon was machen.

Schonmal was in C gemacht in Verbindung mit WinCC ?


----------



## dumens_de (28 Juni 2011)

Genau das findet man natürlich nicht.
Aber ein Skript, das den Ausdruck über einen Bestimmten Zeitraum macht, hatte ich mir schon erhofft. Das brauchen doch sicherlich viele.
Ich hab bisher immer bei Siemens was gefunden, das ich dann entsprechend angepasst habe. Hier finde ich aber nichts.

So wie es mir erscheint gibt es 2 Möglochkeiten dies zu löse.
1. Wie beschrieben Ausdruck und Ausdruck in Datei.
2. Export von Meldungen und TAGs, über einen besti,,ten Zeitraum, die dann wieder geladen werden können.

Punkt 2 wäre mir lieber aber Punkt 1 wäre auch akzeptabel.

Weis evtl. jemand wo man so ein Skript programmieren lassen kann?
Das kann ja auch nicht so viel kosten.


----------



## Willi Wusel (28 Juni 2011)

sailor schrieb:


> Du könntest das evtl. auch mit den Report-Designer von WINCC machen.
> - Im Reportdesigner ein Layout mit allen was Du brauchst anlegen
> - einen Druckauftrag anlegen
> - über C-Script RPTJobPrint(pszJobName) Druckauftrag ereignisgesteuert über eine externe Variable starten und im Druckauftrag sowohl auf den Drucker als auch in eine Datei ausdrucken. Name und Speicherort der Datei
> ...



Wobei du aber nur eine Datei im emf-Format erzeugen kannst (andere Dateiformate sind nicht möglich) und der Dateiname ist auch nicht frei wählbar bzw. per Variable steuerbar. Im Projektpfad des WinCC Projekts wird von WinCC der Ordner "PRT_OUT" erstellt. In diesem Ordner wird von WinCC ein Ordner mit dem eingegebenen Namen angelegt und der Ordnername wird durch Erstelldatum und Uhrzeitangabe ergänzt. Der Bericht wird beim Start der Ausgabe in diesem Ordner seitenweise als emf-Dateien gespeichert. 

Schließe mich dem Vorschlag von pylades an, das Add-On "PM-Quality" einzusetzen.  

Gruß Willi


----------



## dumens_de (28 Juni 2011)

Wäre das über User Archive zu realisieren?


----------



## sailor (29 Juni 2011)

Der Druckauftrag müßte über das C-Script ausgelöst werden und der Trigger des C-Script über eine Variable. Das kann man im C-Editor im Dialog Trigger angeben.
Was mir nicht klar ist, ist das mit der PDF-Ausgabe. Die ist gegraut und kann nicht angewählt werden. In der Hilfe hab ich deswegen auch nichts gefunden.
Ist keine Startzeit angewählt, wird der Auftrag eben durch das Script sofort gestartet.
In der Ablage kann der Pfad der .emf Datei angegeben werden.
In den ordner PRT_OUT wird scheinbar nur dann ausgedruckt, wenn keiner der angegebenen Drucker bereit ist. Eventuell kannst du 2 Aufträge starten. 1. Drucker 2. PDF-Creator. PDF-Creator auf  automatisches Speichern stellen.
Wg. der gegrauten PDF-Anwahl im Druckauftrag würde ich mal Siemens -Support kontaktieren

Das sind jetzt aber nur Anregungen. Getestet hab ichs nicht.

Viel Spass
Sailor


----------



## daschris (29 Juni 2011)

Hallo 
ich hab mal sowas mit standardmitteln gemacht.
Du musst eigntlich nur den passenden SQL string zusammenbauen und ihn dann an das meldeocx im reportdesigner unter "Verbinden/dynamischeParameter" hängen. In dem Beispiel hier sind jetzt die Zeiträume fest vorgegeben ich weiss nicht wo du die Daten herbekommst aber ich hole sie mir vorher per query aus dem user archiv (Ist auskommentiert)... Das ganze war nur mal zum ausprobieren, das kundenprojekt finde ich jetzt nicht 

Hier auf dem Bild kannst du den Report sehen.

Vielleicht ist es ja was für dich


```
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
float ErgSilo, ErgBio, ErgAll;
char SQLString1[500], *Query, *OneQuery, *OneEntry, ZielBio[50], CIPSQLAlarm[500], CIPSQLWarning[500];
long int dwCount;
char **QueryResult;
char tag[50], BatchName[500], SQLMeldungen[500], SQLBedMeldungen[500];
int i, k;
strcpy(tag,"03/05/2009");
strcpy(BatchName,"KREIS 1 RM_PIPE CIP LA");
sprintf(SQLString1,"Batchname like '%s' AND Startzeitpunkt >=  '%s 00:00:00' AND Startzeitpunkt <=  '%s 23:59:59'",BatchName, tag,tag);
sprintf(SQLMeldungen,"DATETIME >=  '2009-07-28 15:19:45.000' AND DATETIME <=  '2009-07-28 15:21:00.000' AND Class = 1");
sprintf(SQLBedMeldungen,"DATETIME >=  '2009-07-28 15:19:45.000' AND DATETIME <=  '2009-07-29 15:21:00.000' AND Class = 2");
//strcpy(CIPSQLAlarm,"CLASS IN(1) AND TYPE IN(1)");
//strcpy(CIPSQLWarning,"CLASS IN(1) AND TYPE IN(1 ,2 ,3)");
//strcpy(CIPSQLAlarm,"CLASS IN(1) AND TYPE IN(1 ,2 ,3)");
SetTagChar("SQLString_1",SQLString1);
SetTagChar("CIPSQLMeldungen",SQLMeldungen);
SetTagChar("CIPSQLBedMeldungen",SQLBedMeldungen);
SetTagChar("CIPTag",tag);
SetTagChar("CIPBatchName",BatchName);
//SetTagChar("CIPSQLAlarm",CIPSQLAlarm);
//SetTagChar("CIPSQLWarning",CIPSQLWarning);
/*
GetQueryFromUserArchive("ARCH_4",SQLString1, &dwCount,&QueryResult);
k=1;
ErgBio=0;
for (i=0; i<dwCount; i++){
       OneQuery=strtok(QueryResult[i],","); 
       while (OneQuery != NULL){
               switch(k){
                       case 1: SetTagChar("ZR_StartZeit_1",OneQuery); break; //Startzeit
                       case 2: SetTagChar("ZR_ZielZeit_1",OneQuery); break;//Endzeit
                       case 3: SetTagChar("ZR_Start_1",OneQuery); break;//Quelle
                       case 4: SetTagChar("ZR_Ziel_1",OneQuery); break;//Ziel
                       case 5: SetTagChar("ZR_MengeSoll_1",OneQuery); break; //Soll wert
                       case 6: SetTagChar("ZR_Menge_1",OneQuery);break;  //Ist wert
                       case 7: SetTagChar("ZR_Charge_1",OneQuery);break; //BatchID
                       case 8: SetTagChar("ZR_ChargeName_1",OneQuery);break; //BatchName
               }           
               OneQuery =strtok(NULL,",");
               k++;
       }
       free(QueryResult[i]);
}
free(QueryResult);
*/

RPTJobPrint("Druckauftrag004");
}
```


----------



## dumens_de (29 Juni 2011)

Danke für die Antworten.
Ich kann das z.Zt. aber nicht testen. Damit kann ich aber was anfangen.
Ich werde noch mitteilen, wie ich es letztendlich gemacht habe.


----------



## dumens_de (7 Juli 2011)

So nun hab ich mal verschiedene Sachen Probiert und die Sache so gemacht wie Sailor das vorgeschlagen hat. Der Vorschlag von daschris wäre wahrscheinlich besser, bekam ich aber nicht zum laufen.


Ich setze mit diesem VB Skript die Startzeit:
Sub OnClick(ByVal Item)        
Dim ActDate
Dim Year_Sect
Dim Month_Sect
Dim Day_Sect
Dim Date_Mod
Dim ActTime
Dim Time_Mod_b_1
Dim DateString_b_1

    ActDate = Date                    'aktuelles Datum ermitteln - get actual date


    Year_Sect = Year(Date) 
    Month_Sect = Month(Date)
    Day_Sect = Day(Date)
    'Date_Mod = Year_Sect & "-" & Month_Sect & "-" & Day_Sect
    Date_Mod = Day_Sect & "." & Month_Sect & "." & Year_Sect

    ActTime = Time 'aktuelle Uhrzeit ermitteln - determine actual time


    Time_Mod_b_1 = DateAdd("n", -1, ActTime)   'aktuelle Uhrzeit minus 1 Minuten ermitteln


    DateString_b_1 = Date_Mod &" "& Time_Mod_b_1


    HMIRuntime.Tags("BeginTime_1").Write DateString_b_1 

End Sub
​Mit diesem den Endzeitpunkt:

Sub OnClick(ByVal Item)       
Dim ActDate
Dim Year_Sect
Dim Month_Sect
Dim Day_Sect
Dim Date_Mod
Dim Date_End
Dim ActTime
Dim Time_Mod_e_1
Dim Time_Mod_e_2
Dim DateString_e_1
Dim DateString_e_2

    ActDate = Date                    'aktuelles Datum ermitteln - get actual date


    Year_Sect = Year(Date) 
    Month_Sect = Month(Date)
    Day_Sect = Day(Date)
    'Date_Mod = Year_Sect & "-" & Month_Sect & "-" & Day_Sect
    Date_Mod = Day_Sect & "." & Month_Sect & "." & Year_Sect

    ActTime = Time 'aktuelle Uhrzeit ermitteln - determine actual time


    Time_Mod_e_1 = DateAdd("n", +1,  ActTime)   'aktuelle Uhrzeit plus 1 Minuten ermitteln


    DateString_e_1 = Date_Mod &" "& Time_Mod_e_1


    HMIRuntime.Tags("EndTime_1").Write DateString_e_1

End Sub​Kuve Ausdruck im Zeitbereich geht.


Was nicht geht ist, dass ich diese Skripts durch eine Meldung oder sonstwie Ereignisgesteuert auslösen kann. Da geht nur C-Skript.
Wäre schön wenn da jemand eine Idee hätte.


Dann hab ich noch die Meldeliste.
Da hab ich folgendes von daschris Vorschlag herausgezogen und angepasst. Steridok2 ist die Liste.
Funktioniert keider nicht, keine Ahnung wie das Start und endedatum da in das Formular kommen soll:
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{

char **QueryResult;
char tag[50], BatchName[500], SQLMeldungen[500], SQLBedMeldungen[500];
int i, k;

sprintf(SQLMeldungen,"DATETIME >=  '2011-01-03 15:19:45.000' AND DATETIME <=  '2011-07-05 15:21:00.000' AND Class = 1");

SetTagChar("CIPSQLMeldungen",SQLMeldungen);

RPTJobPrint("Steridok1");    
RPTJobPrint("Steridok2");
​Wäre schön wenn da noch jemand nen tip hätte.
Danke im Voraus.
​


----------



## sailor (7 Juli 2011)

Hi,
nochmal: Einen Report im Reportdesigner anlegen mit allen was Du brauchtst. Auch ein "WINCC-Online-trend- Control" kann als Bild in diesen Report eingebracht und dynamisiert werden, fast wie im normalen Grafikdesigner. Im Dialog kannst Du auch die von Dir berechnete (warum mit Klick und nicht zyklisch?) Start/Stop-Zeit eintragen. Die Kurvenvariablen des Control im Report müssen aber aus den Archiv kommen. 
Der Ausdruck  erfolgt mit einen Druckauftrag in einen globalen C-Script mit Trigger durch eine Variable (Ext/Int - egal).
Weil Du fragst, wie ein Script ereignisgesteuert werden kann: Vielleicht weisst Du ja nicht, das es im Projektbaum des WINCC-Explorers den Punkt "Global Script" gibt. Dort müsste auch das Script mit der Druckauftagssteuerung und auch Dein Script, welches ja über einen Mausklick ausgeführt wird
Hoffe jetzt klappts.
Ansonsten hocke ich mich am WE mal hin und probiers selber.
Gruß
Sailor


----------



## dumens_de (8 Juli 2011)

Danke nochmal für die Anregung.
Ich hab aner eigentlich nur 2 Problemchen. 
Das eine ist dass ich die "Endzeit nicht geschrieben bekomme, weil ich das ding nicht in C hinbekomme und weil VB skript nicht von einer Meldung aufgerufen werden kann.
Das zweite ist, dass das Zeitfenster funktioniert, wenn ich im Reportdesigner das hier erzeuge "
DATETIME >=  '2011-07-08 00:00:00.000' AND DATETIME <=  '2011-07-08 23:59:59.999'

aber nicht das mit Variablen:
DATETIME >=  "TimeStart_1"AND DATETIME <=  "TimeEnd_1"

Wobei die Variablen beim Trend funktionieren. Da werden allerdings die millisekunden nicht gebraucht soviel ich weis.


Die Funktion einer Textliste vermisse ich im Report auch. Das muß aber doch eigentlich gehn.


----------



## pylades (8 Juli 2011)

dumens_de schrieb:


> ....
> Was nicht geht ist, dass ich diese Skripts durch eine Meldung oder sonstwie Ereignisgesteuert auslösen kann. Da geht nur C-Skript.
> Wäre schön wenn da jemand eine Idee hätte.
> ...
> Danke im Voraus.



VBS-Aktionen kann man auch ereignisgesteuert auslösen.

 Aktionen
Einleitung
 Eine Aktion wird immer durch einen Trigger ausgelöst. In Runtime wird eine  Aktion z.B. ausgeführt, wenn ein Objekt per Mausklick bedient wird, ein  bestimmter Zeitpunkt eingetreten ist oder ein Variablenwert sich geändert  hat


Pylades


----------



## dumens_de (13 Juli 2011)

Danke zunächst mal für eure hilfe.
Ich hab aber immer noch einige Probleme.

Kannmir vileicht jemand sagen warum das hier nicht geht:

Option Explicit
Function action
Dim PROGRAMM
Dim SteriOPDATPR_AKT


Set SteriOPDATPR_AKT = HMIRuntime.Tags("Steri/OPDAT.PR_AKT")
Set PROGRAMM = HMIRuntime.Tags("PROGRAMM")


HMIRuntime.Tags("PROGRAMM").Write "P1 121°C"     DAS HIER GEHT SOLANGE OBEN DAS .READ nicht dort steht

     If SteriOPDATPR_AKT = 1 Then                        DAS NICHT
HMIRuntime.Tags("PROGRAMM").Write "234"
     Elseif SteriOPDATPR_AKT = 2 Then
HMIRuntime.Tags("PROGRAMM").Write "345"
     Elseif SteriOPDATPR_AKT = 3 Then
HMIRuntime.Tags("PROGRAMM").Write "456"
     Else
HMIRuntime.Tags("PROGRAMM").Write "456"
         MsgBox "Value out of range!"
     End If

End Function


Dann ist da noch das Problem diesen String in eine Variable zu schreiben und dabei die Uhrzeit die Kursiv ist durch Variablen zu ersetzen.

DATETIME >=  '_2011-07-13 00:00:00_.000' AND DATETIME <=  '_2011-07-13 23:59:59_.999'

Danke schon mal im Voraus.


----------



## sailor (14 Juli 2011)

Das hier:
_Set SteriOPDATPR_AKT = HMIRuntime.Tags("Steri/OPDAT.PR_AKT")
Set PROGRAMM = HMIRuntime.Tags("PROGRAMM")
_
Ergänzen: _SteriOPDATPR_AKT.read
__PROGRAMM.read

Für die andere sache hab ich jetzt grad keine Zeit. Kannst du das mit den String genauer beschreiben? ist irgendwie unklar, was du machen willst.
Gruß
Sailor
_


----------



## dumens_de (14 Juli 2011)

_Das müßte meiner meinung nach so aussehen:
in der Variablen __Steri/OPDAT.PR_AKT steht mit Sicherheit  ; 2 oder 3 drin_
_
Option Explicit
Function action
Dim PROGRAMM
Dim SteriOPDATPR_AKT


Set SteriOPDATPR_AKT = HMIRuntime.Tags("Steri/OPDAT.PR_AKT").Read

     If SteriOPDATPR_AKT = 1 Then     
HMIRuntime.Tags("PROGRAMM").Write "234"
     Elseif SteriOPDATPR_AKT = 2 Then
HMIRuntime.Tags("PROGRAMM").Write "345"
     Elseif SteriOPDATPR_AKT = 3 Then
HMIRuntime.Tags("PROGRAMM").Write "456"
     Else
HMIRuntime.Tags("PROGRAMM").Write "456"
         MsgBox "Value out of range!"
     End If

End Function


Das andere ist, dass das hier als String in eine Variable muß, akllerdings müssen Teile davon Variabel sein.

_DATETIME >=  '_2011-07-13 00:00:00_.000' AND DATETIME <=  '_2011-07-13 23:59:59_.999'

So:

DATETIME >=  '_VARIABLE1_.000' AND DATETIME <=  '_VARIABLE2_.999'


----------



## dumens_de (14 Juli 2011)

Zur Info
Ich hab den String jetzt in der SPS zusammengebastelt.


----------

