Lösungen

Die Eval-Funktion richtig nutzen

15.11.2006
Eine nützliche, aber von vielen Access-Anwendern unbeachtete Funktion ist Eval. Sie dient dazu, einen Zeichenfolgen-Ausdruck auszuwerten. Lesen Sie in diesem Beitrag, wie Sie die Eval-Funktion effizient einsetzen und welche nützlichen Möglichkeiten sie bietet.

Ein Zeichenfolgen-Ausdruck wird prinzipiell so interpretiert, wie wenn Sie den Ausdruck im Direktfenster oder direkt im Code ausführen. Deshalb lässt sich die Funktion dann sinnvoll einsetzen, wenn beispielsweise der Benutzer die Möglichkeit haben soll, zur Laufzeit Befehle einzugeben, die dann ausgeführt werden sollen.

Mathematische Berechnungen

Das einfachste Beispiel ist die Berechnung einer Formel, die der Benutzer in ein Formular oder einen mit der InputBox erzeugten Dialog eingibt. Der dazu erforderliche Code (Listing 1) ist denkbar einfach. Zunächst wird der Variablen strFormel der Rückgabewert der InputBox-Funktion zugewiesen. Diese erzeugt das Dialogfeld in Bild 1, in das der Benutzer eine Formel eingeben kann.

Bild 1: Auszuwertende Formel.
Bild 2: Ausgabe des Berechnungsergebnisses.

Sub EingabeAuswerten()
Dim strFormel As String
strFormel = InputBox("Bitte geben Sie die Formel ein:")
MsgBox Eval(strFormel)
End Sub

Funktionen und Methoden

Neben einfachen mathematischen Berechnungen kann die Eval-Funktion aber auch Funktionen und sogar Eigenschaften und Methoden auswerten und Zeichenkettenoperationen durchführen. Generell gilt dabei, dass Sie Zeichenketten, die nicht ausgewertet, sondern als Zeichenkette verwendet werden sollen, in Hochkommata einfassen müssen. Die Prozedur in Listing 2 zeigt, wie Sie nacheinander die Access-Version, den Datenbanknamen und den Datenbankpfad ausgeben.

Sub FunktionenMethoden()
Dim strFormel As String
strFormel = "'Access-Version: ' & application.version"
Debug.Print Eval(strFormel)
strFormel = "'Datenbankname: ' & Application.CurrentDb.Name"
Debug.Print Eval(strFormel)
strFormel = "'Datenbankpfad: ' & getPfad1()"
Debug.Print Eval(strFormel)
End Sub
Function getPfad1() As String
getPfad1 = Left(CurrentDb.Name, _
Len(CurrentDb.Name) - _
Len(Dir(CurrentDb.Name)))
End Function

Der Datenbankpfad wird hier über die benutzerdefinierte Funktion getPfad1 ermittelt. Sie sehen daran, dass auch benutzerdefinierte Funktionen möglich sind, solange sie innerhalb eines normalen Moduls und nicht in einem Klassenmodul definiert sind.

Allerdings gibt es ein paar Einschränkungen. Sie können nur die Methoden und Eigenschaften verwenden, die VBA kennt. Das sind also alle Eigenschaften und Methoden des Access-Objektmodells, die zu Objekten gehören, die Access automatisch erzeugt. Es ist nämlich nicht möglich, Objektvariablen zu verwenden. Daher scheitert auch der Code in Listing 3, der zunächst eine Objektvariable erzeugt und dieser einen Verweis auf die aktuelle Datenbank zuweist. Der direkte Zugriff auf den Datenbanknamen über Application.CurrentDB.Name (Listing 2) funktioniert hingegen.

Sub FunktionenMethoden()
Dim strFormel As String
Dim objDB As DAO.Database
Set objDB = Application.CurrentDb
strFormel = "'Datenbankname:' & objDB.Name"
Debug.Print Eval(strFormel)
End Sub

Parameter übergeben

Selbstverständlich können Sie an die Funktionen, die Sie innerhalb der Zeichenketten verwenden, auch Parameter übergeben. Dazu fassen Sie diejenigen, die als Texte übergeben werden sollen, in doppelte Anführungszeichen ein. Das Beispiel in Listing 4 zeigt dieses Vorgehen. In der Formel, die von der Eval-Funktion ausgewertet wird, wird die benutzerdefinierte Funktion Ausgabe aufgerufen. Ihr wird als erster Parameter ein Text, als zweiter der Wert der Funktion Date() übergeben. Damit die Eval-Funktion nicht versucht, den Inhalt des ersten Parameters als Funktion auszuwerten, wird er in Anführungszeichen eingefasst. Und da sich der Parameter schon innerhalb einer Zeichenkette befindet, werden die Anführungszeichen verdoppelt.

Sub Parameter()
Dim strFormel As String
strFormel = "Ausgabe(""Datum:"",Date())"
Debug.Print Eval(strFormel)
End Sub
Function Ausgabe(strText As String, datDatum As Date) As String
Ausgabe = strText & CStr(datDatum)
End Function

Möchten Sie ein Datum als Parameter übergeben, fassen Sie es einfach in Doppelkreuze ein. Die dürfen Sie dann aber nicht noch einmal in Anführungszeichen setzen (Listing 5).

Sub Parameter2()
Dim strFormel As String
strFormel = "Ausgabe(""Datum:"",#01/05/2006#)"
Debug.Print Eval(strFormel)
End Sub

Zusammenfassung

Die Eval-Funktion ist sehr flexibel einzusetzen. Sie können Sie nicht nur im VBA-Code nutzen, sondern beispielsweise auch als Funktion für Steuerelemente in Formularen und Berichten. Denkbar ist daher auch, die auszuwertende Formel aus einer Datenbanktabelle zu lesen. Damit ließen sich auch komplexere Berechnungen in Berichten und Formularen ausführen, ohne VBA zu bemühen. Ein Sicherheitsrisiko stellt die Eval-Funktion kaum dar, weil potenziell gefährliche VBA-Anweisung wie kill zum Löschen von Dateien als Prozeduren implementiert sind und daher nicht in einer Funktion aufgerufen werden können.

Inhalt und Aufbau der Formel

Die Formel muss syntaktisch korrekt sein. So müssen Klammern korrekt verschachtelt sein und die in VBA verfügbaren Rechenzeichen verwendet werden. Dezimalzahlen müssen mit Dezimalpunkt anstelle des im deutschen üblichen Kommas eingegeben werden.
Dezimalkommata dürfen verwendet werden, wenn solche Zahlen als Zeichenketten innerhalb der Formel stehen. Allerdings sind sie in Anführungszeichen zu setzen. Dann wandelt die Eval-Funktion zunächst die Zeichenketten um und ersetzt dabei gegebenenfalls das Komma durch einen Dezimalpunkt. Danach wird erst die Formel berechnet. Möchten Sie beispielsweise die Formel 10 x 0,5 berechnen, könnten Sie dazu eine der beiden folgenden Zeichenketten an die Eval-Funktion übergeben:
10 x 0.5
10 x"0,5"
Beide führen zum korrekten Ergebnis.