Werte aus einen DB auslesen

vierlagig

Well-known member
Beiträge
9.882
Punkte Reaktionen
2.020
Zuviel Werbung?
->Hier kostenlos registrieren
klar larry, für dich immer :ROFLMAO: ...

also erstmal der baustein, der im OB35 alle 10ms aufgerufen wird

Code:
*
FUNCTION_BLOCK "Kurvenschreiber"
TITLE =
//Kurvenschreiber
//
//Aurufumgebung: Weckalarm OB mit 10ms
//Interface: EXCEL, Visu, other direkt auf IDB
//
//Dieser Baustein erstellt nach einem Startimpuls einen Datenbaustein mit aus 
//Aufzeichnungsdauer und Stützpunktanzahl berechneter Länge. Der Datenbaustein 
//wird mit den Daten des angegebenen MD gefüllt.
//
//Es können max. 10 DB angelegt werden. Bevor eine neue Messung gestartet werden 
//kann, müssen diese 10 DB gelöscht werden.
//
//DATE:     19.05.2008
//AUTHOR:   4lagig
//VERSION:  V0.1
AUTHOR : '4lagig'
VERSION : 0.1


VAR
  xInStart : BOOL ;    //Aufzeichnung starten
  xInDeleteDb : BOOL ;    //Datenbausteine löschen
  xOutOnAir : BOOL ;    //Aufzeichnung läuft
  xDbOverflow : BOOL ;    //10 DBs angelegt
  xHelpFlag1 : BOOL ;    
  xHelpFlag2 : BOOL ;    
  iInMdNumber : INT ;    //Aufzuzeichnendes Doppelwort
  iInTimeStamp : INT ;    //Auflösung
  iInTimeWriting : DINT ;    //Aufzeichnungsdauer in ms
  wDbNumber : WORD ;    //Nummer des erstellten DB
  wDbLength : WORD ;    //Länge des erstellten DB
  iCreateReturn : INT ;    
  iDataCounter : INT ;    //Adressierungszähler
  iCycleTimes : INT ;    //Aufzeichnungshäufigkeit
  iCycleCounter : INT ;    //Aufzeichnungszähler
  iDelReturn : INT ;    
  wBuffer0 : WORD ;    
  wBuffer1 : WORD ;    
  wBuffer2 : WORD ;    
  wBuffer3 : WORD ;    
  wBuffer4 : WORD ;    
  wBuffer5 : WORD ;    
  wBuffer6 : WORD ;    
  wBuffer7 : WORD ;    
  wBuffer8 : WORD ;    
  wBuffer9 : WORD ;    
  iDbCounter : INT ;    //erstellte DBs zählen
END_VAR
VAR_TEMP
  wDbNumberTemp : WORD ;    //Datenbausteinnummer zur Weiterverarbeitung
  dMdNumber : DWORD ;    //Merkerdoppelwortnummer zur Weiterverarbeitung
  dAr1Save : DWORD ;    //AR1
  dAr2Save : DWORD ;    //AR2
  wDbnoSave : WORD ;    //letzter globaldaten DB
  iLoop : INT ;    //Schleifenzähler
END_VAR
BEGIN
NETWORK
TITLE =


// ---------> Interrupt-Daten sichern <--------- //


      L     DBNO; // letzten offenen Globaldatenbaustein ...
      T     #wDbnoSave; // ... sichern
      TAR1  #dAr1Save; // AR1 sichern
      TAR2  #dAr2Save; // AR2 sichern


// --------> Startbedingungen ermitteln <------- //


      U     #xOutOnAir; // Aufzeichnung läuft bereits
      SPB   log; // dann aufzeichnen

      U     #xInStart; // Startimpuls
      FP    #xHelpFlag1; 
      UN    #xDbOverflow; // bereits 10 Aufzeichnungen gemacht
      SPBN  late; // neuer DB oder Möglichkeit zu löschen


// -------> Datenbausteinnummer prüfen <-------- //


      L     #wBuffer9; // der letzte Pufferplatz
      L     0; // ungleich 0
      <>I   ; // heißt 10 DBs angelegt
      O     ; // oder
      L     #iDbCounter; // der DB-Zähler
      L     10; // ist auf 10
      ==I   ; 
      SPBN  go; // wenn noch Platz ist, ist alles i.O.
      S     #xDbOverflow; // 10-DBs angelegt
      SPA   late; // maximale Anzahl erreicht, erst löschen


// ------> Datenbausteinlänge ermitteln <------ //


go:   L     #iInTimeWriting; // Länge der Aufzeichnung
      L     #iInTimeStamp; // Trigger 10, 20, 30, ... 100ms ...
      /I    ; // = Anzahl der Aufzuzeichnenden Werte
      L     4; // REAL in Bytes ...
      *I    ; // ...Anpassung
      +     4; // Kopfdaten 2*INT
      T     #wDbLength; // Datenbausteinlänge


// ----------> Datenbaustein erzeugen <--------- //


      CALL "CREAT_DB" (
           LOW_LIMIT                := W#16#1,// Bereich der DB-Nummer
           UP_LIMIT                 := W#16#FF,// angeben
           COUNT                    := #wDbLength,// Länge übergeben
           RET_VAL                  := #iCreateReturn,// Fehlercode
           DB_NUMBER                := #wDbNumber);// DB Nummer zur weiterbearbeitung


// --------> Datenbausteinnr. ablegen <--------- //


      L     #wBuffer8; // shift-Register begin...
      T     #wBuffer9; // 
      L     #wBuffer7; // 
      T     #wBuffer8; // 
      L     #wBuffer6; // 
      T     #wBuffer7; // 
      L     #wBuffer5; // 
      T     #wBuffer6; // 
      L     #wBuffer4; // 
      T     #wBuffer5; //                
      L     #wBuffer3; // 
      T     #wBuffer4; // 
      L     #wBuffer2; // 
      T     #wBuffer3; // 
      L     #wBuffer1; // 
      T     #wBuffer2; // 
      L     #wBuffer0; // 
      T     #wBuffer1; // 
      L     #wDbNumber; // 
      T     #wBuffer0; // ... end

      L     #iDbCounter; // DB-Zähler
      +     1; // 
      T     #iDbCounter; // inkrementieren


// -------------> Initialisierung <------------- //


      L     0; // 0
      T     #iDataCounter; // für den Wertezähler

      L     0; // 0
      T     #iCycleCounter; // für Aufzeichnungszähler

      L     #iInTimeStamp; // Trigger 10, 20, 30, ... 100ms ...
      L     10; // 10
      /I    ; // dividiert
      T     #iCycleTimes; // macht die Pausen

      L     #wDbLength; // verfügbarer Speicherplatz
      +     -4; // -4 
      T     #wDbLength; // macht Adressierung

      SET   ; // 1
      S     #xOutOnAir; // für Aufzeichnung läuft


// -------------> Kopf schreiben <-------------- //


      L     #wDbNumber; // DB-Adresse
      T     #wDbNumberTemp; // für Weiterverarbeitung

      L     #iDataCounter; // Adressierungszähler
      SLD   3; // Bits maskieren
      LAR1  ; // in AR1  laden
      AUF   DB [#wDbNumberTemp]; // DB öffnen

      L     #wDbLength; // DB Länge Nutzdaten
      T     DBW [AR1,P#0.0]; // in DB schreiben

      L     #iInTimeStamp; // Auflösung
      T     DBW [AR1,P#2.0]; // in DB schreiben

      L     #iDataCounter; // Adressierung
      +     4; // um vier
      T     #iDataCounter; // erhöhen  


// --------------> Daten erfassen <------------- //


log:  U     #xOutOnAir; // Aufzeichnung läuft
      SPBN  late; // 

      L     #iCycleCounter; // Aufzeichnungszähler
      L     1; 
      +I    ; // inkrementieren
      T     #iCycleCounter; 

      L     #iCycleCounter; 
      L     #iCycleTimes; // mit Soll
      ==I   ; // vergleichen
      SPBN  late; // wenn nich, dann nich

      L     0; // wenn doch, dann 0
      T     #iCycleCounter; // in Aufzeichnungszähler

      L     #wDbNumber; // DB-Adresse
      T     #wDbNumberTemp; // für Weiterverarbeitung

      L     #iInMdNumber; // MD-Adresse
      SLD   3; 
      T     #dMdNumber; // für Weiterverarbeitung

      L     #iDataCounter; // Adressierungszähler
      SLD   3; // Bits maskieren
      LAR1  ; // in AR1  laden
      AUF   DB [#wDbNumberTemp]; // DB öffnen
      L     MD [#dMdNumber]; // Wert
      T     DBD [AR1,P#0.0]; // in DB schreiben

      L     #iDataCounter; // Adressierung
      +     4; // um vier
      T     #iDataCounter; // erhöhen     

      L     #wDbLength; 
      L     #iDataCounter; // mit Adressierungszähler
      <=I   ; // vergleichen
      SPBN  late; 
      R     #xOutOnAir; // Aufzeichnung beendet


// ---------> Datenbausteine löschen <---------- //


late: U     #xInDeleteDb; // löschen angefordert
      FP    #xHelpFlag2; 
      UN    #xOutOnAir; // und keine Aufzeichnung aktiv
      SPBN  end; 

      L     10; // max. angelegte DBs
next: T     #iLoop; // als Schleifenzähler benutzen

      L     #wBuffer0; // DB-Adresse auf 0 prüfen
      L     0; 
      ==I   ; // wenn 0 (=ungültige DB-Adresse)
      SPB   shif; // löschen überspringen

      CALL "DEL_DB" (// Datenbaustein löschen
           DB_NUMBER                := #wBuffer0,
           RET_VAL                  := #iDelReturn);

shif: L     #wBuffer1; // shift-Register begin...
      T     #wBuffer0; //  
      L     #wBuffer2; // 
      T     #wBuffer1; // 
      L     #wBuffer3; // 
      T     #wBuffer2; // 
      L     #wBuffer4; // 
      T     #wBuffer3; // 
      L     #wBuffer5; // 
      T     #wBuffer4; // 
      L     #wBuffer6; // 
      T     #wBuffer5; // 
      L     #wBuffer6; // 
      T     #wBuffer7; // 
      L     #wBuffer7; // 
      T     #wBuffer8; // 
      L     #wBuffer9; // 
      T     #wBuffer9; // 
      L     0; // 
      T     #wBuffer9; // ... end

      L     #iLoop; 
      LOOP  next; 
      SET   ; 
      R     #xDbOverflow; // max-Bit rücksetzen
      L     0; 
      T     #iDbCounter; // Datenbausteinzähler zurücksetzen


// -------------> Schlußbehandlung <------------ //


end:  LAR1  #dAr1Save; // AR1 rücksichern
      LAR2  #dAr2Save; // AR2 rücksichern
      AUF   DB [#wDbnoSave]; // letzten Globaldatenbaustein öffnen
      SET   ; 
      SAVE  ; // EN0 eins machen
      BE    ; 

END_FUNCTION_BLOCK
im excel sieht das dann wie im anhang aus.

es ist weder bugfrei noch ausführlich getestet geschweigedenn besonders schön, gerade der VBA-teil ist überarbeitungsbedürftig, hab es wie gesagt nur schnell zusammengeschustert
 

Anhänge

  • libnodavebsp.jpg
    libnodavebsp.jpg
    263,7 KB · Aufrufe: 425
Zuletzt bearbeitet:

vierlagig

Well-known member
Beiträge
9.882
Punkte Reaktionen
2.020
also um das jetzt nochmal festzuhalten:

larrys protool-lösung funktioniert 1. natürlich auch und wird 2. die werte evtl. komfortabler darstellen können

wollte den protool-gedanken nicht untergraben, nur feststellen das es ein paar mehr wege nach rom gibt und wie larry bewies funktioniert es eben auch über protool, ebenso wie mit libnodave, man kann es auch mit OPC und dde-anbindung machen ...
 
OP
magmaa

magmaa

Well-known member
Beiträge
339
Punkte Reaktionen
23
Zuviel Werbung?
->Hier kostenlos registrieren
Oh too manny input von vierlagig ist doch wieder ne andere möglichkeit oder?
Werde mich erstmal mit Protool auseinander setzten.
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.093
Punkte Reaktionen
2.720
Genau ..
der Vorschlag von 4L beschreibt eine alternative Möglichkeit - Im Prinzip in Anlehnung an den Beitrag #2 von MW in diesem Thread ...

Ich würde dir auf jeden Fall auch empfehlen, zunächst den eingeschlagenen Weg weiter zu verfolgen ...

Gruß
LL
 
OP
magmaa

magmaa

Well-known member
Beiträge
339
Punkte Reaktionen
23
Zuviel Werbung?
->Hier kostenlos registrieren
Danke der nachfrage aber bin gerade etwas zeitlich eingespannt.
Darum hab ich mich jetzt nicht weiter mit der Sache beschäftigt.
Aber soweit wieder Zeit ist oder die Notwendigkeit besteht, setzt ich mich nochmal mit dem Thema auseinander.
Und dann kommen auch sicher die nächsten Fragen.
 
OP
magmaa

magmaa

Well-known member
Beiträge
339
Punkte Reaktionen
23
Hallo so hab mich Interesse halber mal wieder mit dem Thema beschäftigt.
Mittlerweile aber mit WinCC flex 2008


Code:
On Error resume next
 
Dim appExcel , fs , wbExcel , wsExcel
Dim Verzeichnis , Datei
Dim Zeile
'------------------------------------------------------------------------------
' Variablen-Zuweisungen ...
Verzeichnis = "c:\daten\"
Datei = "test.xls"
'------------------------------------------------------------------------------
' Pointer auf Tabelle laden
Set appExcel = CreateObject ("EXCEL.Application")
Set fs = CreateObject ("Scripting.FileSystemObject")
'------------------------------------------------------------------------------
' Objekte erzeugen
' prüfe ob datei existiert. wenn nicht erzeugen.
if not fs.fileexists (Verzeichnis + Datei) then
    appExcel.Workbooks.Add
    appExcel.ActiveWorkbook.SaveAs(Verzeichnis + Datei)
end if
 
Set wbExcel = appExcel.Workbooks.Open (Verzeichnis + Datei)
Set wsExcel = wbExcel.Worksheets("Tabelle1")
 
' Zelle lesen und um 1 erhöhen
Zeile = wsExcel.Range("D1") + 1 
 
' Zelle beschreiben
wsExcel.Cells (Zeile , 1) = date
wsExcel.Cells (Zeile , 2) = time
wsExcel.Range("D1") = Zeile 
 
' Tabelle abspeichern
wbExcel.Close true 'false
appExcel.Quit ()
 
'------------------------------------------------------------------------------
' verwendeten Speicher wieder freigeben
Set wsExcel = Nothing
Set wbExcel = Nothing
Set fs = Nothing
Set appExcel = Nothing
Set Verzeichnis = Nothing
Set Datei = Nothing

Mit folgenden Code kann ich werte aus einer Variable auslesen und in Excel speichern.

Wenn ich nun aber aber DB mit n worten auslesen will brauch ja ziemlich viel Variablen im Wincc flex
Quasi pro Wort eine Variable und das ganze dann nochmal im Skript das ziemlich umständlich.

Kann man die Variablen Adressierung der Variablen in Wincc flex variable gestallten oder muss ich das mit pointer über die SPS machen.

Oder gibt es noch ne besser lösung?
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.093
Punkte Reaktionen
2.720
Hallo,
wie wäre es auf Seiten der SPS mit einem ARRAY ?
Dieses kannst du dann in der Visu als eine Variable (mit z.B. 100 Elementen) anlegen. Im Script kannst du die dann (innerhalb einer Schleife) indexieren. Dazu gibt es im Forum auch einige Beispiele (hier vor Allem nach den Beiträgen von Kai Ausschau halten).

Gruß
LL
 
OP
magmaa

magmaa

Well-known member
Beiträge
339
Punkte Reaktionen
23
Zuviel Werbung?
->Hier kostenlos registrieren
Also ich hab mir ein jetzt ein DB mit einem Array mit 10 Wörtern angelegt und in Wincc flex zwei Variablen.

Eine Interne index variable und eine zum DB

Sieht dann so aus Name: Wert, Adresse DB1 DBW [index]

Wenn ich das Skript von Hand über einen Button aufrufe und die index Variable im Skript um zwei erhöhe dann funktioniert es.

Wenn ich das ganze in eine Schleife packe wird mir nur ein Wert Angezeigt.
Wird das Skrit zuschnell bearbeite das die Aktualisierung der Variable Wert nicht hinterherkommt oder woran liegt das?

Code:
Index = 0
 
For i = 1  To 9

  ' Zelle lesen und um 1 erhöhen
  Zeile = wsExcel.Range("D1") + 1 
 
  ' Zelle beschreiben
  wsExcel.Cells (Zeile , 1) = Wert
  wsExcel.Cells (Zeile , 2) = "Wert " & i
  wsExcel.Range("D1") = Zeile 
 
  Index = Index + 2 

Next
 

Domi55

Well-known member
Beiträge
111
Punkte Reaktionen
1
Hallo,
wie wäre es auf Seiten der SPS mit einem ARRAY ?
Dieses kannst du dann in der Visu als eine Variable (mit z.B. 100 Elementen) anlegen. Im Script kannst du die dann (innerhalb einer Schleife) indexieren. Dazu gibt es im Forum auch einige Beispiele (hier vor Allem nach den Beiträgen von Kai Ausschau halten).
LL

Hallo Larry!
Das wäre genau das was ich benötige! Habe aber noch keinen Beitrag von Kai gefunden! Also 100 werte habe ich im DB! Jetzt muß ich halt das mit dem Array machen! Wie geht das genau?
Danke schonmal!
 

Domi55

Well-known member
Beiträge
111
Punkte Reaktionen
1
Oh man! Das klappt noch nicht so ganz! Habe mal das Script ein wenig umgewandelt! Aber es läuft nicht! Habe es mal im Anhang stehen! Das ganze soll auf dem Mobile Panel 277 laufen! Habe halt 50 Werte im DB! Habe noch keine Erfahrung mit VBS bzw mit Siemens VBS programmierung! Wäre über jede Hilfe super Dankbar!
Gruß Dominik
 

Anhänge

  • Script.txt
    2,6 KB · Aufrufe: 49
OP
magmaa

magmaa

Well-known member
Beiträge
339
Punkte Reaktionen
23
Zuviel Werbung?
->Hier kostenlos registrieren
Danke mit


Code:
'HINWEIS:
' Beim Erstellen von Skripten können Sie mit <Strg+Leertaste> vordefinierte 
' Systemfunktionen in das neue Skript einbinden.
' Das HMIRuntime-Objekt ermöglicht einfachen Zugriff auf die Objekte des
' WinCC flexible Objektmodells, ihre Methoden und ihre Eigenschaften.
' Für ein komfortables Auswählen einer Objektreferenz betätigen Sie bitte <Alt+Rechts>.
' Komplexe Skripte können Sie mit Sprachelementen der Programmiersprache
' VBScript erstellen.
' Der Zugriff auf WinCC flexible Variablen erfolgt direkt über den Variablennamen,
' z.B. Tag = 5


On Error Resume Next
 
Dim appExcel , fs , wbExcel , wsExcel
Dim Verzeichnis , Datei
Dim Zeile
Dim i 
'------------------------------------------------------------------------------
' Variablen-Zuweisungen ...
Verzeichnis = "c:\daten\"
Datei = "test.xls"
'------------------------------------------------------------------------------
' Pointer auf Tabelle laden
Set appExcel = CreateObject ("EXCEL.Application")
Set fs = CreateObject ("Scripting.FileSystemObject")
'------------------------------------------------------------------------------
' Objekte erzeugen
' prüfe ob datei existiert. wenn nicht erzeugen.
If Not fs.FileExists (Verzeichnis + Datei) Then
    appExcel.Workbooks.Add
    appExcel.ActiveWorkbook.SaveAs(Verzeichnis + Datei)
End If
 
Set wbExcel = appExcel.Workbooks.Open (Verzeichnis + Datei)
Set wsExcel = wbExcel.Worksheets("Tabelle1")


 
For i = 0  To 9

' Zelle lesen und um 1 erhöhen
Zeile = wsExcel.Range("D1") + 1 
 
' Zelle beschreiben
wsExcel.Cells (Zeile , 1) = SmartTags("wert1")(i) 
wsExcel.Cells (Zeile , 2) = "Wert " & i
wsExcel.Range("D1") = Zeile 

Next 
 
' Tabelle abspeichern
wbExcel.Close True 'false
appExcel.Quit ()
 
'------------------------------------------------------------------------------
' verwendeten Speicher wieder freigeben
Set wsExcel = Nothing
Set wbExcel = Nothing
Set fs = Nothing
Set appExcel = Nothing
Set Verzeichnis = Nothing
Set Datei = Nothing

geht es
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.093
Punkte Reaktionen
2.720
Zuviel Werbung?
->Hier kostenlos registrieren
@magmaa:
Zu WinCC kann ich nichts sagen ...

@Dominik:
Welches Ereignis (auf der Visu) startet denn dein Script ? Ich nehme an, dass du nur das Script hast. Das reicht aber nicht. Du könntest hier z.B. eine Taste nehmen und mit der das Script aufrufen - oder eine Variable (bei Wert-Änderung).

Gruß
LL
 

Domi55

Well-known member
Beiträge
111
Punkte Reaktionen
1
Hallo Larry!
Ich starte das Skript mit einem Button von der Folientastatur am Mobile Panel! Aber machen tut es noch nichts! Kann es sein das ich meinen DB nicht korrekt aufrufe?
LG Domi
 

Larry Laffer

Supermoderator
Teammitglied
Beiträge
13.093
Punkte Reaktionen
2.720
... dann wird das Script auch ausgeführt. In dem Fall ist der Fehler intern.
Auf den ersten Blick fällt mir da dein "bcreated" auf. Der muß TRUE sein, damit du etwas speicherst. Er ist aber nur dann TRUE, wenn es die Datei vorher nicht gab - wolltest du das so ?

Gruß
LL
 
Oben