18. november 2010 - 15:12Der er
56 kommentarer og 1 løsning
Forespørgsel tom ved flere markeringer i liste
Hej
Har oprettet en forespørgsel som bygger på kriterier i en formular. I formularen har jeg oprettet en liste med kriterier. Det hele virker fint, når jeg ikke tillader mere en én markering i listen. Så snart jeg vælger simpel eller sammensat markering i egenskaberne for listen er resultatet i forespørgslen tom.
Jeg har på fornemmelsen, at det er fordi der databasen skal fortælles, at der skal et "Or" imellem de markerede værdier på listen, men jeg kan bare ikke få det til at virke.
Hvis du har kriterierne stående på samme linie i forespørgselsgitteret, gælder der AND imellem dem. For at få OR, skal de stå på hver sin linie (altså som en trappe).
I forespørgslen har jeg nede i kriterierne benyttet udtryksgeneratoren til at skrive, at kriteriet for denne kolonne er lig med inputtet i den liste, som jeg har indsat i formularen. Dvs. at der kun er ét kriterie for hver kolonne.
Noget i stil med [Forms]![Køreliste]![Liste1]
Det virker som sagt fint, hvis der kun markeres én værdi i listen. Jeg forstår ikke i dit svar, hvordan jeg skal få den til at acceptere flere markeringer på listen.
Sorry. Misforstod som om du havde flere uafhængige kriterier (altså på flere felter). Du har flere kriterier på eet felt. Har ingen erfaring her. Bakker ud.
Du kan ikke burge quiery designeren når du ahr en listbox som tillader flere valg. Du skal selv hive værdierne ud, og så lave en SQL sætning.
Private Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
Og
...
Dim strWhere as String
strWhere = "[MyField] IN " & GetDataFromListBox(Me!MyListbox)
og derpå
Me.Filter = strWhere Me.FilterOn = True
og så bliver formularen filtreret efter kriterierne.
Private Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End FunctionPrivate Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
Private Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End FunctionPrivate Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
Den her linie er rød. Ved ikke om det betyder noget.
End FunctionPrivate Function GetDataFromListBox(myListBox As Control) As String
strWhere = "[MyField] IN " & GetDataFromListBox(Me!myListBox)
Ved godt det er pga. navnet så har rettet den til
strWhere = "[MyField] IN " & GetDataFromListBox(Liste27)
Nu brokker den sig ikke mere, og jeg kan godt vælge flere punkter på listen. Problemet er nu, at forespørgslen medtager alt. Muligvis fordi kriteriefeltet i forespørgslen ikke er korrekt. Hvad skal det hedde?
Hvis din formular fortsat er baseret på en forespørgsel, så skal den forespørgsel ikke sortere på det kriterie du nu har lagt et andet sted, nemlig i koden og i formularens filter.
"Den medtager fortsat poster fra de poster på listen, som ikke er markeret." Hvornår? Npr ofrulamren åbens så er der ikke sat noget kriterie, så det er som dest akl vær. Efter at have valgt i listboxen, s åbliver formualrens filter aktivee i AfterUpdate, og derpå skulle gerne kun de valgte poster vises.
Hmm ok. Når jeg åbner formularen er der 3 udvælgelseskriterier. Et datofelt og 2 lister. Det er kun den ene liste (Liste27), som vi tester med nu. Datofeltet virker fint og den anden liste er sat op til kun én markering. Virker også fint.
I formularen har jeg en kommandoknap, som åbner en rapport baseret på forespørgslen, som datofeltet og listerne skal referere til.
I kolonnen [AUF_WERK_ID], som Liste27 refererer til, er kriteriefeltet nu tomt. Som jeg forstår dig, skal det være tomt, da den indsatte kode gør, at forespørgslen ved, at [AUF_WERK_ID] skal være lig de markerede værdier i listen.
Problemet er bare, at forespørgslen er helt ligeglad med, hvad der er markeret i listen.
Er der et eller andet sted i koden, hvor jeg mangler at fortælle, at forespørgslen kolonne [AUF_WERK_ID] skal baseres på Liste27 mon?
2. Denne forespørgsel udvælger poster efter kriterier angivet i din formular.
3. Formularen er tillige baseret på forespørgslen, så formularen viser alene de poster som forespørgslen har udvalgt efter de kriterier der er angivet for forespørgslen. Forespørgslen aner intet om nogen Liste27.
4. Derpå, i formularen, laver du et filter baseret på Liste27. Filteret er knyttet til formularen. Resultatet af dette ændrer intet i forespørgslen, men udvælger FRA forespørgslen de poster som opfylder filterkriteriet og viser alene disse i FORMULAREN. Forespørgslen selv er stadig ubekendt med nogen liste 27. Filteret svare til at køre en forespørgsel ovenpå en forespørgsel (i stedet for på en tabel).
5. Nu vil du have en rapport basereret på samme poster. Så skal rapporten have samme filter.
Private Function GetDataFromListBox(myListBox As Control) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer
iCount = 0 sTemp = ""
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & myListBox.ItemData(oItem) iCount = iCount + 1 Else sTemp = sTemp & "," & myListBox.ItemData(oItem) iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
Private Sub Vis_køreliste_Click()
DoCmd.OpenReport "Køreliste", , , strWhere
End Sub
Når jeg trykker på knappen, spørger den efterparameter for AUF_WERK_ID og den forsøger at printe rapporten selvom den bare skal vise den på skærmen.
Så vil jeg lige tillade mig at blande mig (når I nu lukker).
Det ser ud som om, du har fået blandet dine variable sammen.
I sætningen DoCmd.OpenReport "Køreliste", , , strWhere bruger du strWhere; men det er jo den variabel, der indeholder dit filter.
For at se rapporten, skal du bruge acViewPreview For at printe rapporten, skal du bruge acViewNormal De fremgår begge af hjælpeteksten, når du skriver DoCmd.OpenReport "Køreliste",
Som skrevet tidligere havde jeg ikke tjekket koden. Det har jeg gjort nu og kan se hvor neoman var på vej hen. Det er jo helt korrekt, at strWhere (filteret) skal med i kaldet. Det korrekte kald bliver således: DoCmd.OpenReport "Køreliste", acViewPreview, , strWhere
Nu har jeg bygget et lille testmiljø og afprøvet koden. Den ser ud til at virke helt fint!
Jeg kan ikke overskue, hvad det er du gør forkert. Prøv at rette koden til:
Private Sub Liste27_AfterUpdate() strWhere = "[AUF_WERK_ID] IN " & GetDataFromListBox(Liste27) Debug.Print strWhere
Me.Filter = strWhere Me.FilterOn = True End Sub
... og aflæs så strWhere i Immediate vinduet (Ctrl-G), når du ændrer på markeringerne i listen. Her burde du se helt fornuftige filtre. Kører det stadigvæk ikke, så prøv at poste et par af filtrene her, så vi kan tjekke dem.
Ahaaa. Der er en lille fejl i den oprindelige kode. Den forudsætter, at du har numeriske værdier i din liste. Når der er tale om tekster, skal du lige rette et par linier, så du får anførselstegnene med:
If iCount = 0 Then sTemp = sTemp & """" & myListBox.ItemData(oItem) & """" iCount = iCount + 1 Else sTemp = sTemp & "," & """" & myListBox.ItemData(oItem) & """" iCount = iCount + 1 End If
Yessir! Så virker det ;-) Jeg godkender dit første svar.
Jeg har faktisk en liste mere i samme formular, men den bygger på talværdier. Navnet på denne er Liste29. Er det samme kode som den liste vi har arbejdet med indtil nu?
Smider lige nogle ekstra point i, hvis du gider svare på dette :-)
Drop extra point. Nu skal vi bare have lukket denne her :o)
Hvis du vil bruge koden med din anden liste (talværdier), ja så skal du jo tilbage til den tidligere version uden anførselstegn.
Det mest elegante vil derfor være at du parameterstyrer funktionen, så du kan bruge den til begge lister:
Private Function GetDataFromListBox(myListBox As Control, NumericValues As Boolean) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer Dim Sep As String
iCount = 0 sTemp = ""
If NumericValues Then ' Hvis tal, så ingen anførselstegn Sep = "" Else ' Hvis tekst, så anførselstegn Sep = """" End If
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 Else sTemp = sTemp & "," & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
så skal du rette i kaldene til funtionen:
Private Sub Liste27_AfterUpdate() strWhere = "[AUF_WERK_ID] IN " & GetDataFromListBox(Liste27, False) Me.Filter = strWhere Me.FilterOn = True End Sub
Private Sub Liste29_AfterUpdate() strWhere = "[AUF_WERK_ID] IN " & GetDataFromListBox(Liste29, True) Me.Filter = strWhere Me.FilterOn = True End Sub
Private Function GetDataFromListBox(myListBox As Control, NumericValues As Boolean) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer Dim Sep As String
iCount = 0 sTemp = ""
If NumericValues Then ' Hvis tal, så ingen anførselstegn Sep = "" Else ' Hvis tekst, så anførselstegn Sep = """" End If
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 Else sTemp = sTemp & "," & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ") " ' Else ' MsgBox "Nothing was selected from the list", vbInformation ' strSQL = strSQL ' Exit Function 'Nothing was selected End If 'strip last comma from list End Function
Det er som om, at den nogen gange bruger den ene liste som kriterie, men til gengæld medtager alt fra den anden liste og omvendt
Det kan jo ikke lade sig gøre at listerne bliver blandet sammen. Der er jo tale om to helt uafhængige kald. Jeg er bange for at du ikke har fortalt hele historien om opbygningen.
Den struktur, vi er nået frem til, håndterer to scenarier: 1. Hvis du vælger på Liste_27, filteres formularen på AUF_WERK_ID 2. Hvis du vælger på Liste_29, filteres formularen på KOPF_TOUR
Det slår mig lige: Forestiller du dig, at du kan vælge værdier på begge lister SAMTIDIG? I så fald skal koden jo bygges helt anderledes op. Ellers må du lige dryppe et par ord om, hvad det er du gerne vil.
"Det slår mig lige: Forestiller du dig, at du kan vælge værdier på begge lister SAMTIDIG? I så fald skal koden jo bygges helt anderledes op."
Shit. Ja. Det er lige præcis det jeg forestiller mig :-/ Var sikker på, at når det kørte med den ene liste, kunnne jeg "bare" lige kopiere. Hvis det bliver for meget bøvl, lukker vi som sagt bare her, og så må jeg oprette et nyt spørgsmål. Helt ok med mig.
Ahaa. Ja, det er jo en helt anden historie. Så skal der jo lidt mere krydderi på. Har desværre ikke tid her til aften; så du må lige væbne dig med lidt tålmodighed.
Hersker der OG eller ELLER mellem de to lister (ja, det er lidt tricky)? "OG" betyder altså, at du kun vil se poster, som svarer til en markering på BEGGE lister. "ELLER" betyder at du vil se alle poster, der svarer til en markering på mindst EN AF listerne.
Så er jeg tilbage med den kombinerede løsning. Håber, du kan få det til at spille:
Option Compare Database Option Explicit
Dim strWhere As String Dim strWhere1 As String Dim strWhere2 As String
'Nulstil vars og fjern filter Private Sub Form_Open(Cancel As Integer) strWhere = "" strWhere1 = "" strWhere2 = "" Me.FilterOn = False End Sub
Private Sub Liste27_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Liste27, False) If Dummy = "" Then strWhere1 = "" Else strWhere1 = "[AUF_WERK_ID] IN " & Dummy End If OpdaterFilter End Sub
Private Sub Liste29_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Me.Liste29, True) If Dummy = "" Then strWhere2 = "" Else strWhere2 = "[KOPF_TOUR] IN " & Dummy End If OpdaterFilter End Sub
Private Sub OpdaterFilter() strWhere = "" If (strWhere1 <> "") And (strWhere2 <> "") Then strWhere = "(" & strWhere1 & ") AND (" & strWhere2 & ")" Else If strWhere1 <> "" Then strWhere = strWhere1 If strWhere2 <> "" Then strWhere = strWhere2 End If 'Debug.Print strWhere If strWhere = "" Then Me.FilterOn = False Else Me.Filter = strWhere Me.FilterOn = True End If End Sub
Private Function GetDataFromListBox(myListBox As Control, NumericValues As Boolean) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer Dim Sep As String
iCount = 0 sTemp = ""
If NumericValues Then ' Hvis tal, så ingen anførselstegn Sep = "" Else ' Hvis tekst, så anførselstegn Sep = """" End If
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 Else sTemp = sTemp & "," & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ")" Else GetDataFromListBox = "" End If End Function
Dim strWhere As String Dim strWhere1 As String Dim strWhere2 As String
'Nulstil vars og fjern filter Private Sub Form_Open(Cancel As Integer) strWhere = "" strWhere1 = "" strWhere2 = "" Me.FilterOn = False End Sub
Private Sub Liste27_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Liste27, False) If Dummy = "" Then strWhere1 = "" Else strWhere1 = "[AUF_WERK_ID] IN " & Dummy End If OpdaterFilter End Sub
Private Sub Liste29_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Me.Liste29, True) If Dummy = "" Then strWhere2 = "" Else strWhere2 = "[KOPF_TOUR] IN " & Dummy End If OpdaterFilter End Sub
Private Sub OpdaterFilter() strWhere = "" If (strWhere1 <> "") And (strWhere2 <> "") Then strWhere = "(" & strWhere1 & ") AND (" & strWhere2 & ")" Else If strWhere1 <> "" Then strWhere = strWhere1 If strWhere2 <> "" Then strWhere = strWhere2 End If 'Debug.Print strWhere If strWhere = "" Then Me.FilterOn = False Else Me.Filter = strWhere Me.FilterOn = True End If End Sub
Private Function GetDataFromListBox(myListBox As Control, NumericValues As Boolean) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer Dim Sep As String
iCount = 0 sTemp = ""
If NumericValues Then ' Hvis tal, så ingen anførselstegn Sep = "" Else ' Hvis tekst, så anførselstegn Sep = """" End If
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 Else sTemp = sTemp & "," & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ")" Else GetDataFromListBox = "" End If End Function Private Sub Vis_køreliste_Click()
Den sidste del omkring "Vis_køreliste" har jeg kopieret ind igen, da der ikke skete noget, når jeg trykkede på kommandoknappen i formularen. Det gør der så stadigvæk ikke.
Jeg har prøvet at lave en ny kommandoknap, men så kører den helt udenom de 2 lister som filter.
Har rodet lidt videre. Jeg fik klumret rundt i den kommandoknap, men tror jeg er nogenlunde på sporet igen. Nu er koden således:
Option Compare Database Option Explicit
Dim strWhere As String Dim strWhere1 As String Dim strWhere2 As String
'Nulstil vars og fjern filter Private Sub Form_Open(Cancel As Integer) strWhere = "" strWhere1 = "" strWhere2 = "" Me.FilterOn = False End Sub
Private Sub Liste27_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Liste27, False) If Dummy = "" Then strWhere1 = "" Else strWhere1 = "[AUF_WERK_ID] IN " & Dummy End If OpdaterFilter End Sub
Private Sub Liste29_AfterUpdate() Dim Dummy As String
Dummy = GetDataFromListBox(Me.Liste29, True) If Dummy = "" Then strWhere2 = "" Else strWhere2 = "[KOPF_TOUR] IN " & Dummy End If OpdaterFilter End Sub
Private Sub OpdaterFilter() strWhere = "" If (strWhere1 <> "") And (strWhere2 <> "") Then strWhere = "(" & strWhere1 & ") AND (" & strWhere2 & ")" Else If strWhere1 <> "" Then strWhere = strWhere1 If strWhere2 <> "" Then strWhere = strWhere2 End If 'Debug.Print strWhere If strWhere = "" Then Me.FilterOn = False Else Me.Filter = strWhere Me.FilterOn = True End If End Sub
Private Function GetDataFromListBox(myListBox As Control, NumericValues As Boolean) As String Dim oItem As Variant Dim sTemp As String Dim iCount As Integer Dim Sep As String
iCount = 0 sTemp = ""
If NumericValues Then ' Hvis tal, så ingen anførselstegn Sep = "" Else ' Hvis tekst, så anførselstegn Sep = """" End If
If myListBox.ItemsSelected.Count <> 0 Then For Each oItem In myListBox.ItemsSelected If iCount = 0 Then sTemp = sTemp & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 Else sTemp = sTemp & "," & Sep & myListBox.ItemData(oItem) & Sep iCount = iCount + 1 End If Next oItem GetDataFromListBox = "(" & sTemp & ")" Else GetDataFromListBox = "" End If End Function
Øhm. Først og fremmest: 1) Virker det, hvis du kun markerer elementer på Liste27? 2) Virker det, hvis du kun markerer elementer på Liste29? 3) Virker det, hvis du kun markerer ét elementer på hver liste?
Hvis du kan svare ja til alle 3 ovenfor, må der være et eller andet i din OG/ELLER logik, der svigter.
Koden giver dig de poster, der svarer til de markerede elementer fra Liste27 (med ELLER imellem), der SAMTIDIG svarer til de markerede elementer fra Liste29 (med ELLER imellem) - altså med OG imellem de to lister.
Prøv at forklare nærmere, hvad du mener der går galt - evt med et eksempel.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.