# Abfrage mit VBA



## starbug (21. Dezember 2011)

Hallo,

ich würde gerne wissen wie ich in Access eine Abfrage per VBA erstellen kann und dann
zusätzlich noch ein Kriterium übergeben kann was variabel sein muss. 

Also generel würde ich ja sowas machen

```
Dim db As DAO.Database
    Dim rec_adr As DAO.Recordset 

   Set rec_adr = db.OpenRecordset("SELECT * FROM Artikerl WHERE ArtikelNr = 1234")
```

Ich möchte das aber so haben, das wenn ich in meiner Artikelliste auf die ArtikelNr. doppleklicke sich die Abfrage öffnet und als Kriterium die angeklickte ArtikelNr übergeben wird. Wie kann man sowas machen?


----------



## Yaslaw (21. Dezember 2011)

Erstelle in Datasheet-Formular auf die Abfrage.
Dann kannst du dieses mit dem Filter öffnen


```
Sub openFilteredDS(ByVal artikelNr As Long)
    Dim myFilterString As String
    
    myFilterString = "ArtikelNr = " & artikelNr
    
    Call DoCmd.OpenForm("myFormName", acFormDS, , myFilterString)
End Sub
```


----------



## starbug (21. Dezember 2011)

Ok ich hab das mal gemacht aber ändert sich nichts. der Filter schaltet sich zwar ein aber es ändert sich halt nichts. es wäre glaube ich auch besser wenn sich das neue Formular oder die Abfrage in einem neuen Fenster öffnet. Was könnte man da tun?


----------



## Yaslaw (21. Dezember 2011)

Diese function öffnet das ganze in einem neuen Fenster.

Wie hast du es denn eingebaut?


----------



## starbug (21. Dezember 2011)

Hier rein


```
Private Sub PRDNO_DblClick(Cancel As Integer)
End Sub
```


----------



## Yaslaw (21. Dezember 2011)

Ja, das ist leer. Da wird nix ausgeführt. Du musst schon mein Code anpassen und da reinkopieren. Ansonsten geht nix.


----------



## starbug (21. Dezember 2011)

Ich weiss das es leer ist, ich wollte nur zeigen wo ich es eingefügt habe. Allerdings hast du ja bei deiner Methode nen String Parameter als Argument, den kann ich doch hier gar nicht einfügen da schon was anderes als Parameter übergeben wurde


----------



## starbug (21. Dezember 2011)

Hier mal wich es angepasst habe:



```
Sub openFilteredDS(ByVal artikelNr As Sring)
    Dim myFilterString As String
    
    myFilterString =  Me.artikelNr
    
    Call DoCmd.OpenForm("Artikel_Form", acFormDS, , myFilterString)
End Sub
```

Nur da tut sich nichts.


----------



## Yaslaw (21. Dezember 2011)

*Item: *Wie nix? Es öffnet kein Fenster, es kommt keine ehlermeldung? Die Maus blockiert, er wie was wo?

Nebenbei, finde die 10 Unterschiede

```
'Dein Code
    myFilterString =  Me.artikelNr

'Mein Code
    myFilterString = "ArtikelNr = " & artikelNr
```


----------



## starbug (22. Dezember 2011)

Du hast aber auch oben die Variable artikelNr als Long zugewiesen, oder meinst du mit "ArtikelNr"
den Namen des Textfeldes?: Kurze andere Frage: Ich müsste das doch auch mit SQL ausführen können, so etwa:


```
Private Sub PRDNO_DblClick(Cancel As Integer)

Dim sqlstring As String

sqlstring = "SELECT Master.ArtikelNr, Master.Artikel, Master.KundenNr, Master.Kunde, Master.Preis FROM Master"
        
DoCmd.RunSQL sqlstring


End Sub
```


Kommt aber immer ein Fehler und zwar: "Laufzeitfehler 3075 Syntaxfehler (fehlender Operator) in Abfrageasudruck Master.Preis".

Wieso ist das so?


----------



## Yaslaw (22. Dezember 2011)

RunSQL führt ein SQL aus. Sprich, ein INSERT, DELETE oder UPDATE. SELECT ohne INTO zählt da nicht dazu, da es keine Daten manipuliert.

Ein Auszug aus der F1-Hilfe auf runSQL


> SQLStatement: A string expression  that's a valid SQL statement for an action query  or a data-definition query . It uses an INSERT INTO, DELETE, SELECT...INTO, UPDATE, CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX, or DROP INDEX statement. Include an IN clause if you want to access another database.




Die ArtikelNr in meinem Beispiel war ein Beispiel. Nimm dein ArtikelNr-Feld oder was auch immer. Aber es muss immer vom Type 'Feld = Wert' sein und nicht nur 'Wert'


----------



## starbug (22. Dezember 2011)

Also ist es generell nicht möglich eine einfache Auswahlabfrage mit VBA zu erstellen?


----------



## Yaslaw (22. Dezember 2011)

Doch. Es ist nur die Frage was du damit willst.

Du kannst jederzeit eine Abfrage erstellen und öffnen. Doch dazu muss sie mindestens als Abfrage gespeichert sein.

Dazu eine kleine Funktion

```
Public Sub openSqlAsQuery(ByVal sql As String)
    Const C_TEMP_QUERY_NAME = "vw_temp"
    
    'Dein SQL
    sql = "SELECT * FROM "
    
On Error Resume Next
    'Versuchen das SQL hinter der Abfrage vw_temp zu ersetzen
    CurrentDb.QueryDefs(C_TEMP_QUERY_NAME).sql = sql
    If Err.Number <> 0 Then
        'Falls das Query vw_temp noch nicht besteht, neu anlegen
        Call CurrentDb.CreateQueryDef(C_TEMP_QUERY_NAME, sql)
        Err.clear
    End If
On Error GoTo 0

    'Abfrage öffnen
    Call DoCmd.OpenQuery(C_TEMP_QUERY_NAME)

End Sub
```

Diese kannst du dann so aufrufen

```
Public Sub test()
    Dim SqlString As String
    
    SqlString = "SELECT Master.ArtikelNr, Master.Artikel, Master.KundenNr, Master.Kunde, Master.Preis FROM Master"

    Call openSqlAsQuery(SqlString)

End Sub
```


----------



## starbug (22. Dezember 2011)

```
Public Sub openSqlAsQuery(ByVal sql As String)
    Const C_TEMP_QUERY_NAME = "vw_temp"
    
    'Dein SQL
    sql = "SELECT * FROM "
```


Muss ich denn dann hier sql = SELECT Master.ArtikelNr, Master.Artikel......etc. eingeben?

Oder ist das irgendwie so eine Allgemeine Form. Weil bei dem Test Code würde ich es ja sonst nochmal engeben.


----------



## Yaslaw (22. Dezember 2011)

Yaslaw hat gesagt.:


> Diese kannst du dann so aufrufen
> 
> ```
> Public Sub test()
> ...



Nachtrag:
*Sorry, hab ein Fehler in meinerm Script entdeckt!*
das folgende muss gelöscht werden!

```
'Dein SQL
    sql = "SELECT * FROM "
```

So sollte es aussehen

```
Public Sub openSqlAsQuery(ByVal sql As String)
    Const C_TEMP_QUERY_NAME = "vw_temp"
     
On Error Resume Next
    'Versuchen das SQL hinter der Abfrage vw_temp zu ersetzen
    CurrentDb.QueryDefs(C_TEMP_QUERY_NAME).sql = sql
    If Err.Number <> 0 Then
        'Falls das Query vw_temp noch nicht besteht, neu anlegen
        Call CurrentDb.CreateQueryDef(C_TEMP_QUERY_NAME, sql)
        Err.clear
    End If
On Error GoTo 0
 
    'Abfrage öffnen
    Call DoCmd.OpenQuery(C_TEMP_QUERY_NAME)
 
End Sub
```


----------

