# Frage zu Libnodave und VB



## delphie (26 Oktober 2005)

Hallo!
Habe jetzt endlich mal Zottels Libnodave ausprobiert und muß sagen das klapte ja alles leichter als gedacht.
Ich lese damit  3 S7-DBs mit Produktionsstückzahlen über Ethernet in eine Exel Tabelle.
Leider knobel ich jetzt schon eine ganze Weile an den Feinheiten am Makro rum und komme nicht weiter.
Problem 1:
Im DB sind die Werte als Int
Lese ich sie als integer dann sind die Words um ein Byte verschoben.
Die Zahlen sind damit falsch.
Jetzt lese ich sie Byte weise als Byte1$ und Byte2$ und stelle sie in Exel dann als Byte2$+Byte1$ dar. Dann stimmen die Zahlen.
Wo läst sich die Startposition festlegen ab wo ich lesen möchte oder muß es der ganze DB sein?
Wenn ich als integer lese und bpos-1 oder bpos+1 rechne liest er ja nicht ein byte zurück sondern ein ganzes word.

Problem 2:
Die Werte sind in hex und ich möchte sie ohne die exel Funktionen gleich aus dem Makro in dec wandeln. Oder noch besser in dec lesen. Geht das?

Problem 3:
Wenn ich die DB Länge für die Anzahl der For-Next-Schleifen Durchläufe benutze in der die bpos erhöht wird kommen nur ca 25 Werte in der Tabelle an.
Benutze ich Konstante Zahlen z.B. 200 dann kommen auch 200 Werte in die Tabelle.
Die DB Länge wird als long bzw dword gelesen wie im Beispiel-Makro.
Woran kann das liegen?

Danke schonmal im vorraus:


----------



## seeba (26 Oktober 2005)

Wenn ich z.B. einen DB mit readBytes lese und als Länge 16 angebe, werden 8 Wörter gelesen. Danach führ ich dann 8 mal getU16 in eine jeweils andere Variable aus und schon hab ich die ersten 8 Wörter als Word/Integer ohne Vorzeichen! Dein Problem kann ich leider nicht nachvollziehen!

*Gruß Sebastian*


----------



## delphie (26 Oktober 2005)

:?:  Versteh ich nicht. ??
Wenns geht nochmal für Anfänger zum mitschreiben!
readbytes habe ich nicht verwendet sondern das beispiel Makro getprogramblock etwas geändert. Habe mit VB nicht sonderlich viel Erfahrung.
Klar sonst würd ich hier ja nicht Fragen.
Vieleicht am Beispiel.
Hier mein Quellcode:

Sub lesen db50()
Dim ph As Long, di As Long, dc As Long, buffer(5000) As Byte, length As Long
res = initialize(ph, di, dc)
If res = 0 Then
    res = daveGetProgramBlock(dc, Asc("A"), 50, buffer(0), length)
    bpos = 0
    For i = 0 To 200
        byte1$ = ""
        byte2$ = ""
        byte1$ = byte1$ + Hex$(buffer(bpos)) + ","
        bpos = bpos + 1
        byte2$ = byte2$ + Hex$(buffer(bpos)) + ","
        bpos = bpos + 1
        Cells(i,1) = byte1$+byte2$
    Next i
End If
Call cleanUp(ph, di, dc)
End Sub

An stelle von daveGetProgramBlock vieleicht daveGetU16 verwenden und dann buffer(2500) As Integer ???
Geht das mit dem 1 byte versetzt lesen wenn ich 
res = daveGetProgramBlock(dc, Asc("A"), 50, buffer(1), length)
schreibe?


----------



## seeba (26 Oktober 2005)

delphie schrieb:
			
		

> :?:  Versteh ich nicht. ??
> Wenns geht nochmal für Anfänger zum mitschreiben!
> readbytes habe ich nicht verwendet sondern das beispiel Makro getprogramblock etwas geändert. Habe mit VB nicht sonderlich viel Erfahrung.
> Klar sonst würd ich hier ja nicht Fragen.
> ...



Mit VBA kenn ich mich nicht aus... Aber ist da jetzt getProgrammBlock das selbe wie readBytes?


----------



## delphie (26 Oktober 2005)

Ich glaube es wird erst der ganze Baustein in den Buffer gelesen unabhängig davon wie viele Bytes ich auswerte.
Bin mir aber nicht sicher.
Weil wenn ich die Buffergröße kleiner stelle als der Baustein groß ist dann bekomme ich ja einen Fehler.
Was ist mit daveGetU16from(buffer(0)) kanns damit funktionieren wenn ich die Bytes bzw words direkt lese?
Ist bei buffer(x) ,  x die byteposition?
Ich hoffe mal Großmeister Zottel schaut heute noch persönlich hier vorbei damit ich nächste Nacht weiter basteln kann. 
So viele Fragen.
Vieleicht sollte mal jemand ein Buch schreiben "Libnodave leicht gemacht" oder so!


----------



## seeba (26 Oktober 2005)

delphie schrieb:
			
		

> Ich glaube es wird erst der ganze Baustein in den Buffer gelesen unabhängig davon wie viele Bytes ich auswerte.
> Bin mir aber nicht sicher.
> Weil wenn ich die Buffergröße kleiner stelle als der Baustein groß ist dann bekomme ich ja einen Fehler.
> Was ist mit daveGetU16from(buffer(0)) kanns damit funktionieren wenn ich die Bytes bzw words direkt lese?
> ...


naja nehm halt den Befehl daveReadBytes und werte dieses Ergebnis dann mit getU16 usw. aus! Du kannst mir auch gern mal deine Excel-Mappe zumailen oder so.


----------



## delphie (26 Oktober 2005)

Ich versuche mal daveReadBytes.
Vieleicht hat ja mal jemand ein kleines Beispiel an dem ich basteln kann.


----------



## Zottel (26 Oktober 2005)

delphie schrieb:
			
		

> Ich glaube es wird erst der ganze Baustein in den Buffer gelesen unabhängig davon wie viele Bytes ich auswerte.
> Bin mir aber nicht sicher.
> Weil wenn ich die Buffergröße kleiner stelle als der Baustein groß ist dann bekomme ich ja einen Fehler.
> Was ist mit daveGetU16from(buffer(0)) kanns damit funktionieren wenn ich die Bytes bzw words direkt lese?
> ...


Jetzt will ich nicht alles gründlich lesen. daveReadBytes ist das was ihr braucht. getProgramBlock braucht ihr nur, wenn ihr so was wie eine eigene Programmiersoftware oder ein Archivierungstool für Programmbausteine bauen wollt.
Da DBs in Step7 auch unter "Bausteine" auftauchen, kann man sie eben auch mit getProgramBlock auslesen, bekommt aber nicht nur Daten, sondern auch die Kopfinformation der Bausteine. Was die bedeutet, ist auch mir weitgehend unbekannt.
daveReadBytes(dc, daveDB, 6, 14, 23, puf)
würde 23 Byte ab DB6.DBB14 in den Puffer puf und in den INTERNEN Puffer lesen.
getU16 holt zwei Bytes aus dem INTERNEN Puffer und wandelt sie in eine Zahl als ob sie eine 16-bit-Wort ohne Vorzeicehen wären. 
Dabei wird eine interne Leseposition um 2 erhöht. Sie zeigt also danach auf die Kopie von DB6.DBB16.
Nun mag es Fälle geben, wo man nicht alles der Reihe nach aus dem Puffer holen will.
Dann kann man mit daveGetXXXAt(<position>) die Position im INTERNEN Puffer selbst angeben. Die interne Leseposition ändert sich dabei nicht.
Oder man möchte aus einem EIGENEN Puffer lesen, den man an daveReadBytes übergeben hat, also aus Puf.
Dazu dient: daveGetXXXfrom(puf(position))
Eine interne Leseposition gibt es dabei nicht.


----------



## lorenz2512 (26 Oktober 2005)

Hallo,
hier mal ein Ausschnitt aus dem Lesen Code:
Private Sub CommandButton3_Click()
Range("A3:b100").Select
    Selection.ClearContents
    CommandButton3.Select

xanz = ((TextBox2 - TextBox1) / 2)
Dim ph As Long, di As Long, dc As Long
res = initialize(ph, di, dc)
For i = 0 To xanz
If res = 0 Then
    res2 = daveReadBytes(dc, daveDB, 1, TextBox1 + (i * 2), 2, 0)

    If res2 = 0 Then
        v1 = daveGetS16(dc)
    Cells(3, 2).Offset(i, 0) = v1
    nr = TextBox1 + (i * 2)
    Cells(3, 1).Offset(i, 0) = nr


End If
End If
Next i
Call cleanUp(ph, di, dc)
End Sub

damit lese ich aus DB1 die Wörter von Textbox1 bis Textbox2
, ganz fertig bin ich noch nicht mit dem Schreiben, aber das Lesen haut hin und schreibt mir in die erste Zeile die VW's (ist halt eine 200er CPU) und in die 2. die Werte. Und das sieht fertig so aus(mußt registriert sein um das Bild sehen zu können)
:


----------



## delphie (26 Oktober 2005)

Danke alle zusammen.
Hat mir sehr weiter geholfen.


----------

