Hallo,
ich möchte aus meiner Datenbank heraus externe Daten abfragen und übernehmen. Dazu habe ich einige Fragen zum allgemeinen Ablauf.
Hier erst einmal der Code:
Option Compare Database
Option Explicit
Private Sub Form_Current()
Dim sTag As String
Dim dtTime As Date
Dim vValue As Variant
Dim Cn As New ADODB.Connection
Dim Cmd As New ADODB.Command
Dim RS As New ADODB.Recordset
Set Cn = New ADODB.Connection
Set Cmd = New ADODB.Command
Set RS = New ADODB.Recordset
Cn.ConnectionString = "Provider = PIOLEDB; Data Source = pi-abcdef; User ID = xyz; Password =xyz "
Cn.Open
Cmd.ActiveConnection = Cn
Cmd.CommandText = "SELECT tag, time, value from piarchive..pisnapshot WHERE tag IN ('Wert1', 'Wert2')"
Set RS = Cmd.Execute
RS.MoveFirst
While Not RS.EOF
sTag = RS.Fields("TAG").Value
dtTime = RS.Fields("TIME").Value
vValue = RS.Fields("VALUE").Value
Debug.Print sTag, dtTime, vValue 'zum Testen der Werte
RS.MoveNext
Wend
RS.Close
Cn.Close
End Sub
Ich müßte ca. 80 Werte abfragen. Die Frage wäre: Wie löse ich es am Besten mit der Abfrage der 80 Werte? Ich könnte ja alle der Reihe nach eintragen. Also ungefähr so: Select .....('Wert1', 'Wert2', .......'Wert80'). Da gibt es doch sicherlich eine elegantere Lösung, oder?
Die zweite Sache wäre jetzt die Werte in eine Tabelle schreiben. Aber bevor die Daten in die Tabelle geschrieben werden, sollen eventuell vorhandene Daten in der Tabelle gelöscht werden.
Wenn ich folgenden Code verwende...
With CurrentDb().OpenRecordset ("tblDaten", dbOpenDynaset, dbAppendOnly)
.AddNew
!sTag = sTag
!Zeitstempel = dtTime
!Wert = vValue
.Update
End With
...und diesen vor RS.MoveNext einfüge, dann schreibe ich zwar Daten in die Tabelle aber immer nur einen Wert.
Ich hoffe einer kann mir hier mal weiterhelfen. Vielen Dank.....
mfg Pjo12345
Hallo,
"Ich müßte ca. 80 Werte abfragen."
Damit meinst Du, alle Datensätze auslesen, bei denen der Wert in "tag" mit irgendeinem Wert in der "IN-Liste" übereinstimmt?
"Da gibt es doch sicherlich eine elegantere Lösung, oder?"
semantisch nein, syntaktisch könnte die Liste per VBA zusammengesetzt werden. Dabei erhebt sich die Frage, woher die Werte in der "IN-Liste" kommen.
"Aber bevor die Daten in die Tabelle geschrieben werden, sollen eventuell vorhandene Daten in der Tabelle gelöscht werden."
naja, dann tu das... (z. B, mit einer Lösch-Abfrage)
"...aber immer nur einen Wert."
der Code besitzt ja auch keine "Schleife", die für das Schreiben mehrerer Datensätze sorgen könnte..
(btw: Auf die Namen "Tag" , "Time" und "Value" dringend verzichten, weil es sich dabei um ein reservierte Wörter handelt.)
Also die Daten in der IN-Liste muß ich von Hand vorgeben (Kennziffern bestimmter Meßstellen im Prozeßleitsystem).
Keine Schleife in meinem Code? Ich dachte, dass das so gehen würde:
RS.MoveFirst
While Not RS.EOF
sTag = RS.Fields("TAG").Value
dtTime = RS.Fields("TIME").Value
vValue = RS.Fields("VALUE").Value
Debug.Print sTag, dtTime, vValue 'zum Testen der Werte
With CurrentDb().OpenRecordset ("tblDaten", dbOpenDynaset, dbAppendOnly)
.AddNew
!sTag = sTag
!Zeitstempel = dtTime
!Wert = vValue
.Update
End With
RS.MoveNext
Wend
Access müsste doch eigentlich die While Wend Anweisungen solange durchlaufen bis EOF erreicht ist. Aber hier tut sich auch schon ein Problem auf. Irgendwie scheint die Anweisung RS.MoveFirst wirkungslos zu sein. Ich habe die ganze Sache mal getestet. Egal ob mit oder ohne RS.MoveFirst, es kommt immer das gleiche Ergebnis raus. Und zwar habe ich in meiner IN-Liste zum Testen drei Werte (Wert1, Wert2, Wert3). In der Ausgabe erscheint aber Wert3 danach Wert1 und Wert2 verdunstet im Nirvana. Ist denn generell etwas falsch an der Herangehensweise?
mfg Pjo12345
Hallo,
der "addnew"-Code stand ja nun zusammenhanglos im Raum...
"Ist denn generell etwas falsch an der Herangehensweise?"
ich denke ja...
Du beziehst Dich immer auf die (festen) Kriterienwerte (Wert1, Wert2, Wert3), die in die Tabelle geschrieben werden sollen (so ich Dich richtig verstehe).
Diese werden aber nur dazu verwendet, um passende DS aus der Tabelle zu filtern. Wenn es nun keine passenden gibt, oder wie im vorliegenden Fall (vermutlich) nur einen, dann kann auch keiner (bzw. der eine gefundene) in die Tabelle "tblDaten" geschrieben werden.
"Ich müßte ca. 80 Werte abfragen."
Diese Aussage ist an sich falsch formuliert. Es werden Werte (d. h. Datensätze) abgefragt (d. h. in den Recordset geladen) , bei denen der Wert in "TAG" mit einem Wert in der "IN-Liste" übereinstimmt. (Dabei muß lt. der Syntax das Tabellenfeld "TAG" den Datentyp TEXT aufweisen.
Druck mal die Anzahl der RS-Datensätze und die aktuelle RS-Cursor-Position im Direktfenster aus:
.
.
Set RS = Cmd.Execute
RS.Movelast
RS.MoveFirst
Debug.Print "Anzahl:" & RS.Recordcount & " ; Aktueller DS: " & RS.Absoluteposition
While Not RS.EOF
.
.
Also mit den Kriterienwerten filtere ich meine DS aus der Tabelle. Das stimmt. Ich glaube, dass ich hier einen Denkfehler hatte. Ich war der Meinung, die Kriterienwerte werden seriell abgearbeitet. Das scheint ja nicht so zu sein. Daher auch die "verkehrte" Reihenfolge. Den Rest werde ich heute Nacht mal probieren.
Bei: Debug.Print "Anzahl:" & RS.Recordcount & " ; Aktueller DS: " & RS.Absoluteposition erhalte ich -1 und -1. :-\
Alle Werte werden jetzt auch in die Tabelle geschrieben. Na mal sehen wie es weiter geht.
mfg Pjo12345