Plausibilitätsprüfung von Messwerten

By , 6. Oktober 2009

Bei der manuellen Messwerterfassung hat man immer die Unsicherheit des Faktors „Mensch“ zu berücksichtigen. Zahlendreher oder zuviele Nullen sind da schnell mal eingegeben, und im Nachhinein schwer zu finden. Da ist es besser man macht eine Plausibilitätsprüfung indem man das Formular ungebunden macht und bei klick auf den Speicherbutton die Eingabewerte überprüft.

Z.B. auf die Anzahl der Stellen, ob positiv oder negativ, ob größer oder kleiner von einem bestimmten Wert, oder ob in einem bestimmten Zahlenbereich liegend.

Das Problem daran ist, dass sich diese Begrenzungen ständig ändern können. Dann muss man den VBA-Code durchsuchen wo man diese Plausibilitätsprüfung gemacht hat. Besser wäre das doch wenn man in einer Tabelle alle Plausibilitäten einfach ablegen könnte von wo aus sie einfach zu administrieren sind. Und genau das wollen wir jetzt machen.

Zuerst die Tabelle.
Jeder Messwert hat eine bestimmte Nummer oder Namen. Außerdem benötigen wird ein Vergleichsmuster, und eine Werteliste mit den einzelnen Werten gegen den der Messwert abgeprüft wird.

Ein Datensatz in dieser Tabelle sieht z.B. so aus:

ID Bezeichner Muster Werteliste
1 MP1 > {1} AND <= {2} AND <> {3} 2;5;4

Im Muster sieht man Platzhalter in geschweiften Klammern stehen, diese werden dann mit den Werten aus der Werteliste ergänzt.

Hat man am Messpunkt MP1 einen Wert von z.B. 3 angegeben, so muss dieser in das Muster eingefügt werden, und der komplette Ausdruck mittels eval() geprüft werden.

Im ersten Schritt werden die Werte aus der Werteliste eingefügt;

    Set db = CurrentDb
    Set rs = db.OpenRecordset("Select * From tbl_Plausibilitäten", dbOpenDynaset)
    For i = 1 To 5
        rs.FindFirst "Bezeichner = 'MP" & i & "'"
        If Not rs.NoMatch Then
            ctlWert = Replace(Me("MP" & i).Value, ",", ".")
            bolAusdruck = ctlWert & " " & rs!Muster

            tmpSplit = Split(rs!Werteliste, ";")
            For k = 1 To UBound(tmpSplit) + 1
                bolAusdruck = Replace(bolAusdruck, "{" & k & "}", tmpSplit(k - 1))
            Next k

ctlWert ist der eingegebene Messwert. Da dieser auch Komma-Zahlen enthalten kann ist das Komma in einen Punkt umzuwandeln, sonst funktioniert später die Auswertung nicht.

Danach wird der aktuelle Messwert am Messpunkt MPi in den Ausdruck bolAusdruck eingefügt:

            For k = 1 To UBound(tmpSplit)
                posA = InStr(pos, LCase(bolAusdruck), "and")
                posB = InStr(pos, LCase(bolAusdruck), "or")
                If posA <= posB And posA > 0 Or posB = 0 Then
                    pos = posA + 4
                Else
                    pos = posB + 3
                End If
                bolAusdruck = Left(bolAusdruck, pos - 1) & ctlWert & " " & Mid(bolAusdruck, pos)
            Next k

Der Messwert muss nach dem And bzw. Or – mit dem mehrere Ausdrücke verkettet werden – eingefügt werden, daher wird 4 bzw 3 Zeichenlängen zur Position hinzugefügt. Die Position pos ist im nächsten Schleifendurchlauf die Startposition um weitere Verknüpfungsoperatoren zu finden und nach denen der Messwert einzufügen.

Nun ist der Bool’sche Ausdruck bolAusdruck komplett und kann auf Richtigkeit geprüft werden. Wie oben schon gesagt verwendet man dazu die Funktion Eval().

            If Not Eval(bolAusdruck) Then
                MsgBox "Messwert am Messpunkt " & i & " ist nicht Plausibel!"
                Exit Sub
            End If

Fehlt noch zum Schluss die eigentliche Speicherung der Messwerte per Einfügeabfrage. Und dabei gibt es auch noch einen Fallstrick der es zu beachten gilt.
Die Werte der Abfrage stehen in einer Komma-Separierten Liste. Wenn nun davon ein Messwert ebenfalls ein Komma hat, wirft VBA die Fehlermeldung heraus, dass die Anzahl der Abfragefelder und Zielfelder nicht übereinstimmen. Daher sind Werte mit Komma umzuwandeln wobei das Komma durch einen Punkt ersetzt wird, wie oben bei ctlWert.

        Me("MP" & i).Value = Replace(Me("MP" & i).Value, ",", ".")
    Next i
    
    'Messwerte speichern
    db.Execute "Insert into tbl_Messwerte (MP1, MP2, MP3, MP4, MP5) Values (" & Me!MP1 & ", " & Me!MP2 & ", " & Me!MP3 & ", " & Me!MP4 & ", " & Me!MP5 & ")"

Nun haben wir die Prozedur komplett, bis auf die Deklaration und Initialisation der Variablen.
Die komplette Prozedur sieht wie folgt aus:

Private Sub Speichern_Click()
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim i As Long, k As Long, pos As Long, posA As Long, posB As Long
    Dim Messwert As Double
    Dim bolAusdruck As String, ctlWert As String, Operator As String
    Dim tmpSplit As Variant
    
    Set db = CurrentDb
    Set rs = db.OpenRecordset("Select * From tbl_Plausibilitäten", dbOpenDynaset)
    For i = 1 To 5
        rs.FindFirst "Bezeichner = 'MP" & i & "'"
        If Not rs.NoMatch Then
            ctlWert = Replace(Me("MP" & i).Value, ",", ".")
            tmpSplit = Split(rs!Werteliste, ";")
            bolAusdruck = ctlWert & " " & rs!Muster
            pos = 1
            For k = 1 To UBound(tmpSplit) + 1
                bolAusdruck = Replace(bolAusdruck, "{" & k & "}", tmpSplit(k - 1))
            Next k
            
            For k = 1 To UBound(tmpSplit)
                posA = InStr(pos, LCase(bolAusdruck), "and")
                posB = InStr(pos, LCase(bolAusdruck), "or")
                If posA <= posB And posA > 0 Or posB = 0 Then
                    pos = posA + 4
                Else
                    pos = posB + 3
                End If
                bolAusdruck = Left(bolAusdruck, pos - 1) & ctlWert & " " & Mid(bolAusdruck, pos)
            Next k
            
            If Not Eval(bolAusdruck) Then
                MsgBox "Messwert am Messpunkt " & i & " ist nicht Plausibel!"
                Exit Sub
            End If
        End If
        Me("MP" & i).Value = Replace(Me("MP" & i).Value, ",", ".")
    Next i
    
    'Messwerte speichern
    db.Execute "Insert into tbl_Messwerte (MP1, MP2, MP3, MP4, MP5) Values (" & Me!MP1 & ", " & Me!MP2 & ", " & Me!MP3 & ", " & Me!MP4 & ", " & Me!MP5 & ")"
    
    rs.Close
    Set rs = Nothing
    Set db = Nothing
End Sub

Leave a Reply

You must be logged in to post a comment.

OfficeFolders theme by Themocracy