VBA: Cached Object in einer Function
Ein Klassiker: Wir haben eine selbstgeschriebene Funktion (user definied function) die ein RegExp-Objekt enthält. RegExp-Objekte können sehr schnell Texte parsen. Am schnellsten sind sie aber, wenn nicht jedesmal der Pattern und die Settings neu initialisiert werden müssen. Bei einzelnen Aufrufen ist das nicht relevant. Wenn man die Funktion hingegen in einem Query (Abgfrage) verwendet, hat man schnell den Fall dass das RegExp-Objekt 1000 mail initialisiert und 1000 mal entfernt wird.
Dank der Static-Daklaration und dem Private Property kann man das relativ einfach umgehen.
Funktion ohne Cache
Hier mal eine einfache Funktion in einem Modul
Funktion mit Cache im Funktionscode
Jetzt baue ich mal ein Cache mit der Static Dimensionierung ein. Das ganzw ist aber noch mässig lesbar
Funktion mit Cache als Property
Ich kapsle gerne einzelne Elemente. Darum schreibe ich jetzt das ganze Initializieren des RegExp-Objektes in ein Property.
Natürlich ist es in diesem Beispiel ein wenig übertrieben. Wenn man jedoch komplexere Funktionen hat, verbessert es die Lesbarkeit.
Ein Klassiker: Wir haben eine selbstgeschriebene Funktion (user definied function) die ein RegExp-Objekt enthält. RegExp-Objekte können sehr schnell Texte parsen. Am schnellsten sind sie aber, wenn nicht jedesmal der Pattern und die Settings neu initialisiert werden müssen. Bei einzelnen Aufrufen ist das nicht relevant. Wenn man die Funktion hingegen in einem Query (Abgfrage) verwendet, hat man schnell den Fall dass das RegExp-Objekt 1000 mail initialisiert und 1000 mal entfernt wird.
Dank der Static-Daklaration und dem Private Property kann man das relativ einfach umgehen.
Funktion ohne Cache
Hier mal eine einfache Funktion in einem Modul
Visual Basic:
Option Explicit
'/**
' * Extrahiert die ID aus einem String
' * @example: extractId("user=c123,id=34,name=erb")
' * @param String
' * @return String
' */
Public Function extractId(ByVal iString As String) As Integer
Dim rx As Object: Set rx = CreateObject("VBScript.RegExp")
rx.pattern = "id=(\d+)"
rx.Global = False
rx.IgnoreCase = True
rx.MultiLine = False
extractId = CInt(rx.execute(iString)(0).subMatches(0))
End Function
Funktion mit Cache im Funktionscode
Jetzt baue ich mal ein Cache mit der Static Dimensionierung ein. Das ganzw ist aber noch mässig lesbar
Visual Basic:
Option Explicit
'/**
' * Extrahiert die ID aus einem String
' * @example: extractId("user=c123,id=34,name=erb")
' * @param String
' * @return String
' */
Public Function extractId(ByVal iString As String) As Integer
Static rx As Object
If rx Is Nothing Then
Set rx = CreateObject("VBScript.RegExp")
rx.pattern = "id=(\d+)"
rx.Global = False
rx.IgnoreCase = True
rx.MultiLine = False
End If
extractId = CInt(rx.execute(iString)(0).subMatches(0))
End Function
Funktion mit Cache als Property
Ich kapsle gerne einzelne Elemente. Darum schreibe ich jetzt das ganze Initializieren des RegExp-Objektes in ein Property.
Natürlich ist es in diesem Beispiel ein wenig übertrieben. Wenn man jedoch komplexere Funktionen hat, verbessert es die Lesbarkeit.
Visual Basic:
Option Explicit
'/**
' * Extrahiert die ID aus einem String
' * @example: extractId("user=c123,id=34,name=erb")
' * @param String
' * @return String
' */
Public Function extractId(ByVal iString As String) As Integer
extractId = CInt(rxId.execute(iString)(0).subMatches(0))
End Function
'/**
' * Cache für das RegExp-Object um die ID zu extrahieren
' * @return RegExp
' */
Private Property Get rxId() As Object
Static rxCached As Object
If rxCached Is Nothing Then
Set rxCached = CreateObject("VBScript.RegExp")
rxCached.pattern = "id=(\d+)"
rxCached.Global = False
rxCached.IgnoreCase = True
rxCached.MultiLine = False
End If
Set rxId = rxCached
End Property