valume91
Goto Top

Access VBA, Bericht filtern

Wie kann ich einen Bericht per VBA nach Datum (von... bis...) filtern?

Hallo Wissende face-wink

Ich brauche eurern fachmännischen Rat! Ich habe einen Bericht den ich mit einer Abfrage als Grundlage generiert habe. In diesem Bericht habe ich ein Feld welches ein Datum enthält. Nun soll man in diesem Bericht so filtern können das nur die Datensätze angezeigt werden, die in einer gewissen Zeitspanne liegen (von/bis).

Ich habe mir das so gedacht:
Ich habe ein Formular, welches zwei ungebundene Textfelder und ein Button enthält. In die Textfelder gebe ich die Datum Werte "von" und "bis" ein. Beim klick auf den Button öffnet sich dann der Bericht, und zwar nur mit den Datensätzen die in dieser Zeitspanne liegen!

Leider habe ich keine Ahnung wie der Code dazu aussehen sollte face-sad
ABER! Ich weiss das Ihr es wisst! face-smile

MfG Valume

Content-ID: 126464

Url: https://administrator.de/contentid/126464

Ausgedruckt am: 22.11.2024 um 10:11 Uhr

jhinrichs
jhinrichs 05.10.2009 um 13:40:44 Uhr
Goto Top
Hallo,

ungefähr so:

Private Sub cmdAusgabe_Click()
On Error GoTo Err_cmdAusgabe_Click

    Dim stDocName As String

    stDocName = "rptReport"  
    DoCmd.OpenReport stDocName, acPreview, , setFilter()   

Exit_cmdAusgabe_Click:
    Exit Sub

Err_cmdAusgabe_Click:
    MsgBox Err.Description
    Resume Exit_cmdIntPrg_Click
    
End Sub

Private Function setFilter() As String
Dim sFilter, sVon, sBis As String
    sFilter = ""  
    
    If Me.txtDatVon <> "" Then  
      sVon = "Datum >= " & SQLDate(Me.txtDatVon)  
    End If
      
    If Me.TxtDatBis <> "" Then  
      sBis = "Datum <= " & SQLDate(Me.TxtDatBis)  
    End If
      
    If sVon = "" And sBis = "" Then  
      sFilter = "Datum > #01/01/1900#"  
    Else
      If sVon <> "" And sBis <> "" Then  
        sFilter = sVon & " And " & sBis  
      Else
        If sVon = "" Then  
          sFilter = sBis
        Else
          sFilter = sVon
        End If
      End If
    End If
                    
    setFilter = "(" & sFilter & ")"  
    
End Function


Private Function SQLDate(InDate As String) As String
  Dim sDay, sMonth, sYear As String
  Dim sDatVal As String

  sDatVal = DateValue(InDate)

  sDay = Day(sDatVal)
  sMonth = Month(sDatVal)  
  sYear = Year(sDatVal)

  SQLDate = "#" & sMonth & "/" & sDay & "/" & sYear & "#"  

End Function

Wird aus dem Formular, mit dem die Tabelle/Abfrage verknüpft ist, aufgerufen, über den Button "cmdAusgabe". Das Datumsfeld im Formular heißt "Datum", die Von/Bis-Felder heißen txtDatVon bzw. txtDatBis. Über setFilter wird ein SQL-Ausdruck zum Filtern der Ausgabe generiert, fehlen EInträge in Von/Bis wird jeweils alles (vorausgesetzt, es gibt keine EInträge vor dem 1.1.1900) ausgegeben. Die Funktion SQLDate ist notwendig, um das Datum SQL-gerecht zu formatieren.
Hope this helps.
Viele Grüße
broecker
broecker 05.10.2009 um 15:17:46 Uhr
Goto Top
andere Variante "ohne Programmieren":
die Daten auf denen der Bericht basiert kommen aus einer Abfrage, nicht nur einer Tabelle (dürfte aber 1:1 sein), dann kommen in die Abfrage Kriterien hinzu, die mit dem Ausdrucksassistenten (geladene Formulare, Felder, Wert) aufgebaut werden: sieht in etwa so aus: >Forms![NameDesFormulars]![NameDesFeldes], fertig! ("in etwa" weil ich mir nicht merken kann, ob das nun deutschsprachig oder englisch generiert wird, macht aber der Ausdrucksassistent)
Das Formular muß beim Anzeigen des Berichtes offen sein.
Vorteil: intuitiv, Nachteile: es muß dokumentiert werden, daß die Abfrage vom Formular abhängt, Access (face-wink)
Valume91
Valume91 05.10.2009 um 16:05:28 Uhr
Goto Top
Tag zusammen

Danke für die schnellen Antworten!

@jhinrichs
Wird aus dem Formular, mit dem die Tabelle/Abfrage verknüpft ist, aufgerufen, über den Button "cmdAusgabe".
Der Button "cmdAusgabe" sowie die von-bis Felder sollten sich eigentlich in einem Formular befinden das keine Datenherkunft hat. Es existiert nur um den Bericht zu filtern.
Der Bericht: "ber_QBericht" hat direkt die Abfrage als Datenherkunft.
Ausserdem habe ich den Bericht nirgends in deinem Code gefunden. Wie geht das dann das er gefiltert wird?


@broecker
Wenn ich dich richtig verstanden muss ich dann immer in der Abfrage die Kriterien anpassen.
Es sollte aber so sein das man dies direkt über ein kleines Formular tun kann das sich "vor" dem Bericht öffnet.

MfG Valume
jhinrichs
jhinrichs 05.10.2009 um 16:14:38 Uhr
Goto Top
Hallo,
ich weiß jetzt nicht genau, ob ich verstanden habe, was Du meinst, aber hier wird der Bericht geöffnet (angepasst auf Dein Beispiel):
stDocName = "ber_QBericht"  
DoCmd.OpenReport stDocName, acPreview, , setFilter()    
Eine Verknüpfung der Abfrage mit dem Formular ist nicht notwendig, der Filter ist ja letztlich ein SQL-WHERE-Statement, welches von DoCmd.OpenReport ausgewertet wird.

Die Lösung von broecker sollte auch gehen, Du musst aber eine extra Abfrage für den Bericht erstellen, die dann die Kriterien enthält.
Valume91
Valume91 05.10.2009 um 16:42:33 Uhr
Goto Top
Hi jhinrichs
Danke erstmal für die Antwort. Ich probiers morgen aus!
MfG Valume
broecker
broecker 06.10.2009 um 00:21:36 Uhr
Goto Top
nein, es wird in der Abfrage immer das auf dem Formular eingetragene Datum berücksichtigt, geht wirklich ganz einfach:

Feld Datum
<=FormularDatumEnde UND >FormularDatumBegin
Valume91
Valume91 06.10.2009 um 14:47:23 Uhr
Goto Top
Tag zusammen

Ich habe eure Vorschläge nun ausprobiert.
@broecker
Hat funktioniert. Leider ist dies für mich unpraktisch, da mehrere Berichte auf die selbe Abfrage zugreifen. Und so kommt immer beim einen die Meldung das das entsprechende Formular nicht geöffnet ist.

@jhinrichs
Beim Code kommt bei mir die Fehlermeldung:

Fehler beim kompilieren.
Sprungmarke nicht definiert.


Und folgende Zeile wird Blau markiert:
Resume Exit_cmdIntPrg_Click

Was mache ich falsch?


Edit sagt:

Ich habs jetzt mit dem Code von jhinrichs gelöst. Der Fehler ging weg als ich die Zeile
Resume Exit_cmdIntPrg_Click
gelöscht habe. xD

Andere Frage:
Ich würde jetzt gerne noch bei gewissen Feldern (sagen wir "felda" und "feldb") aufsteigen bzw absteigend sortieren. Wie geht das?
Diese Funktion sollte auch im gleichen Formular eingebaut sein wie die für die Zeitspanne.


Lg Valume
broecker
broecker 06.10.2009 um 15:10:12 Uhr
Goto Top
der Bericht könnte im Hintergrund (Ereignis "Beim Laden") das Formular öffnen, aber warum nicht mehrere Berichte?
jhinrichs
jhinrichs 06.10.2009 um 15:19:44 Uhr
Goto Top
Sorry, die Zeile ist noch als Fragment aus meiner Anwendung stehen geblieben, kein Wunder, dass er sie angemeckert hat. Sie muss in dem Beispiel so lauten:
Resume Exit_cmdAusgabe_Click
Die Sortierung kannst Du über die Schaltfläche "Sortieren und Gruppieren" in der Entwurfsansicht des Berichtes festlegen.
Valume91
Valume91 06.10.2009 um 15:21:45 Uhr
Goto Top
Ja das mit dem Formular öffnen wäre eine Möglichkeit, wenn auch unschön.
Habe jetzt wie gesagt den Code von jhinrichs genommen, und hat prima funktioniert.
Danke trotzdem für deine Hilfe broecker!
Vieleicht weist du ja eine Antwort auf meine neue Frage bezüglich auf- bzw. absteigend sortieren.

MFG Valume
Valume91
Valume91 06.10.2009 um 15:26:12 Uhr
Goto Top
Tag jhinrichs

Danke ich werden den Teil wieder einfügen ;)

Die Sortierung kannst Du über die Schaltfläche
"Sortieren und Gruppieren" in der Entwurfsansicht des
Berichtes festlegen.
Jup ist klar, nur soll der User die Sortierung selbst festlegen können, und der kommt nunmal nicht in die Entwurfsansicht. Man sollte also bereits im "Datumfilternformular" die Kriterien für die Sortierung eingeben können.
Ist das möglich?

MfG Valume
jhinrichs
jhinrichs 06.10.2009 um 15:43:40 Uhr
Goto Top
Meines Wissens nicht direkt. Du könntest aber über z.B. ein Auswahlfeld (nennen wir es mal "cboAuswahl") verschiedene vorsortierte Berichte auswählen lassen und dann im Programmcode die Zeile
stDocName = "ber_QBericht"
durch so etwas wie
stDocName = Me.cboAuswahl
ersetzen.
Auf die gleiche Art könnte man in der DoCmd.OpenReport-Methode das Filter-Argument auswählen, um dem Bericht eine bestimmte (sortierte) Abfrage zuzuweisen, aber da wird es dann schon wieder etwas komplizierter, so dass Du da, ggf. mit Hilfe der Hilfefunktion zur OpenReport-Methode, etwas experimentieren solltest.
Valume91
Valume91 08.10.2009 um 11:45:34 Uhr
Goto Top
Tag zusammen

Ich möchte diesen Beitrag neu aufnehmen.
Das mit dem auf- bzw. absteigend Sortieren habe ich aufgegeben.
Nun aber etwas neues, ähnlich der Datum sortieren funktion:
Im selben Formular ( "frm_KriterienBericht") habe ich ein zusätzliches ungebundenes Textfeld ("Erfasser").
Nun möchte ich das mit einem Klick auf den selben Button wie bei der Sortierung nach Datum, der Bericht nach dem Inhalt von "Erfasser" gefiltert wird. Das Feld in der Abfrage dazu heisst "ErfasstGruppe_IDFS".
Wie lautet der Code hierzu?
Er sollte nicht sehr anders als der vorherige sein oder?

MfG Valume
broecker
broecker 08.10.2009 um 12:51:06 Uhr
Goto Top
Stimmt. (Fülltext um die dreißig Zeichen aufzufüllen)
das ganze Projekt müssen wir ja nicht lösen, nur noch bedingt face-smile
Valume91
Valume91 08.10.2009 um 13:15:46 Uhr
Goto Top
Da hast du auch wieder recht face-wink
Ich kapier nur leider nicht wie ich der Filtern Befehl funktioniert.
Den Rest kann ich ja mit if oder case lösen.
jhinrichs
jhinrichs 08.10.2009 um 13:34:22 Uhr
Goto Top
Hallo,
der Filter ist ein String (im Beispiel in der setFilter-Funktion erstellt), der dem Bedingungsteil eines SQL-SELECT-WHERE-Statements entspricht.
Beispiel:
SQL:
SELECT Feld1, Feld2 FROM tblTabelle WHERE Id = "test"
Filter:
Id = "test"
Konkret:
Du müsstest an den Filterstring in der Funktion setFilter() anhängen:
setFilter = setFilter & "And ErfasstGruppe_IDFS = " & Me.Erfasser
natürlich nur, wenn Erfasser nicht leer ist (sonst kommt ein Syntaxfehler)
Tipp dazu: nach der Codeänderung setze einmal einen Breakpoint in die setFilter-Funktion und schaue Dir per Einzelschrittverarbeitung an, wie sich der setFilter-String zusammenbaut.
Valume91
Valume91 19.10.2009 um 11:47:07 Uhr
Goto Top
Hi jhinrichs

Ich war in den Ferien deshalb konnte ich dieen Thread lange nicht weiterverfolgen.
Tut mir leid aber ich verstehe praktisch nichts von dem was du geschrieben hast.

Ich muss ja irgendwie die Setfilter Variable anpassen oder?
(Es sollen beide Filter funktionieren, also nach vonbis und nach dem Wert im Feld "durch1")

Also was muss ich bei
setFilter = "(" & sFilter & ")"  
einfügen damit zusätzlich noch noch nach "durch1" gefiltert wird? Also wie füge ich das ein damit immer noch nach vonbis gefiltert wird?

lg Valume
jhinrichs
jhinrichs 19.10.2009 um 12:04:54 Uhr
Goto Top
Hallo,
was ist "durch1"?
Oben war von "Erfasser" die Rede, geht es darum?
Valume91
Valume91 19.10.2009 um 12:47:04 Uhr
Goto Top
ja durch1 ist der Erfasser, bzw das Feld in dem das Filterkriterium steht.
jhinrichs
jhinrichs 20.10.2009 um 08:03:48 Uhr
Goto Top
Hallo,
s.o.:
(Sorry, habe oben setFilter geschrieben, meinte die lokale Variable sFilter, in der der String zusammengebaut wird)
sFilter = sFilter & "And ErfasstGruppe_IDFS = " & Me.Erfasser
natürlich nur, wenn Me.Erfasser nicht leer ist (sonst kommt ein Syntaxfehler)

für letzteres müsstest Du eine if-Abfrage bauen. Diesen Block fügst Du vor
setFilter = "(" & sFilter & ")"
ein, was als letzte Zeile nur noch einmal Klammern um die Abfrage baut, die nicht zwingend erforderlich sind, die Zeile könnte auch lauten:
setFilter = sFilter

Um die Funktionsweise zu verstehen, noch einmal die Empfehlung, im VB-Editor einen Haltepunkt zu Beginn der setFilter-Funktion zu setzen und dann mit Einzelschritten den Zusammenbau des Filterausdrucks verfolgen.
Valume91
Valume91 21.10.2009 um 09:16:41 Uhr
Goto Top
Hi jhinrichs

das Ende des codes sieht nun so aus:
If Me.durch1.Value = "" Then  
setFilter = "(" & sFilter & ")"  
Else
sFilter = sFilter & "And ErfasstGruppe_IDFS = " & Me.durch1  
setFilter = sFilter
End If

Beim Klick auf den Button kommt jedoch immer die Meldung:
Parameterwert eingeben: ErfasstGruppe_IDFS

Muss ich ErfasstGruppe_IDFS noch sonst wo haben als in der Abfrage?

Gruss Valume
jhinrichs
jhinrichs 21.10.2009 um 13:32:33 Uhr
Goto Top
Hallo,
ja, in dem Bericht, den Du ausgeben möchtest als (ggf. unsichtbares) Feld.