Probleem met vba code voor sortering volgens datum in ms access

Status
Niet open voor verdere reacties.
printscreen_sorteervoorbeeld.jpg


In dit printscreentje van die eerder vermeldde Frm_Controle_prioriteit (waar ik de kolommen even netjes op volgorde van de criteria heb gezet (en de priorkolom manueel hernummerd) zie je de volgorde zoals ze zou moeten zijn:
  1. Act (enkel zij dus die Act aangevinkt hebben)
  2. PrioriteitGemeente (de lui met een 1 komen voor de lui met 0, en in geval van gelijkheid geeft criteria 3 en indien ook gelijk criteria 4 dan voorrang
  3. PrioriteitCategorie (hoe lager het cijfer hoe meer prioriteit
  4. Datum Aanvraag (de oudste aanvrager heeft natuurlijk voorrang)

@ etraas Nummeren van het veld prior gebeurd door de VBA code onder de knop "toevoegen op de ......." als dat je vraag is van waar die prior hernummeren gebeurd?

@Octafish
Die eenvoudige querie doet het inderdaad goed maar de dametjes bij ons die handelingen van kopieren en plakken steeds laten doen heeft al enige wrevel veroorzaakt :confused: Eenmaal dat ze wisten dat het met een druk-op-het-knopje ook zou moeten gaan willen ze natuurlijk dat knopje zien werken :D Probleem is als we die querie de baas laten spelen dat hij dan manuele eerder gemaakte prioriteitsverschuivingen (wegens die dringende redenen en zo) gewoon aan zijn laars lapt.
 
je query qryWachtlijst_Actief wordt dan :

PHP:
SELECT Tbl_wachtlijst.PrioriteitGemeente, Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst], Tbl_wachtlijst.Prior, Tbl_wachtlijst.Act, Tbl_wachtlijst.Pas, Tbl_wachtlijst.Geschrapt, Tbl_wachtlijst!BNaam & " " & Tbl_wachtlijst!BVoornaam AS Naam_voornaam, Tbl_wachtlijst.BNaam, Tbl_wachtlijst.BVoornaam, Tbl_wachtlijst.BVWoonplaats, Tbl_wachtlijst.Categorie, Tbl_wachtlijst.Tijdelijk_opgenomen, Tbl_wachtlijst.Instellingsnummer
FROM Tbl_wachtlijst
WHERE (((Tbl_wachtlijst.Prior) Is Not Null) AND ((Tbl_wachtlijst.Act)=True) AND ((Tbl_wachtlijst.Pas)=False) AND ((Tbl_wachtlijst.Geschrapt)=False) AND ((Tbl_wachtlijst.Instellingsnummer)=1))
ORDER BY Tbl_wachtlijst.PrioriteitGemeente DESC , Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst];

Net voor je je formulier een refresh geeft kan je deze code gebruiken :

PHP:
 Set rs = dbsCurrent.OpenRecordset("SELECT Tbl_wachtlijst.PrioriteitGemeente, Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst], Tbl_wachtlijst.Prior " _
                                        & "FROM Tbl_wachtlijst " _
                                        & "WHERE (((Tbl_wachtlijst.Prior) Is Not Null) And ((Tbl_wachtlijst.Act) = True) And ((Tbl_wachtlijst.Pas) = False) And ((Tbl_wachtlijst.Geschrapt) = False) And ((Tbl_wachtlijst.Instellingsnummer) = 1)) " _
                                        & "ORDER BY Tbl_wachtlijst.PrioriteitGemeente DESC , Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst]; ")

    Dim prio As Integer
    prio = 1
    
    Do Until rs.EOF
    
     rs.Edit
      rs!Prior = prio
     rs.Update
     prio = prio + 1
    
    rs.MoveNext
    Loop

Wil je dat eens proberen.
 
Snap het, je hernummert met de grove borstel achteraf nog eens de actieve zijde zonder achter de vorige code te kijken, dat is een oplossing die lijkt te lukken Demuynck Simonne was eerst niet juist en nu wel. :thumb:

Ik heb dus de code onder de knop "toevoegen op correcete.." gezet
De code ziet er nu zo uit:
Code:
Private Sub cmdToevoegen_Click()

    'Zoek de correcte plaats:
    'De gemeente heeft voorrang, gevolgd door categorie en dan volgens datum
    
    Dim dbsCurrent As Database
    Dim rs As Object
    Dim currNr, currBVWoonplaats, PriorGemeente, reden As String
    Dim currcat, currInst, currPrior, newPrior As Long
    Dim currDatum As Date
    Const strcJetDate = "\#mm\/dd\/yyyy\#"
        
    Set dbsCurrent = CurrentDb
    
    'geef de inwoners met dezelfde gemeente als de instelling prioriteit
    Set rs = dbsCurrent.OpenRecordset("select IPlaats from Tbl_Instelling where IHuidig = true")
    If (Not rs.EOF) Then
        PriorGemeente = rs(0)
    Else
        MsgBox "Geen gemeente van de huidige instelling gevonden", vbExclamation
        Exit Sub
    End If
    
    currNr = Me.SubWachtlijst_Niet_Actief.Form!Nr.Value
    Set rs = dbsCurrent.OpenRecordset("select Instellingsnummer from Tbl_Wachtlijst where [Nr Wachtlijst] = '" & currNr & "'")
    If (Not rs.EOF) Then
        currInst = rs(0)
    End If
    
    Set rs = dbsCurrent.OpenRecordset("SELECT Prior, BVWoonplaats, [Datum aanvraag] as datum, Nz(Sorteernummer,6) as Sorteernr " & _
                "FROM Tbl_Wachtlijst LEFT JOIN Categorie ON Tbl_Wachtlijst.Categorie = Categorie.Categorie " & _
                "WHERE [Nr Wachtlijst] = '" & currNr & "'")
    If (Not rs.EOF) Then
        rs.MoveFirst
        currPrior = rs("Prior")
        currBVWoonplaats = rs("BVWoonplaats")
        currBVWoonplaats = Nz(currBVWoonplaats, "Onbekend")
        currDatum = rs("Datum")
        currDatum = Nz(currDatum, Date)
        currcat = rs("Sorteernr")
    End If
    
    Set rs = dbsCurrent.OpenRecordset("SELECT [Nr Wachtlijst], Prior, BVWoonplaats, [Datum aanvraag] as datum, Nz(Sorteernummer,6) as Sorteernr " & _
                    "FROM Tbl_Wachtlijst LEFT JOIN Categorie ON Tbl_Wachtlijst.Categorie = Categorie.Categorie " & _
                    "WHERE Prior > 0 ORDER BY Prior;")
    rs.MoveFirst
    Do While (Not rs.EOF)
        newPrior = rs("Prior")
        If (rs("BVWoonplaats") <> PriorGemeente And currBVWoonplaats = PriorGemeente) Then
            Exit Do
        End If
        If ((rs("BVWoonplaats") = PriorGemeente And currBVWoonplaats = PriorGemeente) Or (rs("BVWoonplaats") <> PriorGemeente And currBVWoonplaats <> PriorGemeente)) Then
            'volgens categorie
            If (currcat < rs("Sorteernr")) Then
                Exit Do
            End If
            If (currcat = rs("Sorteernr")) Then
                'volgens datum
                If (rs("datum") > currDatum) Then
                    Exit Do
                End If
            End If
        End If
        rs.MoveNext
    Loop
    
    Query = "update Tbl_Wachtlijst set Prior = Prior + 1 where Prior >= " & _
            newPrior & " and instellingsnummer = " & currInst
    dbsCurrent.Execute (Query)
    
    Query = "update Tbl_Wachtlijst set Prior = " & newPrior & ", Act = true, Pas = false, Geschrapt = false " & _
            " where [Nr Wachtlijst] = '" & currNr & "'"
    dbsCurrent.Execute (Query)
    
    reden = InputBox("Reden toevoeging:")
    
    Query = "insert into Tbl_prioriteitwijzigingen([Nr wachtlijst],[Reden wijziging],[Datum wijziging],Instellingsnummer,Oude_PriorNr,Oude_Wachtlijst,Nieuwe_PriorNr,Nieuwe_Wachtlijst) " & _
            "values('" & currNr & "','" & reden & "'," & Format(Date, strcJetDate) & "," & currInst & ",0,'Passief'," & newPrior & ",'Actief')"
    dbsCurrent.Execute (Query)
    
Set rs = dbsCurrent.OpenRecordset("SELECT Tbl_wachtlijst.PrioriteitGemeente, Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst], Tbl_wachtlijst.Prior " _
                                        & "FROM Tbl_wachtlijst " _
                                        & "WHERE (((Tbl_wachtlijst.Prior) Is Not Null) And ((Tbl_wachtlijst.Act) = True) And ((Tbl_wachtlijst.Pas) = False) And ((Tbl_wachtlijst.Geschrapt) = False) And ((Tbl_wachtlijst.Instellingsnummer) = 1)) " _
                                        & "ORDER BY Tbl_wachtlijst.PrioriteitGemeente DESC , Tbl_wachtlijst.PrioriteitCategorie, Tbl_wachtlijst.[Datum aanvraag], Tbl_wachtlijst.[Nr wachtlijst]; ")
 
    Dim prio As Integer
    prio = 1
    
    Do Until rs.EOF
    
     rs.Edit
      rs!Prior = prio
     rs.Update
     prio = prio + 1
    
    rs.MoveNext
    Loop
    
    Me.SubWachtlijst_Actief.Requery
    Me.SubWachtlijst_Geschrapt.Requery
    Me.SubWachtlijst_Niet_Actief.Requery
    
End Sub

:thumb: Ik test het nog verder op een copie van de originele DB (moet daar een paar dingen aanpassen aangezien de DB door het kiezen van het instellingsnummer in nog 8 andere instellingen gebruikt wordt), en meldt dan terug maar alvast bedankt Etraas
:confused: Maar wat ik nu al zie is dat eventueel manueel aangepaste "dringende" priors, door de knop "verplaats naar" te hebben gebruikt, herberekend worden en aldus gewijzigd wat niet zou mogen. Aangezien er in de originele DB nog foutafhandeling zit en messageboxen laat ik voorlopig een messagebox verschijnen dat nze dametjes waarschuwt dat hun manuele wijzigingen ongedaan worden gemaakt, maar zoals gezegd is dat eerder uitzonderlijk dat ze die gebruiken.
Ik heb verder even de teveel gestripte zaken terug toegevoegd aan de DB waardoor de andere knoppen (zoals schrappen, passief maken en terug passief maken) weer werken en er beter getest kan worden.
 

Bijlagen

  • wachtlijst_met_10_met_code_etraas.rar
    86,8 KB · Weergaven: 21
Laatst bewerkt:
Misschien dat de aanvragers die verplaatst worden manueel ergens best een ID krijgen in een aparte gekoppelde tabel en dat er dan bij het "toevoegen op de juiste plaats" een andere dynamische recordset wordt gemaakt waarin deze "uitzonderingen" dus uitgesloten worden? Anders zullen er blijven conflicten komen?
'k heb die knoppen "verplaatsen naar" en "toevoegen onderaan" voorlopig verborgen in de DB. Iemand die weet hoe dit anders op te lossen?
 
stuur even je e-mail adres naar vbb@etsoft.nl , praten we zo verder . Misschien tegen de forum regels maar dat is toch handiger.
Email adres is een paar dagen geldig !
 
Ik vind dat het probleem lang genoeg geduurd heeft :)
Jouw probleem is eigenlijk atypisch voor automatisering; enerzijds wil je gautomatiseerd records prioriseren, en aan de andere kant wil je handmatig volgordes kunnen veranderen. Het ene staat echter haaks op het andere: een nummer automatisch toekennen kan alleen als alle records die genummerd moeten worden, voldoen aan de gestelde criteria. Alleen dan krijg je correcte nummers. Wil je een record een hogere of lagere prioriteit toekennen, dan kan dat alleen als dat record binnen de gestelde criteria dat hogere of lagere nummer 'verdient'; is dat niet het geval, dan wordt bij de volgende bijwerkactie de volgorde weer veranderd. Maar dat hoef ik je niet uit te leggen, dat heb je zelf al lang en breed ondervonden!

Bij handmatig hernummeren, kun je dus geen rekening houden met de eerder bepaalde criteria. Dat betekent, dat je de recordset regel voor regel door moet lopen, en de records moet hernummeren. Een truc die ik daarvoor gebruik, is een Keuzelijst met een Spinnercontrol. In de keuzelijst laad je de recordbron die hernummerd moet worden, en op een actie op de spinner verplaats je de records. Ik heb e.e.a. ingebouwd op een apart formulier (Frm_Wachtlijst_Aanpassen_Spinner) waar je dus een record uit de wachtlijst selecteert, en dat vervolgens omhoog of omlaag verplaatst. Kijk maar eens of je dat kunt inbouwen in je systeem; volgens mij hoef je alleen maar een knop op je hoofdformulier te maken met de naam <Handmatig verplaatsen> o.i.d.
 

Bijlagen

  • Wachtlijst met Spinner.rar
    96,5 KB · Weergaven: 27
Ik vind dat het probleem lang genoeg geduurd heeft :)
Jouw probleem is eigenlijk atypisch voor automatisering; enerzijds wil je gautomatiseerd records prioriseren, en aan de andere kant wil je handmatig volgordes kunnen veranderen.

:p Vertel me zoiets; de secretaresses willen dat het vanzelf gaat én liefst juist en tegelijk willen ze nog hun eigen zinnetje doen (denk dat dat typisch is voor de dametjes) :p

Het probleem is nog aanwezig; als je, met de vba code van etraas uitgeschakeld, bv een catg 12 client dus opschuift volgens het spinner systeem naar bv plaats 3 (je moet wel dus ook telkens klikken om één plaats op te schuiven en dat wordt dus veel klikken in een list met bv 150 actieve aanvragers) en dan als je een andere cliënt met bv cat 12 passief maakt en terug "toevoegt op de juiste plaats" nestelt die zich netjes voor die eerder verplaatste cliënt wat dus niet mag.

Misschien een manier vinden om de cliënten die je "atypisch" verplaatst via de knop "verplaats naar" uit te sluiten van de verdere berekeningen die gebeuren bij "toevoegen op de correcte plaats" (ik heb in bijgevoegd voorbeeld, met de spinner van Michel in verwerkt, een veld "prioruitzondering" bijgemaakt in de Tbl_wachtlijst dat automatisch aangevinkt wordt als de aanvrager verplaatst wordt en uitgevinkt als hij/zij passief of geschrapt wordt). Het vinkje zorgt er ook voor dat we direct zien dat het om een speciaal geval gaat.
 

Bijlagen

  • wachtlijst_met_10_met_code_etraas_met_prioruitzondering.rar
    95,5 KB · Weergaven: 16
Laatst bewerkt:
De methode met de 'spinner' is een handmatige correctie, die geen rekening houdt met de sorteervolgorde die je zelf hebt bedacht. Je moet dus wel eerst sorteren met de criteria die je nu gebruikt; de spinner is geen vervanging daarvan. Want dan blijf je inderdaad schuiven tot je scheel ziet...

Dus de werkwijze zou dan zijn: eerst de automatische sortering uitvoeren, en dan de correctie daarop met de spinner. Jouw probleem is niet zozeer automatisch sorteren op basis van vaste criteria, dat lukt wel. Handmatig sorteren lukt ook, met de spinner. Maar zodra je een nieuwe automatische sortering doet, ben je de pineut, want alle records worden dan weer op hun eigen merites beoordeeld, dus een record dat met de hand omhoog is verplaatst, krijgt alsnog weer een lagere plek. En dan kun je dus weer opnieuw beginnen.

De handmatig verplaatste records uitsluiten van de automatische sortering zou een oplossing kunnen zijn, ware het niet dat bij automatisch nummeren moeilijk rekening kan worden gehouden met reeds met de hand vastgelegde nummers; het resultaat is dan dat je dubbele nummers krijgt. Misschien is dat overigens een optie waar je mee zou kunnen leven: een record met Prior 8* is dan bijvoorbeeld handmatig toegewezen, en valt qua volgorde dan tussen Prior 8 en Prior9.

Een veel ingewikkelder methode is om via een functie de records te hernoemen, op basis bijvoorbeeld van een extra Ja/Nee veld [Handmatig]. Je gebruikt dan een teller om nieuwe nummers te genereren, opent de tabel met records via een recordset, en update elk veld prior met de nieuwe tellerwaarde. In de loop verhoog je met elk record de teller. Of zoiets. Of je het daar helemaal waterdicht mee krijgt weet ik overigens zo niet...
 
IK had dat met die dubbele nummers dus al ondervonden en stel het even aan de dames voor om als ze daar mee kunnen leven. Anders laten we het zo.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan