Anzeige

 Zugriff auf Daten aus Abfrage


#1
Hallo zusammen,

leider habe ich trotz intensiver Suche nichts finden können :(

Bin ganz neu in dem Thema und baue für meine Firma eine Access Datenbank.
Nun möchte ich, dass wenn ein Button auf dem Formular gedrückt wird, Word geöffnet und mit Daten einer Abfrage gefüllt wird.
Ich habe das ganze bereits für ein anderes Word Dokument zum laufen bekommen. Da ist es aber so, dass die benötigten Daten auf dem aktuellen Formular Datensatz zu finden sind und ich dadurch mich "me.Feldname" arbeiten kann.

Für euch ist es wahrscheinlich ein Klacks.

Code:
Function fillVHP()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String


On Error Resume Next
Error.Clear
Path = "Z:\01. Verwaltung\Neuaufnahme-Mappe\Vorlagen neue Patientenmappe\Antrag Verhinderungspflege_Stand_20171128.docx"
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Set doc = appword.Documents.Open(Path, , True)

With doc
    .Formfields("txtPK").Result = [I]berichtkv.Name1[/I]
    .Formfields("txtStrasse").Result = [I]berichtkv.Strasse[/I]
    .Formfields("txtPlz").Result = [I]berichtkv.PLZ[/I]
    .Formfields("txtOrt").Result = [I]berichtkv.Ort[/I]
End With
appword.Visible = True
appword.Activate
Set doc = Nothing
Set appword = Nothing
End Function
Aus der Abfrage "berichtkv" sollen die oben aufgeführten Felder verwendet werden. Bei Klick auf den Button bleiben die Textfelder in Word leider leer. Ersetze ich "berichtkv.Name1" durch "Hallo", öffnet sich Word auch mit "Hallo".
Also ist wahrscheinlich nur mein Syntax für den Zugriff falsch.

Kann mir jemand helfen?

Gruß
 
#4
Ist das die Abfrage selber oder ein QueryDef oder Recordset Objekt in VBA?
Ich gehe mal vom ersteren aus.
Dann fehlt dir das folgende
Visual Basic:
Dim rs As Recordset
Dim sql As String

'Als Beispiel mit ein Filter auf die ID:
sql = "SELECT * FROM berichtkv WHERE id = " & mySelectedId
'Recordset öffnen
Set rs = CurrentDb.openRecordset(SQL)
rs.moveFirst

'Felder auslesen
.Formfields("txtPK").Result = rs!Name1

'Recordset schliessen
rs.Close
 
#5
Vielen Dank für die schnelle Antwort!

Das ist die Abfrage selber, welche man in der normalen Access Oberfläche erstellt.
Die Abfrage liefert zur Zeit nur den Datensatz welcher die im Formular gewählte ID beinhaltet.

Ich habe den Code wie von dir vorgeschlagen angepasst.
Er meckert nun beim Ausführen wie folgt: "1 Parameter wurde erwartet, aber es wurden zu wenig Parameter übergeben" Markiert wird dabei die Zeile

Code:
Function fillVHP()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
Dim rs As Recordset
Dim sql As String


sql = "Select * From berichtkv"
Set rs = CurrentDb.OpenRecordset(sql)
rs.MoveFirst

On Error Resume Next
Error.Clear
Path = "Z:\01. Verwaltung\Neuaufnahme-Mappe\Vorlagen neue Patientenmappe\Antrag Verhinderungspflege_Stand_20171128.docx"
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Set doc = appword.Documents.Open(Path, , True)

With doc
    .Formfields("txtPK").Result = rs!Name1
    .Formfields("txtStrasse").Result = rs!Strasse
    .Formfields("txtPlz").Result = rs!PLZ
    .Formfields("txtOrt").Result = rs!Ort
End With
rs.Close

appword.Visible = True
appword.Activate
Set doc = Nothing
Set appword = Nothing
End Function
 
#6
Klingt nach einem Klassiker
Wenn du deine Abfrage berichtkv von Hand öffnest. Kommt da die Frage nach einem Wert?
Ist das Formular, auf dass die Abfrage zugreift offen?

Grundsätzlich sollte man keine Abfragen machen, die auf Formularfelder zugreifen. Ist immer etwas wacklig.
 
#7
Guten Morgen!

ja wenn ich die Abfrage von Hand öffne, fragt er nach einem Wert. Ich habe diese Bedingung jetzt entfernt und dafür in die SQL Abfrage eingefügt.
Leider bleibt die Problematik die gleiche. Wenn ich Die Funktion ohne Bedingung im SQL Teil ausführe, öffnet er Word mit den Daten des ersten Datensatzes der Abfrage. Wie kann ich nun abfragen dass er den Datensatz nimmt der im Formular gewählt wird? Weil folgendes funktioniert nicht:

Code:
Function fillVHP()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
Dim rs As Recordset
Dim sql As String


sql = "Select * From berichtkv Where KlientenNr = Me.KlientenNr"
Set rs = CurrentDb.OpenRecordset(sql)
rs.MoveFirst

On Error Resume Next
Error.Clear
Path = "Z:\01. Verwaltung\Neuaufnahme-Mappe\Vorlagen neue Patientenmappe\Antrag Verhinderungspflege_Stand_20171128.docx"
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Set doc = appword.Documents.Open(Path, , True)

With doc
    .Formfields("txtPK").Result = rs!Name1
    .Formfields("txtStrasse").Result = rs!Strasse
    .Formfields("txtPlz").Result = rs!PLZ
    .Formfields("txtOrt").Result = rs!Ort
End With
rs.Close

appword.Visible = True
appword.Activate
Set doc = Nothing
Set appword = Nothing
End Function
Gruß
 
#9
SQL:
SELECT dbo_Klient.KlientenNr, dbo_Klient.Nachname, dbo_Klient.Vorname, dbo_Klient.Strasse, dbo_Klient.PLZ, dbo_Klient.Ort, dbo_Klient.VersichertenNr, dbo_Kostentr.Name1, dbo_Kostentr.Strasse, dbo_Kostentr.PLZ, dbo_Kostentr.Ort, dbo_Kostentr.KostentrTypID
FROM dbo_Kostentr INNER JOIN (dbo_Klient INNER JOIN dbo_KlientKostentr ON dbo_Klient.KlientID = dbo_KlientKostentr.KlientID) ON dbo_Kostentr.KostentrID = dbo_KlientKostentr.KostentrID
WHERE (((dbo_Kostentr.KostentrTypID)=2));
 

Biber3

Erfahrenes Mitglied
#10
Moin Alex777,

du ziehst in deinem Resultset mehrere Felder mit gleichem Namen an (Strasse, PLZ, Ort jeweils aus zwei unterschiedlichen Tabellen).
Sorg dafür, dass jeder Feldalias nur 1x vorhanden ist, dann kann auch ein rs!Strasse oder Rs!ort eindeutig aufgelöst werden.

Also
SQL:
SELECT ...
     , dbo_Kostentr.Strasse as KostenTr_Str
     , dbo_Kostentr.PLZ as KostenTr_PLZ
     , dbo_Kostentr.Ort as KostenTr_Ort
...
Oder besser noch: hol dir nur die Felder, die du auch brauchst.

Grüße
Biber
 
#11
Alles klar. Nimm den WHERE wieder aus der Abfrage heraus.
Dann öffnest du im VBA die Abfrage als QueryDef und übergibst den Paramter.
Aus dem Querydef kannst du dann den Recordset öffnen und wie gewohnt damit weiterarbeiten

Hier ein Beispiel für die Abfrage myQuery und den Paramterwert 2
Visual Basic:
    Dim qry As QueryDef
    Dim rs As Recordset
    
    'Abfrage als QueryDef öffnen
    Set qry = CurrentDb.QueryDefs("myQuery")
    'Paramter übergeben
    qry.Parameters(0).value = 2
    'Recordset öffnen
    Set rs = qry.openRecordset
    
    '//TODO: Daten aus dem Recordset auswerten
    
    'Suaber abschliesen
    rs.Close
    qry.Close
 
#12
Okay, die Logik dahinter verstehe ich, es hängt glaube ich noch am Syntax.

Code:
Function fillVHP()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
Dim rs As Recordset
Dim qry As QueryDef

Set qry = CurrentDb.QueryDefs("berichtkv")
qry.Parameters("KlientenNr").Value = "Me.KlientenNr"

Set rs = qry.OpenRecordset
So nimmt er es auf jeden Fall noch nicht :(

Könnt ihr mir hier eigentlich ein gutes Tutorial oder Buch für VBA empfehlen? Habe die Vorzüge entdeckt und das Thema wird für mich zunehmend interessanter.
 
#13
Oh, ich kenne keine Bücher. ich hatte unter Access 2.0 mit der F1-Hilfe begonnen.

Aber du weisst dem Parameter einen String "Me.KlientenNr" zu und nicht den Wert des Feldes.
Probier es mal ohne die "
Visual Basic:
qry.Parameters("KlientenNr").Value = Me.KlientenNr
 
#14
Ne nimmt er leider nicht, er schreibt immer "Element in dieser Auflistung nicht gefunden" und markiert
Visual Basic:
qry.Parameters(KlientenNr).Value = Me.KlientenNr
habe auch schon:
Visual Basic:
qry.Parameters("KlientenNr").Value = Me.KlientenNr
versucht
 
#15
Hast du KlientenNr als Paramter in der Abfrage definiert?
Ansonsten, da du nur ein Parameter hast, kannst du über den Index zugreifen
Visual Basic:
qry.Parameters(0).Value = Me.KlientenNr
 

Biber3

Erfahrenes Mitglied
#16
Moin Yaslaw,

Hast du KlientenNr als Paramter in der Abfrage definiert?
An welcher Stelle deiner Schritt-für-Schritt Anleitung sollte er
a) das denn geahnt oder getan haben und
b) wo am Himmels Willen solte irgendein Parameter denn greifen, wenn dein vorletzter Tipp doch war "nimm die WHERE-Klausel raus" ;)

@Alex777
Wenn es bei dir jetzt eine gespeicherte Query "myQuery" gibt, dann muss in der ersten Zeile etwas stehen wie..
PARAMETERS KlientenNr as Long /* oder "as String" gemäß Datentyp */

Und es muss auch eine WHERE-Klausel geben, in der irgendein Tabellenfeld gegen den Wert dieses Parameters geprüft wird.

Es sei denn, ich bin im vollkommen falschen Film.

Grüße
Biber
 
#17
Stimmt. Mein Fehler. Heute muss Montag sein...
natürlich brauchst du den WHERE
SQL:
PARAMETERS KlientenNr As Long;
SELECT ...
FROM ...
WHERE dbo_Kostentr.KostentrTypID=[KlientenNr];
 
#18
Also jetzt bin ich komplett verwirrt :D :D

Meine Query "Berichtkv" lautet weiterhin wie folgt:

SQL:
SELECT dbo_Klient.KlientenNr, dbo_Klient.Nachname, dbo_Klient.Vorname, dbo_Klient.Strasse, dbo_Klient.PLZ, dbo_Klient.Ort, dbo_Klient.VersichertenNr, dbo_Kostentr.Name1, dbo_Kostentr.Strasse, dbo_Kostentr.PLZ, dbo_Kostentr.Ort, dbo_Kostentr.KostentrTypID
FROM dbo_Kostentr INNER JOIN (dbo_Klient INNER JOIN dbo_KlientKostentr ON dbo_Klient.KlientID = dbo_KlientKostentr.KlientID) ON dbo_Kostentr.KostentrID = dbo_KlientKostentr.KostentrID
WHERE (((dbo_Kostentr.KostentrTypID)=2));
Meine VBA Funktion lautet
Code:
Function fillVHP()
Dim appword As Word.Application
Dim doc As Word.Document
Dim Path As String
Dim rs As Recordset
Dim qry As QueryDef

Set qry = CurrentDb.QueryDefs("Berichtkv")
qry.Parameters(0).Value = Me.KlientenNr

Set rs = qry.OpenRecordset


On Error Resume Next
Error.Clear
Path = "Z:\01. Verwaltung\Neuaufnahme-Mappe\Vorlagen neue Patientenmappe\Antrag Verhinderungspflege_Stand_20171128.docx"
Set appword = GetObject(, "word.application")
If Err.Number <> 0 Then
Set appword = New Word.Application
appword.Visible = True
End If
Set doc = appword.Documents.Open(Path, , True)

With doc
    .Formfields("txtPK").Result = rs!Name1
    .Formfields("txtStrasse").Result = rs!Strasse
    .Formfields("txtPlz").Result = rs!PLZ
    .Formfields("txtOrt").Result = rs!Ort
End With
rs.Close
qry.Close

appword.Visible = True
appword.Activate
Set doc = Nothing
Set appword = Nothing
End Function
Muss die SQL Anweisung der eigentlichen Query geändert werden?
 

Biber3

Erfahrenes Mitglied
#19
Moin Alex777,

ich hoffe, ich bringe jetzt nicht zuviel Chaos in diesen Thread... ich versuch mal von deinem Ur-SELECT auszugehen

SQL:
SELECT dbo_Klient.KlientenNr
     , dbo_Klient.Nachname
     , dbo_Klient.Vorname
     , dbo_Klient.Strasse
     , dbo_Klient.PLZ
     , dbo_Klient.Ort
     , dbo_Klient.VersichertenNr
     , dbo_Kostentr.Name1
     , dbo_Kostentr.Strasse
     , dbo_Kostentr.PLZ
     , dbo_Kostentr.Ort
     , dbo_Kostentr.KostentrTypID
FROM dbo_Kostentr
 INNER JOIN (dbo_Klient INNER JOIN dbo_KlientKostentr ON dbo_Klient.KlientID = dbo_KlientKostentr.KlientID)
   ON dbo_Kostentr.KostentrID = dbo_KlientKostentr.KostentrID
WHERE (((dbo_Kostentr.KostentrTypID)=2));
Zu diesem SELECT hatte ich sinngemäß geschrieben:
"Hey, da sind die Felder Strasse, Ort und PLZ doppelt, das ist nicht so schlau."

Andere Baustelle war die Idee von Yaslaw:
Da sollte auch noch ein Parameter namens "KlientenNr" rein , um auf einen bestimmten Klienten filtern zu können.

Beides zusammen würde (ungetestet) führen zu einer geänderten Query:

SQL:
PARAMETERS KlientenNr as Long;
SELECT dbo_Klient.KlientenNr
     , dbo_Klient.Nachname
     , dbo_Klient.Vorname
     , dbo_Klient.Strasse
     , dbo_Klient.PLZ
     , dbo_Klient.Ort
     , dbo_Klient.VersichertenNr
     , dbo_Kostentr.Name1
     , dbo_Kostentr.Strasse AS KostTR_Strasse
     , dbo_Kostentr.PLZ AS KostTr_PLZ
     , dbo_Kostentr.Ort AS KostTr_Ort
     , dbo_Kostentr.KostentrTypID
FROM dbo_Kostentr
 INNER JOIN (dbo_Klient INNER JOIN dbo_KlientKostentr ON dbo_Klient.KlientID = dbo_KlientKostentr.KlientID)
   ON dbo_Kostentr.KostentrID = dbo_KlientKostentr.KostentrID
WHERE dbo_Kostentr.KostentrTypID)=2
AND dbo_Klient.KlientenNr =[KlientenNr]
In deinem VBA ändert sich nix (so weit ich sehe), du kannst da wie Yaslaw schreiben:
qry.Parameters(0).Value = Me.KlientenNr ' (wie jetzt)

...oder, wie ich es schreiben würde
qry!KlientenNr = Me.KlientenNr

Und dann sollte es fliegen.

Grüße
Biber
 
#20
Ah okay, jetzt sehe ich wieder klarer :D

Bei
Code:
PARAMETERS KlientenNr AS Long;
sagt er immer "Syntaxfehler in PARAMETER-Klausel"

Zum Verständnis, am Ende wird ja auf KlientenNr abgefragt.. Wo ist in dieser Abfrage die Verbindung zu dem auf dem Formular gewählten Datensatz? Also wie bekommt die Variable KlientenNr den Wert aus dem Formular?
 
Zuletzt bearbeitet:
Anzeige

Neue Beiträge

Anzeige