Hallo Community!
in der Runtimeversion von Access 2010 ist - wie in allen anderen Versionen auch - das Kontektmenü in Formularen Sparmaßnahmen zum Opfer gefallen. Was ich aber unglaublich praktisch finde, ist der Textbasierte Filter. Gibt es eine Möglichkeit, ohne großen Aufwand diesen Filter auch in der Runtime Version von Access verfügbar zu machen? Ich bin jetzt nicht wirklich DER Vba Programmierer, von dem her tu ich mich da relativ schwer.
Habt ihr da evtl. ein paar Tipps oder nützliche Links für mich?
In der Forensuche habe ich mit den Suchwürtern "Runtime, Textfilter, Filter" nicht wirklich viel gefunden. Entweder suche ich falsch oder das Thema wurde noch nicht besprochen.
Unter http://www.access-im-unternehmen.de/index.php?id=300&BeitragID=749#anker-23-anchor habe ich schon eine Anleitung gefunden, welche ich auch erfolgreich in mein Projekt eingebunden habe, allerdings fehlen mir die Kenntnisse, die Filtermöglichkeiten auf einen Textfilter zu erweitern.
Vielen Dank im Voraus!
Gruß
also die Lösung unter dem von Dir geposteten Link funktioniert bei mir, wichtig ist nur, dass dort, wo was von Klassenmodulen die Rede ist, auch von Dir Klassenmodule mit dem gegebenen Inhalt erstellt werden ;) Klassenmodule sind KEINE normalen Module! Das wusste ich bspw. nicht, was dann bei mir zu Fehlern geführt hat^^
Mein aktuelles Problem bezieht sich auf das Filtern von Kombinationsfeldern, daher denke ich, dass dieser Thread recht gut passt, weshalb ich keinen neuen erstellt habe...
Filtern an sich ist bereits kein Problem, klappt sowohl mit mehreren Datums-Angaben, als auch mit Text, nur bei Kombinationsfeldern wird nicht nach dem eingegebenen Text gefiltert, sondern nach der Spaltennummer, der Zugrundeliegenden Tabelle...
Sprich ich habe eine Personaldatenbank mit einer Tabelle namens tblAbteilungen und möchte im Formular ein Kombinationsfeld mit den möglichen Abteilungen haben. So weit so gut, wenn ich die Formularansicht öffne, kann ich auch die jeweilige Abteilung auswählen. Wenn es aber ans Filtern geht, muss ich beispielsweise nach "0*" suchen, damit mir alle Datensätze mit der Abteilung "Geschäftsführung" angezeigt werden... Weiterhin würde mich interessieren, warum das Filtern allgemein via VBA NUR in der Runtime funktioniert und nicht in Access selbst.
Wo liegt da nun der Knackpunkt im Code? Ich habe bereits versucht, die gebundene Spalte von 0 auf 1 zu setzen, allerdings hat das einfach nur die Einträge verschoben^^
Der Code ist verdammt lang und ich habe das unwichtige teilweise schon rausgelöscht :X Leider gibts hier im Forum kein Spoiler-Tag^^
Option Compare Database
Option Explicit
Private WithEvents m_Form As Form
Private cbr As CommandBar
Private colOrderBy As Collection
Private colFilter As Collection
Private colCommandbarButtons As Collection
Private WithEvents m_Filterform As Form
Private WithEvents m_FilterformDate As Form
Private WithEvents m_FilterformDateBetween As Form
Private WithEvents m_Filterbox As TextBox
Private WithEvents m_FilterboxDate As TextBox
Private WithEvents m_FilterboxDateFrom As TextBox
Private WithEvents m_FilterboxDateTo As TextBox
Private m_FilterSource As String
Private strCurrentFilter As String
Private strCurrentFilterDate As String
Private strCurrentFilterDateFrom As String
Private strCurrentFilterDateTo As String
Private m_Action As String
Public Sub SetOrderBy(strAction As String)
Dim strOrderBy As String
Dim var As Variant
Dim lngFieldtype As Long
m_Action = strAction
m_FilterSource = Screen.ActiveControl.ControlSource
Select Case m_Action
Case "AddSortAsc", "AddSortDesc", "DropSort", "DropAllSort"
Select Case m_Action
Case "AddSortAsc"
On Error Resume Next
colOrderBy.Remove m_FilterSource
On Error GoTo 0
colOrderBy.Add m_FilterSource & " ASC", m_FilterSource
Case "AddSortDesc"
On Error Resume Next
colOrderBy.Remove m_FilterSource
On Error GoTo 0
colOrderBy.Add m_FilterSource & " DESC", m_FilterSource
Case "DropSort"
On Error Resume Next
colOrderBy.Remove m_FilterSource
On Error GoTo 0
Case "DropAllSort"
Set colOrderBy = New Collection
m_Form.OrderBy = ""
End Select
strOrderBy = ""
For Each var In colOrderBy
strOrderBy = strOrderBy & ", " & var
Next var
strOrderBy = Mid(strOrderBy, 3)
m_Form.OrderBy = strOrderBy
m_Form.OrderByOn = True
Case "AddFilter", "DropFilter", "DropAllFilter"
Select Case m_Action
Case "AddFilter"
lngFieldtype = GetFieldType(m_FilterSource)
Select Case lngFieldtype
'Zahlentypen
Case dbBigInt, dbByte, dbCurrency, dbDecimal, dbDouble, dbFloat, dbInteger, dbLong, dbNumeric, dbSingle
'Text
Case dbChar, dbText, dbMemo, dbGUID
DoCmd.OpenForm "frmFilter"
On Error Resume Next
strCurrentFilter = ""
strCurrentFilter = Split(colFilter.Item(m_FilterSource), "|")(0)
On Error GoTo 0
Set m_Filterform = Forms!frmFilter
Set m_Filterbox = Nothing
Set m_Filterbox = Forms!frmFilter!txtFilter
If Len(strCurrentFilter) > 0 Then
m_Filterbox.Text = strCurrentFilter
Else
m_Filterbox.Text = "*"
End If
m_Filterbox.AfterUpdate = "[Event Procedure]"
m_Filterbox.OnChange = "[Event Procedure]"
'Datum
Case dbDate, dbTime, dbTimeStamp
'Boolean
Case dbBoolean
Case Else
End Select
Case "DropFilter"
m_FilterSource = Screen.ActiveControl.ControlSource
On Error Resume Next
colFilter.Remove m_FilterSource
On Error GoTo 0
SetFilter
Case "DropAllFilter"
Set colFilter = New Collection
SetFilter
End Select
Case "AddFilterDateEqual", "AddFilterDateLarger", "AddFilterDateLargerEqual", "AddFilterDateSmaller", "AddFilterDateSmallerEqual"
DoCmd.OpenForm "frmFilterDate"
Set m_FilterformDate = Forms!frmFilterDate
m_FilterformDate.OnClose = "[Event Procedure]"
On Error Resume Next
strCurrentFilterDate = ""
strCurrentFilterDate = Split(colFilter.Item(m_FilterSource), "|")(1)
On Error GoTo 0
Set m_FilterformDate = Forms!frmFilterDate
Set m_FilterboxDate = Nothing
Set m_FilterboxDate = Forms!frmFilterDate!txtFilterDate
Select Case m_Action
Case "AddFilterDateEqual"
m_FilterformDate.lbl.Caption = "Ist gleich:"
Case "AddFilterDateLarger"
m_FilterformDate.lbl.Caption = "Ist größer:"
Case "AddFilterDateLargerEqual"
m_FilterformDate.lbl.Caption = "Größer gleich:"
Case "AddFilterDateSmaller"
m_FilterformDate.lbl.Caption = "Ist kleiner:"
Case "AddFilterDateSmallerEqual"
m_FilterformDate.lbl.Caption = "Kleiner gleich:"
End Select
m_FilterboxDate.SetFocus
If Len(strCurrentFilterDate) > 0 Then
m_FilterboxDate.Text = strCurrentFilterDate
Else
m_FilterboxDate.Text = ""
End If
m_FilterboxDate.AfterUpdate = "[Event Procedure]"
Case "AddFilterDateBetween"
DoCmd.OpenForm "frmFilterDateBetween"
On Error Resume Next
strCurrentFilterDateFrom = ""
strCurrentFilterDateFrom = Split(colFilter.Item(m_FilterSource), "|")(1)
strCurrentFilterDateTo = ""
strCurrentFilterDateTo = Split(colFilter.Item(m_FilterSource), "|")(2)
On Error GoTo 0
Set m_FilterformDate = Forms!frmFilterDateBetween
Set m_FilterboxDateFrom = Nothing
Set m_FilterboxDateFrom = Forms!frmFilterDateBetween!txtFilterDateFrom
m_FilterboxDateFrom.SetFocus
If Len(strCurrentFilterDateFrom) > 0 Then
m_FilterboxDateFrom.Text = strCurrentFilterDateFrom
Else
m_FilterboxDateFrom.Text = ""
End If
Set m_FilterboxDateTo = Nothing
Set m_FilterboxDateTo = Forms!frmFilterDateBetween!txtFilterDateTo
m_FilterboxDateTo.SetFocus
If Len(strCurrentFilterDateTo) > 0 Then
m_FilterboxDateTo.Text = strCurrentFilterDateTo
Else
m_FilterboxDateTo.Text = ""
End If
m_FilterboxDateFrom.AfterUpdate = "[Event Procedure]"
m_FilterboxDateFrom.OnLostFocus = "[Event Procedure]"
m_FilterboxDateTo.AfterUpdate = "[Event Procedure]"
m_FilterboxDateTo.OnLostFocus = "[Event Procedure]"
m_FilterboxDateFrom.SetFocus
End Select
End Sub
Public Property Set Form(frm As Form)
Dim ctl As Control
Dim strControlSource As String
Dim db As Dao.Database
Dim rst As Dao.Recordset
Dim fld As Dao.Field
Set m_Form = frm
m_Form.OnClose = "[Event Procedure]"
Set colOrderBy = New Collection
Set colFilter = New Collection
Set colCommandbarButtons = New Collection
Set db = CurrentDb
Set rst = m_Form.RecordsetClone
Set rst = db.OpenRecordset(m_Form.RecordSource, dbOpenDynaset)
For Each ctl In m_Form.Controls
strControlSource = ""
On Error Resume Next
strControlSource = ctl.ControlSource
On Error GoTo 0
If Len(strControlSource) > 0 Then
'Datentyp des Feldes herausfinden
Set fld = rst.Fields(strControlSource)
Select Case fld.Type
'Zahlentypen
Case dbBigInt, dbByte, dbCurrency, dbDecimal, dbDouble, dbFloat, dbInteger, dbLong, dbNumeric, dbSingle
CreateSortBar "Aufsteigend sortieren", "Absteigend sortieren", "cbrNumber"
CreateFilterBarNumber
ctl.ShortcutMenuBar = "cbrNumber"
'Text
Case dbChar, dbText, dbMemo, dbGUID
CreateSortBar "Von A bis Z sortieren", "Von Z bis A sortieren", "cbrText"
CreateFilterBarText
ctl.ShortcutMenuBar = "cbrText"
'Datum
Case dbDate, dbTime, dbTimeStamp
CreateSortBar "Von früheren zu späteren Daten sortieren", "Von späteren zu früheren Daten sortieren", "cbrDate"
CreateFilterBarDate
ctl.ShortcutMenuBar = "cbrDate"
'Boolean
Case dbBoolean
CreateSortBar "Von Ja nach Nein sortieren", "Von Nein nach Ja sortieren", "cbrBoolean"
CreateFilterBarBoolean
ctl.ShortcutMenuBar = "cbrBoolean"
Case Else
End Select
End If
Next ctl
End Property
Private Sub m_Filterbox_Change()
Dim strControlSource As String
On Error Resume Next
colFilter.Remove m_FilterSource
On Error GoTo 0
colFilter.Add m_FilterSource & " LIKE '" & m_Filterbox.Text & "'|" & m_Filterbox.Text, m_FilterSource
SetFilter
End Sub
Private Sub SetFilter()
Dim strFilter As String
Dim var As Variant
For Each var In colFilter
strFilter = strFilter & " AND " & Split(var, "|")(0)
Next var
strFilter = Mid(strFilter, 6)
m_Form.Filter = strFilter
m_Form.FilterOn = True
End Sub
Hallo,
nur bezgl (zu dem "Kanonen-Spatzen"-Code kein Kommentar..):
ZitatWenn es aber ans Filtern geht, muss ich beispielsweise nach "0*" suchen, damit mir alle Datensätze mit der Abteilung "Geschäftsführung" angezeigt werden...
ist unklar, was und wie gefiltert wird/werden soll.
Die "Geschäftsführung" muss in tblAbteilungen ein durch einen Primärschlüssel eindeutig definierbarer Datensatz sein.
Wenn z. B. alle Mitarbeiter gefiltert werden sollen, die einer bestimmten Abteilung ("Geschäftsführung") zugeordnet sind, dann braucht es da keinen "Sternchen-Vergleich", der eh nur bei Text(-Werten) sinnvoll ist und der Primärschlüssel(wert) aus tblAbteilungen muss in tblMitarbeiter in einem Fremdschlüsselfeld abgelegt sein.
Zitat von: DF6GL am Dezember 04, 2013, 16:49:20Die "Geschäftsführung" muss in tblAbteilungen ein durch einen Primärschlüssel eindeutig definierbarer Datensatz sein.
Wenn z. B. alle Mitarbeiter gefiltert werden sollen, die einer bestimmten Abteilung ("Geschäftsführung") zugeordnet sind, dann braucht es da keinen "Sternchen-Vergleich", der eh nur bei Text(-Werten) sinnvoll ist und der Primärschlüssel(wert) aus tblAbteilungen muss in tblMitarbeiter in einem Fremdschlüsselfeld abgelegt sein.
Morgen,
ich habe bereits die AbteilungsID als Primärschlüssel in der Abteilungs-Tabelle gesetzt und auch eine 1:n-Beziehung zur Mitarbeiter-Tabelle zwischen AbteilungsID und AbteilungsID gesetzt.
Den Sternchen-Vergleich mache ich auch einfach nur so aus Prinzip... Abgesehen davon ist das Kombinationsfeld, das gefiltert werden soll, sowieso vom Typ Text.
Dennoch bleibt die Frage, was ich abändern muss, damit beim Filtern des Kombi-Feldes auch Buchstaben anerkannt werden und nicht NUR Zahlen, obwohl es ja mit Text gefüllt ist.
Grüße
Hallo,
nun, ich versteh immer noch nicht die "Filter"-Vorstellung.
"Den Sternchen-Vergleich mache ich auch einfach nur so aus Prinzip... " ??
"Prinzipiell" müssen die Datentypen berücksichtigt werden... und die ID (Zahl, Long) ist nun mal kein TEXT.
Vielleicht meinst Du auch, das Kombi-Listenfeld mittels Eingabe eines oder mehrerer Zeichen in das Kombi-Textfeld einzuschränken. (bei Spalte0 == ID, Spalte1 == Abteilungsname, gebundene Spalte ==1 )
Das geht standardmäßig so nicht, wenngleich sich auch der Cursor jeweils auf den ersten passend gefundenen Eintrag positioniert.
Möglicherweise ist mit etwas VBA und den "Tasten"-Ereignissen eine solche Einschränkung der Listenfeld-Einträge zu erreichen, wobei sich DAO und ADODB etwas unterschiedlich verhalten.
Eine andere Möglichkeit wäre , das(die) Kombifeld(liste) mit einem ungebundenen Suchfeld vorzufiltern, ähnlich der Methode der "abhängigen Kombifelder".
Sub txtAbtName_Afterupdate()
Me!cmbAbteilung.Rowsource =" Select Abt_ID, Abt_Name from tbl_Abteilung Where Abt_Name Like '" & Me!txtAbtName & "*'"
End Sub
haha, ok, ich erklär am besten wohl nochmal die genauen Umstände, damit Du nichtmehr auf dem Schlauch stehst :D
Ich erstelle gerade eine Mitarbeiterdatenbank, auf die später alle Mitarbeiter via Access Runtime zugreifen sollen. Da die Runtime, aber kein Kontextmenü beherrscht, habe ich diesen langen Quellcode, den ich gepostet hab, im Netz gefunden, um ein Kontextmenü für die Runtime zu erstellen. Das Kontextmenü enthält Filter- und Sortiermöglichkeiten, die bereits auf den Feldtyp (Text, Zahl, Ja/Nein,...) abgestimmt sind (sprich: Datumsfelder enthalten "von früherem Datum nach späterem sortieren" usw.). Da das Kombi-Feld ein Text-Feld ist, ist im Kontextmenü der Eintrag "Filtern nach..." vorhanden, wird dieser angeklickt, öffnet sich ein kleines Filter-Formular mit einem Textfeld, was bereits ein Sternchen enthält. Wird in das Textfeld des Filterformulars etwas eingetragen, bewirkt die OnChange-Prozedur des Feldes, dass alle Datensätze sofort gefiltert werden. Ich weiß grad nicht, wie ich es besser erklären soll^^
Ich hab zu Testzwecken einfach mal 3 Datensätze angelegt, 2 davon habe ich der Abteilung IT zugeordnet, einen der Geschäftsführung.
Ich möchte nun in das Textfeld-des Filterformulars "IT" eingeben und dann auch bitte die 2 Datensätze angezeigt bekommen, die der IT-Abteilung zugeordnet sind. Stattdessen werde ich aber zu einem neuen Datensatz geleitet. Gebe ich in das Textfeld des Filterformulars aber die ID der Abteilung in der Abteilungs-Tabelle ein, klappt das Filtern wunderbar, jedoch wäre das etwas unkomfortabel für den späteren Gebrauch der restlichen Mitarbeiter in der Runtime.
Ich dachte daran, dass es daran liegen könnte, dass der AutoWert der Abteilungs-Tabelle eben eine Zahl ist und kein Textfeld. Das Ändern auf Text hat aber nicht geholfen, ich konnte immernoch nur via Zahl filtern.
Ich hoffe, dass diese Erklärung weiterhilft und ich hoffe auch, dass Du weiterhin gewillt bist, dich meiner anzunehmen :) Allerdings kann ich auch verstehen, wenn nicht ;D
Grüße!
Hallo,
es liegt nicht an meiner Hilfe-Bereitschaft...
und vermutlich stehst Du auf dem Schlauch ;) ;) ;D
Zitat
Ich hab zu Testzwecken einfach mal 3 Datensätze angelegt, 2 davon habe ich der Abteilung IT zugeordnet, einen der Geschäftsführung.
Ich möchte nun in das Textfeld-des Filterformulars "IT" eingeben und dann auch bitte die 2 Datensätze angezeigt bekommen, die der IT-Abteilung zugeordnet sind.
Tabellenmäßig sieht das so aus:
tblMitarbeiter:
MAID (PK, Autowert)
MA_AbtID (Zahl, Long)
MA_Name
....
....
MAID MA_AbtID MA_Name
1 1 Maier
2 1 Müller
3 2 Schulze
4 1 Mustermann
5 2 Musterfrau
tblAbteilungen
AbtID (Pk, Autowert)
Abt_Bezeichnung (Text)
....
....
AbtID Abt_Bezeichnung
1 Geschäftsführung
2 ITUm nun die richtigen "Zahlen" (Fremdschlüsselwerte) filtern zu können, müssen die erst mal aus der 1-Tabelle (tblAbteilungen) anhand der Abt-Bezeichnung bestimmt und dann zur Filterung hergenommen werden
Beispielhaft:
strKrit = " MA_ABtID in (Select AbtID from tblAbteilung Where Abt_Name like '" & Me!Suchfeld & "*')"
strSQL= " Select * from tblMitarbeiter " & " Where " & strSQL
Wie (entspr. der akt. Such-Situation) und wo (vermutlich als neues Collection-Element) Du nun diesen Where-Condition (Filter-String) in Deinen Code einbaust, überlass ich jetzt Dir...
Super, vielen vielen Dank! Ich habe zwar keine Ahnung, was ich gemacht hab, aber nach vielem Herumspielen mit den Datenherkünften usw. des Kombinationsfeldes, funktioniert es jetzt einwandfrei ;D ;D
Wie gesagt, trotzdem vielen Dank für den Aufwand! :)