VBA om te mijden dat n-de record niet wordt gemaakt, maar een rapport wordt geopend

Status
Niet open voor verdere reacties.

MortovMolotov

Gebruiker
Lid geworden
10 jan 2018
Berichten
12
Dag iedereen,

Een vriend van mij is arts te België, waar de patiënten per prestatie (raadpleging) betalen; na die betaling krijgt de patiënt getuigschriftjes voor verstrekte hulp uit (klik hier voor een voorbeeld).

Een beetje achtergrondinformatie m.b.t. mijn vragen hierbij is de volgende (cfr. dus ook de link hierboven).

Als arts moet je de volgende informatie altijd duidelijk opschrijven:
- de naam vd patiënt
- datum vd consultatie
- de zescijferige code(s) m.b.t. terugbetaling; dit is van belang voor de mutualiteit, omdat die dan weten hoeveel ze de patiënt moeten terugbetalen; bv. consultatie bij een huisarts: 101076, ca. 20 euro terugbetaald, afhankelijk van je statuut; bv. bij een reumatoloog: 102653, 44 euro terugbetaald, 53 euro indien je een WIGW statuut hebt.
- het bedrag


De artsen hebben dergelijke getuigschriften verzameld in "boekjes" van telkens 50 van die getuigschriften. Telkens als zo'n boekje vol is, moet je het samengeteld bedrag en de datum van het laatste getuigschrift erop zetten.


Voor het bijhouden van deze "boekjes" heb ik een access database geschreven die operationeel is, mits men op de hoogte is van de bugs in het systeem.
Men kan dus alle data ingeven, en een rapport is beschikbaar om o.a. het samengeteld bedrag te berekenen.

Maar hier komen dus de bugs
1. in het formulier waar ik mijn data ingeef, heb ik via een combinatie van VBA code en field defaults al geregeld dat:
- bij het openen van een nieuw record (getuigschrift), de nummering automatisch +1 stijgt
- de datum en het "boekje", waarvan van het vorige getuigschrift (record) deel uitmaakte, automatisch worden overgenomen in het nieuwe record
- dit is logisch, gezien je 50 getuigschriften na elkaar van 't zelfde boekje invult, en bovendien hoef je de datum dus niet telkens opnieuw in te geven, hooguit enkele malen wat te wijzigen tijdens het ingeven van je gegevens (het is nl zo dat één boekje (van 50 getuigschriften) na twee, hooguit drie dagen volledig is opgebruikt; dit afhankelijk van het aantal patiënten dat een arts in die periode ziet

2. maar anderzijds had ik graag gewild dat na invullen van het vijftigste boekje
- hetzij alles gereset wordt voor het eerstvolgende record; alle velden leeg dus, want je begint aan een nieuw boekje; alsof je op ESC drukt dus
- hetzij er géén nieuwe record wordt aangemaakt, en meteen het rapport voor dat boekje wordt geopend; ergens logisch, gezien je dan moet beginnen samentellen
- en sowieso had ik op het formulier een knop gezet die het rapport voor het huidige boekje opent.

3. Ik slaag er maar niet in om een default value automatisch te laten selecteren voor het Codes field (= lookup list); bij voorkeur zou dat 102653 moeten zijn.


Hieronder volgen enkele gegevens m.b.t. de structuur van de database; een leeg bestand heb ik opgeladen via deze topic.
(mocht dit niet voldoende zijn, laat het me weten, dan kan ik eea hier aanvullen)

1. Design van Receipts tabel:
https://prnt.sc/hyeiex

2. DB Relationship
https://prnt.sc/hyeimo

3. Formulier om data in te geven
https://prnt.sc/hyej0z

4. SQL code van de query waarvan het rapport "AllReceipts" gebruik maakt:
Code:
SELECT Books.Book, Receipts.Nr, Receipts.CDate, Receipts.Codes, Receipts.Amount, Receipts.PaymentMethod, Receipts.RDate, Receipts.Comments
FROM Books INNER JOIN Receipts ON Books.ID = Receipts.Book
ORDER BY Books.Book, Receipts.Nr;

5. De VBA code voor hetgeen ik in puntje 1. hierboven heb beschreven
Code:
Option Compare Database
Option Explicit

Private Sub Form_Current()
   Dim RS As DAO.Recordset
      
   On Error Resume Next
   
   ' Exit if not on the new record.
   If Not NewRecord Then Exit Sub
   
   ' Goto the last record of the form recordset (to autofill form).
   Set RS = RecordsetClone
   RS.MoveLast
      
   ' Exit if you cannot move to the last record (no records).
   If Err <> 0 Then Exit Sub
   
   Painting = False
   
   If NrTxt <= 50 Then
    BookCombo = RS(BookCombo.ControlSource)
    CDateTxt = RS(CDateTxt.ControlSource)
    NrTxt = RS(NrTxt.ControlSource) + 1
   Else
    BookCombo = ""
    CDateTxt = ""
   End If

   Painting = True

End Sub
Bekijk bijlage Boekjes - leeg.zip


Alvast bedankt voor jullie advies,

Mortov Molotov
 
Een heel verhaal, waar ik eerlijk gezegd na eerste lezing nog niet alles van snap. Dit bijvoorbeeld:
- dit is logisch, gezien je 50 getuigschriften na elkaar van 't zelfde boekje invult, en bovendien hoef je de datum dus niet telkens opnieuw in te geven, hooguit enkele malen wat te wijzigen tijdens het ingeven van je gegevens (het is nl zo dat één boekje (van 50 getuigschriften) na twee, hooguit drie dagen volledig is opgebruikt; dit afhankelijk van het aantal patiënten dat een arts in die periode ziet
mag voor jullie heel logisch lijken, voor mij is het dat bepaald niet. Eerder zeg je namelijk dit:
Telkens als zo'n boekje vol is, moet je het samengeteld bedrag en de datum van het laatste getuigschrift erop zetten.
En wat jij dus lijkt te doen, is steeds de datum van het eerste record overnemen, en niet de laatste. En die zou dus niet overgenomen hoeven te worden, want de Defaultvalue van dat datumveld zou per definitie de invuldatum = Date() moeten zijn. Dus daar is een simpele oplossing voor.

Het resetten van het nummer is ook relatief simpel als je een functie maakt/gebruikt, en niet zomaar de bestaande waarde met 1 verhoogt. Ik zou persoonlijk een batchnummer toevoegen aan het geheel, zodat je ook kan zien hoeveel boekjes er zijn gemaakt, maar vooral is dat handig omdat je dan nog veel makkelijker de batch kunt controleren. Zo'n functie heb ik regelmatig al gepost (onder de naam "Volgnummer") en dan ook nog eens in verschillende varianten; een die bijvoorbeeld per jaar opnieuw nummert (heb je niet zoveel aan) of een die per maand opnieuw begint, of per klant. Die laatste variant lijkt erg op jouw batchvariant. Mits je dus die batches kunt onderscheiden van elkaar. Maar zelfs zonder dat is het nog wel te doen op basis van het getal 50.

Ik zal er op een rustig moment naar kijken!
 
Het blijft even stil, dus dan hou ik het ook nog even rustig :). Wel een simpele oplossing nog voor dit 'probleem':
3. Ik slaag er maar niet in om een default value automatisch te laten selecteren voor het Codes field (= lookup list); bij voorkeur zou dat 102653 moeten zijn.
Je kunt die waarde gewoon als standaardwaarde instellen voor het veld; om MultiValue velden zou je eigenlijk met een grote boog heen moeten lopen want ze zijn gruwelijk (en niet uitwisselbaar, en dat is een stevige zonde in de db wereld) dus om dat met code te doen valt nog niet mee (moet je recordsets maken en insert queries etc). Maar een standaardwaarde kun je gewoon in het veld instellen.
 
Dag Octafish,

Dag voor je reactie en sorry voor mijn laattijdige respons; ben zelf ook even aan het werk geweest, helaas zonder veel succes:

1. Maar eerst zal ik wat duidelijkheid brengen omtrent de tegenstrijdigheden die je hebt vermeld:
Na een bezoek bij een Belgische arts krijg je altijd een getuigschrift mee voor verstrekte hulp; immers, in tegenstelling tot in Nederland, betaal je als patiënt de arts en krijg je een deel van het geld terug via de mutualiteit (ziekteverzekering van staatswege); hoeveel geld, hangt af van de codes vermeld op zo'n getuigschrift. Een Belgische arts dient bij het RIZIV (jullie RIBIZ) boekjes aan te vragen, die 50 van zo'n getuigschriften bevatten (bv. genummerd van 16*0025/01 tot en met 16*0025/50). Eens zo'n boekje "vol" is, nl alle getuigschriften zijn uitgereikt, dient de arts de bedragen op te tellen om tot het totaalbedrag van zo'n boekje (in dit voorbeeld 16*0025) te komen.

Gezien na elke consultatie zo'n getuigschrift wordt afgeleverd, is zo'n boekje na 50 consultaties opgebruikt; in het geval van mijn kennis, die zo'n 16 à 18 patiënten per dag ziet, spreken we dus over één boekje per drie dagen. Op deze manier zijn de datums voor elk getuigschrift bijna altijd dezelfde; bv. 16*0025/01 -> 19 op 03-04-2016, 16*0025/20 -> 35 op 04-04-2016 en 16*0025/36 -> 50 op 05-04-2016.

Als je alle getuigschriften (tabel "Receipts") van boekje 16*0025 na elkaar invult via het desbetreffende formulier, is het eleganter om dus steevast enkele waarden reeds automatisch te laten invullen, ipv. telkens lege velden opnieuw zelf in te tikken, of ctrl+apostrofe te tikken.

Je zei ook dat ik met deze code telkens de datum van het eerste record zou overnemen; in de praktijk blijkt het wel degelijk altijd de datum vd voorafgaande record te zijn - wat de bedoeling was.

2. Maar wat dus niet lukt, is om alle velden leeg te maken eens je een nieuwe record maakt nadat je getuigschrift nr 50 hebt ingevuld; in dàt geval begin je immers met een volgend boekje, bv. 16*0026, te beginnen met nr 1 (en niet nr. 51, want dat bestaat niet in deze context), datum leeg, want niet noodzakelijk dezelfde als getuigschrift 16*0025/50.

Ik heb al wat proberen te experimenteren met eigen wijzigingen, doch zonder succes:

a. ten eerste heb ik de code wat aangepast
Code:
   Dim rs As DAO.Recordset
      
   ' Exit if not on the new record.
   If Not NewRecord Then Exit Sub
   
   ' Goto the last record of the form recordset (to autofill form).
   Set rs = RecordsetClone
   rs.MoveLast
      
   ' Exit if you cannot move to the last record (no records).
   ' If Err <> 0 Then Exit Sub
   
   Painting = False
   
   If (NrTxt Mod 50) <> 0 Then
    BookCombo = rs(BookCombo.ControlSource)
    CDateTxt = rs(CDateTxt.ControlSource)
    NrTxt = rs(NrTxt.ControlSource) + 1
   Else
    NrTxt = 1
   End If

   Painting = True

Zoals je ziet, heb ik de volgende regel weggelaten:
Code:
On Error Resume Next
Ook de if-then-else clause werd wat gewijzigd, cfr. ook de code in topic start.

Hierbij kwam ik erachter dat de else clause niet werd gehaald gezien een error nu wel zichtbaar werd: in de receipts tabel had ik een validation rule (>0;<51) geïmplementeerd (via table design). Na record 50 werd, ondanks alles 51 ingevuld, met een error als gevolgd.

Maar iig krijg ik het niet voor elkaar om van 50 terug naar 1 te springen, ondanks bovenstaande code...
... of zelfs nog maar met een volledige nieuwe aanpak, zoals hier beschreven op de manier van Allen Browne... to no avail, helaas :(


3. En dan nog ff ivm. dit:
Het blijft even stil, dus dan hou ik het ook nog even rustig :). Wel een simpele oplossing nog voor dit 'probleem':

Je kunt die waarde gewoon als standaardwaarde instellen voor het veld; om MultiValue velden zou je eigenlijk met een grote boog heen moeten lopen want ze zijn gruwelijk (en niet uitwisselbaar, en dat is een stevige zonde in de db wereld) dus om dat met code te doen valt nog niet mee (moet je recordsets maken en insert queries etc). Maar een standaardwaarde kun je gewoon in het veld instellen.

Dag Octafish, ik weet dat die multivalued fields zonde zijn, want inderdaad niet uitwisselbaar; oorspronkelijk werkte ik met een join table, maar op die manier was het dan weer onmogelijk om een checked list box (zoals op dit formulier https://prnt.sc/hyej0z) te maken. Toch niet met mijn kennis....

Maar het klopt dat dit allerminst een elegante manier is qua uitwisselbaarheid; mocht ik op termijn van database programma wensen over te schakelen, zal ik een create table query moeten maken om de gegevens via een join table in de nieuwe software te steken, vermoed ik. Het zij zo :)

Maar inderdaad: de standaard waarde kan worden ingevuld, en verschijnt steevast in een datasheet form
Echter, de waarde blijkt niet standaard te zijn aangevinkt als ik werk met het invulformulier. :(



Hopelijk is mijn vraag duidelijker nu :)


alvast bedankt voor je tijd tot nu toe!!!

AANVULLING

Met deze code werkt alvast het systeem om na 50 getuigschriften (records) alles te resetten, te starten met nr. 1

Code:
Dim RS As DAO.Recordset
     
   On Error Resume Next
   
   ' Exit if not on the new record.
   If Not NewRecord Then Exit Sub
   
   ' Goto the last record of the form recordset (to autofill form).
   Set RS = RecordsetClone
   RS.MoveLast
     
   NrTxt = RS(NrTxt.ControlSource)
   
   If (NrTxt Mod 50) <> 0 Then
    BookCombo = RS(BookCombo.ControlSource)
    CDateTxt = RS(CDateTxt.ControlSource)
    NrTxt = NrTxt + 1
    RS.Update
   Else
    NrTxt = 1
    RS.Update
   End If


Rest nu nog de manier om 102653 standaard aangevinkt te laten, en we zijn klaar. :thumb:


Mortov Molotov
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan