Data validering formulier VBA

Status
Niet open voor verdere reacties.

tonydewilde

Gebruiker
Lid geworden
9 dec 2011
Berichten
10
Beste mensen

Ik heb eigenlijk een vier tal vragen betreffende datavalidering van controls op een formulier. Ik heb een ongebonden dialoog formulier . Hierop maken de gebruikers dan hun keuze tussen waarden in comboboxen en dergelijke, er wordt dan een SQL string gebouwd die ik dan gebruik om een query te filteren die aangesloten is op een rapport . Ik laat dan het rapport openen en afdrukken en mailen en nog van dat moois .
MAAR in sommige gevallen wil ik niet dat een combobox leeg blijft wanneer een andere gevuld is met een waarde . BVB combobox gewicht bevat > < >= en <= het textveld gewicht daar kan men een getal in tijpen .

Mijn eerste vraag : ik zou willen dat in het tekstvak gewicht enkel cijfers rechts van het decimaal teken kunnen getijpt worden en maximaal twee na het decimaal teken . Stel dat hier iemand driecijfers intypt na de komma en de filter werkt niet goed . De notatie staat in op vast en 2 cijfers na de komma .Jammer dat men in het vak meer cijfers kan typen :evil:

Mijn tweede vraag : Stel dat wanneer in de combobox niets gekozen wordt , dan wil ik dat deze rood kleurt , dat lukt aardig : de validering van het formulier gebeurt via een subprocedure. Probleem en mss kan ik het algemeen stellen .

Wanneer een eigenschap van een control op een formulier gewijzigd wordt via VBA dan heb ik gezien als ik het formulier sluit en terugopent dat de oorspronkelijke eigenschappen zich niet herstellen , eens gewijzigd altijd gewijzigd ????.
Moeten de oorspronkelijke eigenschappen van de controls die men verandert eerst worden opgeslagen in variabelen en dan bij het sluiten van het formulier opnieuw aan de gewijzigde controls worden gekoppeld ? .:confused:

Mijn derde vraag : Stel dat men een filter heeft gelanceerd via een commandbotton op het formulier is het mogelijk om daar een knop onder te maken met wis alle gemaakte keuzes . Gevolg zou moeten zijn dat alle controls in 1 klap leeg worden . :cool:

Mijn vierde vraag
Last but not least



een subprocedure en een functie verschillen omdat men bij een functie een uitkomst kan meeoverplaatsen naar een gebeurtenisprocedure . Bij een subprocedure kan dit niet.

Nu ben ik erin geslaagd dat toch te doen via een glabale variabele te definieren in de allereerste lijn van de module . Public x as string
compare databases
option explicit

op die manier kan ik een string die inhoud krijgt in een subprocedure , toch aanroepen in een andere procedure . Ik ben een beke verward is dat een alternatief op een functie routine ?. :eek:

Mvg
TDW
 
Beste tonydewilde. Het helpt om een voorbeeldbestand bij jouw uitleg te posten. En ook even aandacht te geven aan de spelling zodat het helemaal helder wordt.
 
Wat is het verschil tussen:
ik zou willen dat in het tekstvak gewicht enkel cijfers rechts van het decimaal teken kunnen getijpt worden en maximaal twee na het decimaal teken.
?
Ik vermoed dat je ofwel alleen cijfers links van het decimaal teken wilt hebben en twee cijfers na het decimaalteken.
Dat betekent dus dat je de tekstwaarde uit het tekstvak moet controleren ofwel tijdens het typen, ofwel nà het typen. In het eerste geval kun je controleren of de ingevoerde tekst uit cijfers bestaat (met If Not IsNumeric(Me.Tekstvak.Text) bijvoorbeeld), gebruik je de AfterUpdate gebeurtenis dan kun je de ingevoerde tekst met Split toewijzen aan een matrix variabele. Daarbij moet de eerste arraywaarde dan met IsNumeric worden gecontroleerd, en de tweede met Len(IsNumeric(....)) etc. Je kunt, als je dan toch bezig bent, gelijk controleren of er meer dan één scheidingsteken is getypt (mag natuurlijk ook niet). Je kijkt dus of de of het verschil tussen LBound en Ubound exact 1 is. Zo niet, dan heb je meer dan één scheidingsteken.
 
Om op de overige vragen terug te komen:
2. Een formulier onthoudt zijn instellingen die je via vba verandert doorgaans niet. Als dat bij jou wel gebeurt, dan heb je misschien Public variabelen gebruikt die worden gebruikt bij het starten van het formulier.
3. Een wisknop is behoorlijk simpel te maken (behalve bij een keuzelijst met meervoudige keuze, daar is het wat ingewikkelder). Me.cboKeuzelijst="" bijvoorbeeld maakt een keuzelijst leeg.
4. Een functie levert in beginsel een uitkomst op, en een procedure voert acties uit. Dat is het grote verschil. Met een functie kun je ook acties uitvoeren, maar tegelijkertijd het resultaat teruggeven aan de vragende opdracht. Bijvoorbeeld: door een functie als String te gebruiken kun je een geselecteerd bestand van een dialoogvenster terugkrijgen als uitkomst. Of, door hem als Boolean te gebruiken, kun je controleren of een actie is gelukt (Boolean=True) of niet (Boolean=False). Een public variabele kun je ook gebruiken om waarden 'mee te nemen' voor later gebruik, maar als je niet uitkijkt, kun je ineens met de nog opgeslagen waarde worden geconfronteerd waar je een ander resultaat verwacht.
 
Bedankt voor de respons .
Stel dat bij de validering van een tekstvak of combobox ergens staat ...

If Is null (ME.txtgewicht.value) then
Msgbox “u mag deze optie niet leeg laten, lege waarden niet toegestaan”
Exit sub
End if

En dan klikt er iemand op de algemene wisknop zoals octafish zegt dan komt er in me.txtgewicht.value een lege string. Deze is waarschijnlijk niet te onderscheppen met de logische test hierboven of vergis ik me . Excuses kan dit ook zelf uit testen maar zit hier op mijn werk ff te gluren .

Als ik het ook goed begrijp , kan ik dus in sommige gevallen met de kennis van subprocedures maar niet van functies (vind ik moeilijk) toch mijn plan trekken door public variabelen te maken heb gezien dat dit ook lukt met private variabelen zolang ze maar gans bovenaan de module staan .

mvg
TDW
 
Tekstvakken zijn altijd (de naam zegt het al) objecten die tekst bevatten. Bij het uitlezen ervan kun je dus simpel checken en leegmaken. Leegmaken doe je dan met Me.txtGewicht.Vlaue="".

Een procedure is doorgaans simpel om te zetten naar een functie door (Private) Sub te vervangen door (Private/Public) Function. Wil je de output van de nieuwe functie gebruiken, dan wijs je aan de functie een variabele type toe. Je laatste stap in de functie is dan de berekende waarde toe te wijzen aan de functie.

Voorbeeldje:
Code:
Public Function DatumKlaar(Datum As Date, WerkDagen As Integer, Optional WerkWeek As Integer) As Date
     DatumKlaar = DateAdd("d", WerkDagen + (iPlus * iWeek), Datum)
Op een tekstveld roep je de functie aan met de variabelen Datum, werkdagen (werkt iemand 4 dagen, of 5 dagen bijvoorbeeld) en/of werkweek

En nog één:
Op een formulier wil ik controleren of een ingevulde waarde ook bestaat in de tabel. Ik gebruik daarvoor de query van een formulier, en het tekstveld.

Code:
    sWaarde = ctlPrevious.Value
    MsgBox fZoekOp(sWaarde, Me)

Code:
Function fZoekOp(ZoekVeld As String, Optional frm As Form) As Boolean
Dim fld As DAO.Field
Dim strSQL As String
    
    strSQL = frm.RecordSource
    If Not Left(UCase(strSQL), 6) = "SELECT" Then
        If InStr(1, strSQL, "[") = 0 Then strSQL = "[" & strSQL & "]"
        strSQL = " SELECT * FROM " & strSQL
    End If
    With CurrentDb.OpenRecordset(strSQL)
        While Not .EOF And Not fZoekOp
            For Each fld In .Fields
                If fld.Value = ZoekVeld Then
                    fZoekOp = True
                    Exit For
                End If
            Next
            .MoveNext
        Wend
    End With
End Function

Deze functie levert TRUE op als de waarde gevonden is, en FALSE als hij niet bestaat.

Ik zou mij aanleren om met functies te werken, vanwege de houdbaarheidsproblemen van publieke variabelen, zoals ik eerder al aangaf.
 
Omdat je een verkeerde check doet op het tekstvak. Zoals ik eerder al uitlegde, is een tekstvak ook echt een tekstvak. Dat kun je dus niet op Null checken, dat levert altijd een verkeerde uitkomst op. Je maakt het veld wel op de juiste manier leeg; je moet het op dezelfde manier checken op inhoud!
 
Een tekststring kan wel degelijk de waarde NULL hebben.
Daar zit het probleem niet.

Probleem zit hierin.
Met de knop Wissen maak je je tekstvak niet NULL maar vul je deze met een lege string.
Vervolgens check via je knop Leeg of je tekstvak NULL is.
Dat is niet zo, je tekstvak bevat een lege string.
Leeg is niet hetzelfde als NULL.
Null wil zeggen onbepaald, de waarde is niet te bepalen.

Oplossing 1

Wijzig je code achter de knop Wissen in

Me.txtnaam.Value = Null

Code achter de knop Leeg laat je staan

Oplossing 2

Wijzig je code achter de knop Leeg in

If Len(Me.txtnaam & "") = 0 Then

Code achter de knop Wissen laat je staan

Tardis
 
Bedankt,bedankt

ik kwam met de volgende oplossing na veel denkwerk voor een combobox

Private Sub Knop4_Click()
Me.cbobox.Value = ""
End Sub

Private Sub Knop5_Click()
If Nz(Me.cbobox.Value, "") = "" Then
MsgBox "leeg"
Else
MsgBox "niet leeg"
End If

End Sub
 
Aardige oplossing maar dat ondervangt dus niet dat je tekstvak NULL is.
Oftewel, je oplossing is niet waterdicht.
Lees mijn reaktie nog eens goed door.

Tardis
 
Graag had ik ook wat toelichting bij die andere vraag octafish heeft hier al op gereageerd maar ik begrijp het niet zo direct . Ik dacht zo in de richting van een functie die het decimaal gedeelte afsplitst van een cijfer en dan testen via len functie op twee tekens of iets in die richting .
Kan ik er niet voor zorgen dat de eindgebruiker gewoon niet meer dan twee cijfers na de komma kan intijpen. Vind ik wel belangrijk . Ik maak een SQL string die via de Querydefs methode een selectie query update. Als de filter voor het veld gewicht drie cijfers heeft na de komma , dan wordt er een lege recordset geretouneerd . Dit is logisch de tabel bestaat bijvoorbeeld uit gegevens die met twee cijfers zijn ingegeven .
Wat is een matrix variabele ?

mvg
TDW
 
Je hoeft doorgaans niet apart op Null te testen als je de functie Nz gebruikt, dus je oplossing is prima!
Het controleren van een tekstvak op zowel numerieke waarde vóór de komma, en maximaal twee cijfers nà de komma, kun je zo doen:

Code:
Private Sub Tekst64_Change()
Dim Inhoud As Variant
Dim LCID As Long
Dim S_Teken As String

S_Teken = ","
Inhoud = Me.Tekst64.Text
If Inhoud & "" <> "" Then
    If GoedGetal(Inhoud, S_Teken) = False Then
        If Right(Inhoud, 1) <> S_Teken Then Me.Tekst64.Text = Left(Inhoud, Len(Inhoud) - 1)
        Me.Tekst64.SelStart = Len(Me.Tekst64.Text)
    End If
End If

End Sub

De check wordt met een functie gedaan:

Code:
Function GoedGetal(Getal As Variant, Splitter As String) As Boolean
Dim tmp As Variant
Dim Getal1 As Boolean, Getal2 As Boolean
    tmp = Split(Getal, Splitter)
    If UBound(tmp) > LBound(tmp) + 1 Then
        GoedGetal = False
    Else
        If LBound(tmp) = UBound(tmp) Then
            If IsNumeric(Getal) Then GoedGetal = True
        Else
            If IsNumeric(tmp(LBound(tmp))) = True Then
                If IsNumeric(Nz(tmp(UBound(tmp)), 0)) = True Then
                    If Len(tmp(UBound(tmp))) <= 2 Then GoedGetal = True
                Else
                    If Len(tmp(UBound(tmp))) = 0 Then GoedGetal = True Else: GoedGetal = False
                End If
            Else
                GoedGetal = False
            End If
        End If
    End If
End Function

Het enige nadeel van deze werkwijze (controleren terwijl de gebruiker typt) is dat je natuurlijk nooit in één keer twee cijfers achter de komma kunt afdwingen. Na de komma typ je doorgaans eerst het eerste cijfer, en daarna pas het tweede. Je hebt dus nog een controle nodig bij het afsluiten van het tekstvak (de gebeurtenis <Na bijwerken> bijvoorbeeld) die controleert of je echt twee cijfers achter de komma hebt getypt. Of je vult het getal aan met nullen.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan