# Mit Excel/VBA und OPC an S7300



## extruder_luder (31 März 2010)

Hallo,

ich nuss eine Anbindung von Excel an die S7 programmieren.

Dafür benutze ich den Siemens OPC Server. Nun habe ich eine Menge Daten, die ich nach Möglichkeut auf einmal lesen möchte.
Dafür möchte ich die Methode "DatCon1.ReadMultiVariable" benutzen. Das gelingt aber leider nicht.

Hat vielleicht jemand eine Programmausdruck in der er diese Methode gebraucht, inklusive der Variablendimensionierung.

Lese ich die Variablen einzeln mit "DatCon1.ReadVariable", so funktioniert es, der OPC Server arbeitet also.

Besten Dank im voraus für die schnelle Hilfe.

Gruss

Oliver


----------



## vladi (31 März 2010)

*-*

Hallo,



> ReadMultiVariable
> The ReadMultiVariable method reads the values from several process
> variables specified by the ItemID.
> The Syntax of the method is:
> ...



Arrays werden hier benötigt.

Gruss: V.


----------



## extruder_luder (31 März 2010)

*Danke*

Hallo,

danke erstmal für die Hilfe. Allerdings hatte ich diese schon gefunden. Trotzdem funktioniert es nicht. Deshalb wäre ich sehr dankbar, wenn ich ein funktionierendes Beispiel hätte.

Gruss


Oliver


----------



## BPlagens (31 März 2010)

Mal kurz aus dem Kopf runtergeschrieben!
Ich hoffe es hilft!
Bin morgen in der Arbeit, dann kann ich dir ein geprüftes Beispiel geben.


```
'diese variablen brauchen wir
DIM ReturnValue as Long
DIM Value(3) as Variant
DIM Error(3) as Variant
DIM Quality(3) as Variant
DIM MyTime(3) as Date
DIM Tag(3) as String 
'hier mal 3 beispieladressen
Tag(0)="S7:[MeineVerbindung]M0.0"
Tag(1)="S7:[MeineVerbindung]MB10"
Tag(2)="S7:[MeineVerbindung]MD12"
'jetzt lesen wir die 3 tags
ReturnValue = Data1.ReadMultiVariables(Tag, Value,Error,Quality,MyTime) 
'und das ganze mal anzeigen lassen 
debug.print cstr(Value(0))
debug.print cstr(Error(0))
debug.print cstr(Quality(0))
debug.print cstr(MyTime(0))
```
 
Viel Erfolg!


----------



## extruder_luder (1 April 2010)

Halloechen,

danke für das Beispiel. Habe ich auch direkt ausprobiert. Leider kommt sofort die Fehlermeldung "Laufzeitfehler 13, Typen unverträglich".

Wäre schön wenn Du es mal ausprobieren könntest und hoffentlich den Bug findest.

Vorerst vielen Dank.
Gruss
Oliver


----------



## vladi (1 April 2010)

*-*

Hi,

bei dem Code vom Kollege, da is:

DIM Value(3) as Variant
DIM Error(3) as Variant
DIM Quality(3) as *Variant*
DIM MyTime(3) as Date
DIM Tag(3) as String 

aber  Quality soll LONG sein.

V.


----------



## extruder_luder (1 April 2010)

Hallo,

im Handbuch "Industrielle Kommunikation mi PG/PC Band 2 " steht "Qualities" as Variant und in OPC mit Excel steht "Quality" as Long.
Also beide male Siemens und doch unterschiedlich. Ist mir aber auch egal, ich brauche schnell eine funktionierende Lösung.

Falls jemand Zeit und Lust hat das mal mit Excel VBA auszuprobieren und es klappt, wäre ich ihm sehr verbunden, wenn er mir den Programmcode inklusive der DIM Anweisungen posten könnte.

Vielen Dank für die Hilfe.

Gruss

Oliver


----------



## BPlagens (1 April 2010)

Gerade getestet und geht! 

```
Private Sub cmdReadMultiVariable_Click()
    Dim myValue As Variant 'hier schreibt DatCon1 den Wert der Variable rein
    Dim myQuality As Variant 'hier schreibt DatCon1 einen Wert für die Qualität des Tags rein (muss 192 sein)
    Dim myTimeStamp As Variant 'hier schreibt DatCon1 den TimeStamp des Tags rein
    Dim myErrors As Variant
    Dim ErrorNr As Long 'Rückgabewert des Aufrufes (muss 0) sein
    Dim ItemID(2) As String 'hier übergeben wir die Tag-Adresse !!Array geht von 0-2!
 
    On Error GoTo ErrorHandler
 
    'So heißt unser Tag - hier am Beispiel von INAT
    'Bei Siemens heißt es in etwa "S7:[Test]M1.7"
    ItemID(0) = "Test.M1.1"
    ItemID(1) = "Test.M1.2"
    ItemID(2) = "Test.M1.3"
 
    'Und aufrufen
    ErrorNr = DatCon1.ReadMultiVariables(ItemID, myValue, myErrors, myQuality, myTimeStamp)
 
    'Debug.Print myValue(1) & " "; CStr(myQuality(1))
    'hier muss geprüft werden ob ErrorNr(1)=0 und myQuality(1)=192 !!!
    'wenn nicht, hat das lesen nicht geklappt!
    txtWert1 = CStr(myValue(0))
    txtWert2 = CStr(myValue(1))
    txtWert3 = CStr(myValue(2))
    Exit Sub
 
ErrorHandler:
    MsgBox Err.Description
End Sub
Private Sub cmdReadVariable_Click()
    Dim myValue(1) As Variant 'hier schreibt DatCon1 den Wert der Variable rein
    Dim myQuality(1) As Long 'hier schreibt DatCon1 einen Wert für die Qualität des Tags rein (muss 192 sein)
    Dim myTimeStamp(1) As Date 'hier schreibt DatCon1 den TimeStamp des Tags rein
    Dim ErrorNr(1) As Long 'Rückgabewert des Aufrufes (muss 0) sein
    Dim ItemID(1) As String 'hier übergeben wir die Tag-Adresse
 
    On Error GoTo ErrorHandler
 
    'So heißt unser Tag - hier am Beispiel von INAT
    'Bei Siemens heißt es in etwa "S7:[Test]M1.7"
    ItemID(1) = "Test.M1.7"
 
    'Und aufrufen
    ErrorNr(1) = DatCon1.ReadVariable(ItemID(1), myValue(1), myQuality(1), myTimeStamp(1))
    Debug.Print myValue(1) & " "; CStr(myQuality(1))
    'hier muss geprüft werden ob ErrorNr(1)=0 und myQuality(1)=192 !!!
    'wenn nicht, hat das lesen nicht geklappt!
    txtWert1 = CStr(myValue(1))
    txtWert2 = "---"
    txtWert3 = "---"
    Exit Sub
 
ErrorHandler:
    MsgBox Err.Description
End Sub
```
 

Der Trick ist Array geht bei 0 los! Nicht bei 1!
Lade gleich mal ein VBA Beispiel hoch!

Viel Erfolg!

Edit: hier ein Link zu einer Excel-Mappe mit Macro (über Macro-Visual Basic...) Folgendes ist eingebunden:
- WriteVariable
- WriteMultiVariable
- ReadVariable
- ReadMultiVariable
- AddNotification
- ValueChanged

http://rapidshare.com/files/370656372/Mappe1.xls.html


----------



## extruder_luder (1 April 2010)

Hallo und Danke BPlagens,

der Aufruf der Routine ReadMultiVariable scheint jetzt zu funktionieren. Wenn ich mir allerdings den Inhalt der Variablen ansehen möcht, kommt die Fehlermeldung" Variable verwendet einen in VB nicht unterstützten Typ der Automatisierung".
Wäre nett, wenn Du mir dabei auch noch behilflich sein könntest.

Gruu

Oliver


----------



## extruder_luder (1 April 2010)

Hallo,

hier mal mein Programmcode:

Public Sub Read_S7_3_Head_For_Event()
Dim ItemId As String
Dim Value As Variant
Dim Quality As Long
Dim Timestamp As Date
Dim ReturnValue As Long
Dim i As Integer
Dim Valuelong As Long
'ItemId = "S7:[3_head]DB1,W0"  // auskommentiert , funktioniert
ItemId = "S7:[3_head]DB1,W0,2"  //  hier möchte ich einfach mal 2 Variablen gleichzeitig lesen
ReturnValue = UserForm1.DatCon1.ReadVariable(ItemId, Value, Quality, Timestamp)
Valuelong = CLng(Value(1))    // hier möcht ich den Inhalt einer Variablen lesen, dabei kommt es zur Fehlermeldung "VB unterstützt diesen Typ nicht
'If Valuelong <> Old_Event_3_Head Then Read_S7_3_Head_cycles
'Old_Event_3_Head = Valuelong
End Sub


Gruss 

Oliver


----------



## BPlagens (1 April 2010)

hallo!

sollte "Valuelong = CLng(Value(1)) " nicht besser "Valuelong=CLng(Value)" lauten? 

Value ist ja in diesem Fall kein Array - oder übersehe ich was? Wieso eigentlich Long wenn du nur ein WORD ließt?


----------



## extruder_luder (2 April 2010)

Hallo BPlagens,

ich lese ja mit der Zeile 

ItemId = "S7:[3_head]DB1,W0,2
ReturnValue = UserForm1.DatCon1.ReadVariable(ItemId, Value, Quality, Timestamp)


2 Worte im DB1 ab Adresse 0.

Deshalb stehen die Werte nach dem Aufruf  in Value(0) und 1.
So glaube ich jedenfalls. Leider kann ich die Werte nicht lesen, da die Fehlermeldung"VBA unterstützt dies Art der Variablen aus der Automatisierungstechnik nicht" kommt.

Da ich auf grosse Datenmengen zugreifen muss, kann ich leider nicht immer einzelne Werte lesen, sondern muss einen ganzen Bereich auf einmal lesen.

Ich habe auch schon in der Symboltabelle der S7 alle möglichen Datentypen ausprobiert, leider ohne Erfolg.

Noch ne Frage:
Hat vielleicht jemand ein Timer active X, ähnlich dem von Visual Basic, wo man Ticks und enable einstellt und dann Ereignisse ausgelöst werden, das ich in VBA eibetten kann?

Application.ontime ist leider sehr mangelhaft.

Gruss

Oliver


----------



## BPlagens (2 April 2010)

Oh, das habe ich übersehen!

Aber ich glaube das ist so keine gute Idee!

Ohne es genau zu wissen würde ich sagen, dass in "Value" jetzt 4 Byte liegen und du die erst mal in 2 Worte aufteilen musst!

Wie sieht denn Value aus wenn du einen Breakpoint setzt und dir die Variable ansiehst?

Ich würde für jede Variable auch einen eigenen Item anlegen. ReadMulti geht jetzt ja! 

Dann bekommst du auf jeden fall ja auch im Value(x) einen Wert den man vernünftig weiter bearbeiten kann.

Wenn es so viele Variablen sind kannst ja das ganze in einer Schleife lösen!


```
n=0
FOR i=1 to 10 STEP 2
    [FONT=Arial]ItemId(n)="S7:[3_head]DB1,W" & cstr(i)[/FONT]
    n=n+1
NEXT i
```
 
Auserdem dürfte dies keine unterschied bei der Performance machen - kannst du ja mal testen.

Was machst du eigentlich? Bist du sicher das VBA + Excel das richtige sind?

Ach ja folgendes zu deinem Timer Problem: http://www.cpearson.com/excel/OnTime.aspx

Nim doch VB 2008 Express und greif von da auf Excel zu - kostet auch nix und ist sicher deutlich komfortabler als das ganze mit VBA zu lösen! Oder du scheinst ja VB6 zu haben - warum nicht das?

cu
bernd


----------



## extruder_luder (4 April 2010)

Hallo BPlagens,

ich muss in 3 Wochen eine BDE in Australien installieren. Sie greift auf 6 CPU's zu und wird ca. 100000 Einträge pro Tag erfassen. Da alle Daten in einem gemeinsamen Excel Dokument liegen werden, schien es mir am einfachsten alles mit Excel zu erschlagen. 
Mein Problem ist, dass ich überhaupt keine Zeit habe und auch noch eine andere IB nächste Woche habe.

Deshalb: so schnell und einfach wie möglich.

Der Aufruf ReadMultiVariable funktioniert, aber wie beschrieben erhalte ich auch dort den Fehler "VB unterstützt diesen Typ der Automatisierung nicht". Richtig funktionieren tut nur der einfache Lesezugriff.

Von der Perfomance ist das Multi deutlich schneller.


Besten Dank, irgendwie schmuggele ich mich durch, sonst such ich mir einen neuen Job.

Gruss


Oliver


----------



## BPlagens (5 April 2010)

Stell doch mal deinen code rein mit realen Variablen, dann werf ich mal einen Blick drauf! 
Lt deinem letzten Beitrag kommt die Fehlermeldung doch bei ReadVariable..?

Aber mal aus meiner Erfahrung: Nimm nicht Excel dafür!!! Ich habe das auch mal auf Kundenwunsch gemacht (zu einer Zeit als Excel nur 32000 Zeilen konnte). Da gibt es nur Probleme! Glaube mir!!!! Schreib das ganze lieber in eine Datenbank (es geht auch Access mit VBA) und hole mit Excel die Daten aus der DB.

Du wirst mit Excel nicht glücklich! Excel ist wirklich gut, aber eben keine Datenbank es ist eine Tabellenkalkulation!

Ich löse das meistens so:
Ein OPC-Client (meist mit VB geschrieben) holt die Daten aus den SPSen und legt die Werte in der DB ab. Ein zweites Programm ist dann für die Auswertung zuständig - das greift dann nur auf die DB zu.

Wie willst du mit Excel denn von zwei Rechnern auf die Daten zugreifen (nur lesen geht ja - aber schreiben)?

Schon mal an etwas wie OPC-Router gedacht? Zum Beispiel http://www.inray.de/produkte/opcrouter.html . Klar kostet Geld, aber dafür musst du dich nicht mit der Control von Siemens beschäftigen.

Nochmal zu Excel 100.000 Werte per Tag? Das macht ja zwischen 90MB- 200MB am Tag! Schon mal mit einer Excel Tabelle gearbeitet die so groß ist? Wenn alles nur Byte sind dann hat du nach einem Monat ja 100.000*30=3.000.000 das sind 2.8GB/Monat = 33.6GB nach einem Jahr! 
Da kannst du mit Excel nicht händeln! Selbst Access kann glaube ich nur 2GB verwalten! 

Sollte ich einen Denkfehler haben - bitte berichtigen!
Übrigens solltest du mal einen Blick auf http://www.xlam.ch/xlimits/excel-new.htm werfen! Du musst den richten Datentyp wählen, wenn du solch hohe Zeilen bzw. Spalten mit VBA ansprechen willst!

Ich hoffe du hast dir da nicht zu viel vorgenommen!

Viel Erfolg!


----------



## vladi (5 April 2010)

*-*

Hi,

BPLagens schildert es sehr schön. Ich hatte Varianten mittels PostgreSQL und MySQL, die Datenbanken sind relativ schnell und nehmen nicht so viel Platz.

Wenn die Daten in der Datenbank vorliegen, kann man nacher nach Lust und Laune mittels Excel Auswertungen bzw. Protokolle erstellen..
DB kann mittels Backup gesichert werden, und an anderen PCs für lokale Bearbeitung angebunden werden, und so weiter..


V.


----------



## Rainer Hönle (5 April 2010)

Wie groß ist das genaue Mengengerüst? 100000 Variablen pro Tag insgesamt oder 100000 Zeilen pro Tag und SPS? Müssen die Daten aller SPSen in eine Tabelle? Sind die Datensätze der SPSen alle gleich aufgebaut?
Bei großen Datenmengen ist Excel tatsächlich nicht das Produkt der Wahl.

<Werbung>
Wenn es etwas Fertiges sein darf, dann ist eventuell ACCON-S7-EasyLog eine Alternative. Hier einfach die gewünschten Daten parametrieren und bei Bedarf die Dateien in für Excel verträgliche Häppchen aufsplitten lassen. Als Ausgabedatei wird eine CVS-Datei erstellt. Es können bis zu 16 Konfigurationen (= 16 SPSen) parallel gestartet werden. Normalerweise loggt jede SPS in eine eigene Datei, bei identischem Satz-Aufbau ist aber sicher auch eine einzige Datei denkbar. Zusätzlich sollte dann allerdings eine "Konstante" mitprotokolliert werden, die die SPS identifiziert.
</Werbung>


----------



## extruder_luder (5 April 2010)

Hallo,

danke für die Tips.

Ich werde nur einen Rechner haben, der auf die SPS'sen zugreift.
100000 Einträge am Tag, aber jeder nur ein paar Byte lang. Das habe ich natürlich schon mit Excel ausprobiert. Die Datei ist ca. 2MB lang, also nicht so wild. Die Daten werden täglich an diverse Leute per E-mail verschickt. Dann wird eine neue Datei erstellt. Nach 2 Monaten fallen die Daten hinten raus. Ist also alles nicht wirklich tragisch und sollte mit Excel problemlos machbar sein, habe ich jedenfalls gedacht. 

Kann ACCON S7 E-mails verschicken ?

Wenn die Sache funktioniert hat, melde ich wieder.

Gruss

Oliver


----------



## Rainer Hönle (5 April 2010)

ACCON-S7-EasyLog verschickt keine E-Mails sondern schreibt nur die Daten in eine CSV-Datei. 
Je nach Excel-Version gibt es allerdings Beschränkungen (z.B. 255 Spalten, 65535 Zeilen), mehr geht (zumindest in den älteren Versionen nicht).

Sind die 100000 Einträge immer eine Variable oder werden mehrere Variablen in eine Zeile geschrieben? Haben alle SPSen dieselben Variablen oder warum sollen die Daten alle in eine Excel-Tabelle? Oder kommen diese in eigene Spalten je nach SPS?


----------



## BPlagens (6 April 2010)

Also bei mir geht 


> ItemId = "S7:[3_head]DB1,W0,2


 
Wenn ich 
	
	



```
[FONT=Arial]S7:[3_head]DB1,INT0,2[/FONT]
```
benutze ohne Probleme!

Du solltest dir mal das Aussehen der Tagsyntax mit dem OPC Scout von Siemens ansehen!

Ach ja noch ein gut gemeinter Rat stelle in der Konfig vom OPC Server unbedingt "Verbindung permanent aufrecht halten" ein!
Und vergiss nicht die ErrorID und Quality auszuwerten!

Werf mal ein Blick auf die Siemens Beispiele (ich glaube unter C:\siemens\simatic.net\opc\example) da ist auch eine Beispiel mit einer Klartextmeldung der Quality dabei.

Hier mal der Code der das Liefert was du willst:


```
Private Sub cmdReadVar_Click()
    Dim myValue As Variant 'hier schreibt DatCon1 den Wert der Variable rein
    Dim myQuality As Long 'hier schreibt DatCon1 einen Wert für die Qualität des Tags rein (muss 192 sein)
    Dim myTimeStamp As Date 'hier schreibt DatCon1 den TimeStamp des Tags rein
    Dim ErrorNr As Long 'Rückgabewert des Aufrufes (muss 0) sein
    Dim ItemID As String 'hier übergeben wir die Tag-Adresse
 
    On Error GoTo ErrorHandler
 
   'bitte mit OPC Scout von Siemens die Richtige Bezeichnung ablesen!
    ItemID = "Test.DB21,INT0,3"
 
    'Und aufrufen
    ErrorNr = DatCon1.ReadVariable(ItemID, myValue, myQuality, myTimeStamp)
 
    'hier muss geprüft werden ob ErrorNr=0 und myQuality(x)=192 !!!
    'wenn nicht, hat das lesen nicht geklappt!
    txtWert1 = CStr(myValue(0))
    txtWert2 = CStr(myValue(1))
    txtWert3 = CStr(myValue(2))
    Exit Sub
 
ErrorHandler:
    MsgBox Err.Description
End Sub
```


----------



## extruder_luder (12 April 2010)

Hallo,

es funktioniert jetzt soweit.
Gebracht hat es die Siemens Funktion:

Function TwoByteToInt(ByVal LoByte As Byte, _
         ByVal HiByte As Byte) As Integer
'Check if HiByte is 0
  If (HiByte And &H80) <> 0 Then
   TwoByteToInt = ((HiByte * 256&) + LoByte) Or &HFFFF0000
  Else
   TwoByteToInt = (HiByte * 256) + LoByte
  End If
  End Function

Ohne die bekam ich die dollsten Fehlermeldungen, wenn ich auf die gelesenen Variablen zugreifen wollte. Durch die Formatkonvertierung klappt es jetzt.

Nun habe ich aber noch ein Problem:
Ich lese die Daten der SPS'sen zyklisch jede Sekunde. Kein Problem. Ziehe ich aber nun den MPI-Stecker ab, so versucht das OPC control ca. 10 Sekunden land auf das OPC Item zuzugreifen, bevor es in den Timeout geht.
Kann man diese Zeit irgendwo einstellen ?
Mit einem vom OPC control erzeugten Ereignis möchte ich nicht arbeiten, da ich auch protokollieren will, ob die CPU's erreichbar sind.


Gruss

Oliver


----------



## BPlagens (12 April 2010)

Ach je - du machst es aber einem nicht leicht dir zu helfen!

Einmal sprichst du von





> ItemId = "S7:[3_head]DB1,W0,2


Jetzt von 





> TwoByteToInt


Warum machst du denn nicht was man dir sagt?


> S7:[3_head]DB1,INT0,2


Du willst doch einen Integer-Wert! Warum also mehrere Byte lesen um dann daraus wieder ein Integer zu machen?

Dann könntest du dir das ganze zusammen basteln deiner Werte sparen!

Aber zu deinem neuen Problem:


> Mit einem vom OPC control erzeugten Ereignis möchte ich nicht arbeiten, da ich auch protokollieren will, ob die CPU's erreichbar sind.


Verstehe ich zwar nicht - genau dafür ist das Ereignis ja da! Wenn es auftritt entsprechend darauf reagieren - sprich Protokoll erstellen!

Die Zeit hat nichts mit der Control zu tun, sondern wird vom OPC-Server bestimmt! (Schau mal in NetPro unter den Eigenschaften deiner Verbindung nach Stichwort "Auftrags-Timeout" und wenn du schon in der Maske bist: "Die Verbindung permanent aufrecht erhalten" anklicken!)

Es gibt für jede Verbindung eine System-Variable die dir den Zustand der Verbindung anzeigt (Bei Inat "Status" bei Siemens &statepathval)

Hier der Auszug der Doku:





> &statepathval()
> Zustand einer Kommunikationsverbindung zu einem Partnergerät.
> Rückgabewerte:
> 1
> ...


Also könntest du bevor du zyklisch liest immer erst &statepathval auswerten! Wenn <> 2 dann macht lesen eh keinen Sinn!

Syntax:"S7:[3_head]&statepathval()"


----------



## extruder_luder (12 April 2010)

Hallo BPlagens,

Du hast recht, ich möchte 16 Bit auslesen.
Da ich aber immer die Fehlermeldung"VB unterstützt diese Art der Variablen aus der Automatisierung nicht" bekommen habe, ging es nicht anders. Ob das an Excel 2007 VBA oder was auch immer liegt, weiss ich nicht und habe darauf auch keine Antwort bekommen.
Da es mit dem Byte Zugriff funktioniert und ich überhaupt keine Zeit habe, nehme ich diesen, ist letztenendes auch egal.

Vielen Dank für den Tip mit der Abfrage :"S7:[3_head]&statepathval()" 

Vielleicht kann ich mich mal revanchieren.

Gruss


----------



## extruder_luder (13 April 2010)

Hallo nochmal BPlagens,

ich weiss das ich nerve, aber ich baue das erste Mal einen OPC Client mit Excel.
Ich würde gerne Deinem Tip mit dem Statepathval folgen.
Du hast ja auch schon die Syntax geschrieben, ich weiss aber trotzdem nicht wie ich das machen soll.

"S7:[3_head]&statepathval()"  ist ja in Anführungszeichen und damit ein String.

Was soll ich damit machen?

Ich wäre unglaublich dankbar für ein kleines Beispiel.

z.B:

dim test as variant ?????

test = "S7:[3_head]&statepathval()"

So ist test natürlich nur der String.

oder wie funktionierts?

Hab die Siemens Doku gelesen, finde aber keine richtige Antwort.

Wäre toll, wenn Du nochmal hilfst.

Gruss

Oliver


----------



## BPlagens (13 April 2010)

Ist ganz einfach!

Es geht genau so wie du jetzt deine Tags liest!


> ItemId = "S7:[3_head]DB1,W0,2
> ReturnValue = UserForm1.DatCon1.ReadVariable(ItemId, Value, Quality, Timestamp)


Nur das ItemId="S7:[3_head]&statepath()" lautet.
Mit "ReturnValue = DatCon1.ReadVariable(ItemId, Value, Quality, Timestamp)" liest du dann den Tag vom OPC Server (ist eben nur ein "System-Tag" der nicht aus der SPS kommt).

Dann hat Value eben den Wert 1,2 oder 3!
Value ist vom Type Byte!

Mach gleich mal ein Beispiel!
Nachtrag: Hier das Beispiel: 

```
Private Sub cmdStatepath_Click()
    Dim myValue(1) As Variant 'hier schreibt DatCon1 den Wert der Variable rein
    Dim myQuality(1) As Long 'hier schreibt DatCon1 einen Wert für die Qualität des Tags rein (muss 192 sein)
    Dim myTimeStamp(1) As Date 'hier schreibt DatCon1 den TimeStamp des Tags rein
    Dim ErrorNr(1) As Long 'Rückgabewert des Aufrufes (muss 0) sein
    Dim ItemID(1) As String 'hier übergeben wir die Tag-Adresse
    
    On Error GoTo ErrorHandler
    
    ItemID(1) = "S7:[3_head]&statepathval()"
       
    'Und aufrufen
    ErrorNr(1) = DatCon1.ReadVariable(ItemID(1), myValue(1), myQuality(1), myTimeStamp(1))
   
    Select Case myValue(1)
        Case 1
            MsgBox "Verbindung ist nicht aufgebaut!"
        Case 2
            MsgBox "Verbindung ist aufgebaut!"
            'Hier könnte dann das Lesen der eigentlichen Tags erfolgen
        Case 3
            MsgBox "Verbindung wird aufgebaut!"
        Case Else
            MsgBox "Status unbekannt!"
            
    End Select
     
    Exit Sub
    
ErrorHandler:
    MsgBox Err.Description

End Sub
```


----------



## extruder_luder (13 April 2010)

Hallo BPlagens,

Du bist echt ne Bank,
Unglaublich tolle Hilfe.

Danke

Oliver


----------



## BPlagens (13 April 2010)

dafür gibt es ja dieses Forum!

Viel Erfolg!


----------



## Dr. OPC (23 April 2010)

Ich las gerade folgende Zeilen:



> 'ItemId = "S7:[3_head]DB1,W0"  // auskommentiert , funktioniert
> ItemId = "S7:[3_head]DB1,W0,2"  //  hier möchte ich einfach mal 2 Variablen gleichzeitig lesen
> ReturnValue = UserForm1.DatCon1.ReadVariable(ItemId, Value, Quality, Timestamp)
> Valuelong = CLng(Value(1)) // hier möcht ich den Inhalt einer Variablen lesen, dabei kommt es zur Fehlermeldung "VB unterstützt diesen Typ nicht



Das funktionierte nicht weil "W0,2" nicht bedeutet das man "2 Variablen gleichzeitig liest" sondern EINE Variable, die vom Typ ARRAY ist und 2 Elemente besitzt.
Daher funktioniert auch der Cast mit CLng nicht, denn das Array kann nicht in einen Long gewandelt werden.

Das wollte ich nur mal angemerkt haben. Dann könnte auch die wilde Konvertiererei wegfallen. 

Der Grund für den Wahnsin scheint gewesen zu sein, dass der ReadMulti nicht ging (übrigens aus genau dem selben Grund wie oben geschildert). Es kommt ein Value-Array zurück in dessen ersten Element ein "Word" (von DB1,W0) stand und im zweiten Element war ein "ArrayofWord" (von DB1,W0,2). Das zweite Item hätte einfach nur "DB1,W2" heissen müssen und es wäre gegangen.

Abschließen möchte ich erwähnen dass der "Multi-Zugriff" IMMER zu bevorzugen ist. Ein "Read-Single" (also auf nur 1 Item) dass dann allerdings ein Array mit 500 Elementen ist, geht natürlich auch, zieht aber ein "zerbröseln" im Client nach sich. Weiterhin wird dem OPC Server die Chance genommen die Zugriff zu optimieren. Deshalb IMMER Multi-Zugriffe.


----------

