Clever-Excel-Forum

Normale Version: StringBuilder für Excel VBA
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Guten Tag miteinander
Ich habe eine String-Schlaufe, die eigentlich viel zu langsam ist, da bei jedem Durchlauf der String erweitert wird. Ich habe im Internet nach "StringBuilder" gesucht und in der Tat einige Beispiele gefunden, doch es ist trotzdem gescheitert. Kennt jemand eine machbare Lösung für VBA-Excel diesbezüglich?
Gruss und Dank
Stefan1
Moin!
Das, was Du bisher hast, ist natürlich geheim?

Inbesondere dürfte die Kenntnis der Aufgabenstellung mögliche Lösungsvorschläge potenzieren …

Fragt sich Ralf
=Worksheetfunction.TextJoin() oder
=Application.TextJoin() (ungetestet)

mit Evaluate und entweder Range oder VBA-Array
Oder das gute alte Join()
Hallo,

vom Rubberduck-Autor Matthieu Guindon: https://github.com/retailcoder/VBA-StringBuilder
Verwendet Windows API und läuft somit z.B. nicht auf einem Mac.

Gruß
Also folgende Versionen existieren im Internet:
Code:
Dim MyBuffer() As String
Dim MyCurrentIndex As Long
Dim MyMaxIndex As Long

Private Sub Class_Initialize()

    MyCurrentIndex = 0
    MyMaxIndex = 16
    ReDim MyBuffer(1 To MyMaxIndex)

End Sub

'Appends the given Text to this StringBuilder
Public Sub Append(Text As String)

    MyCurrentIndex = MyCurrentIndex + 1

    If MyCurrentIndex > MyMaxIndex Then
        MyMaxIndex = 2 * MyMaxIndex
        ReDim Preserve MyBuffer(1 To MyMaxIndex)
    End If
    MyBuffer(MyCurrentIndex) = Text

End Sub

'Returns the text in this StringBuilder
'Optional Parameter: Separator (default vbNullString) used in joining components
Public Function ToString(Optional Separator As String = vbNullString) As String

    If MyCurrentIndex > 0 Then
        ReDim Preserve MyBuffer(1 To MyCurrentIndex)
        MyMaxIndex = MyCurrentIndex
        ToString = Join(MyBuffer, Separator)
    End If

End Function
Bei der obigen scheiterte es an "StringBuilder", weil dieser Begriff nicht erkannt wird. Muss ich hier einen 'Verweis' auf ein bestimmtes Programm beachten oder wie soll VBA "StringBuilder" denn erkennen?.
Und dann finde ich folgende Lösung noch interessant, doch wo steht bloss dieses "Dim MyBuffer, Dim MyCurrentIndex usw.'? Im Klassenmodul oder im Modul selbst, doch beides geht nicht:
Code:
Dim MyBuffer() As String
Dim MyCurrentIndex As Long
Dim MyMaxIndex As Long

Private Sub Class_Initialize()

    MyCurrentIndex = 0
    MyMaxIndex = 16
    ReDim MyBuffer(1 To MyMaxIndex)

End Sub

'Appends the given Text to this StringBuilder
Public Sub Append(Text As String)

    MyCurrentIndex = MyCurrentIndex + 1

    If MyCurrentIndex > MyMaxIndex Then
        MyMaxIndex = 2 * MyMaxIndex
        ReDim Preserve MyBuffer(1 To MyMaxIndex)
    End If
    MyBuffer(MyCurrentIndex) = Text

End Sub

'Returns the text in this StringBuilder
'Optional Parameter: Separator (default vbNullString) used in joining components
Public Function ToString(Optional Separator As String = vbNullString) As String

    If MyCurrentIndex > 0 Then
        ReDim Preserve MyBuffer(1 To MyCurrentIndex)
        MyMaxIndex = MyCurrentIndex
        ToString = Join(MyBuffer, Separator)
    End If

End Function
Wie könnte ich das für Excel-VBA lösen?
Beispiele von hier:
https://codereview.stackexchange.com/que...ingbuilder
Vielen Dank für Eure Unterstützung.
Gruss
Stefan1
Hallo,

(01.08.2020, 10:59)Stefan1 schrieb: [ -> ]Ich habe eine String-Schlaufe, die eigentlich viel zu langsam ist, ...

wenn man wüsste, wie die aussieht, wäre vielleicht gezieltere Hilfe möglich. Wink

Gruß Uwe
Hallo Stefan1, :19:

das ist ja der Code vom StringBuilder, den "maninweb" in #5 schon vorgestellt hat. Den hättest du nur importieren müssen.

Wenn du den Code von deiner Quelle nimmst, muss der Code an die richtige Stelle (einmal Klassenmodul, einmal Modul) und das Klassenmodul muss den richtigen Namen haben bzw. der Code muss ein klein wenig angepasst werden. :21:
[attachment=33316]

Der Test ergibt bei mir bei 30.000 Durchläufen:

The VBA String took: 5,205 seconds
The Stringbuilder took: 0,015 seconds


Mit anderen Funktionen habe ich es nicht getestet, aber die Worksheetfunction.TextJoin() z. B. hat ein Limit von 32.767 Zeichen.
Guten Tag Case
Guten Tag miteinander
Vielen Dank. Genauso hat es funktioniert. Der Unterschied ist unglaublich, von fast 1 Minute zu 3, 4 Sekunden in meinem Fall. Ich wusste das mit der Benennung des Klassenmoduls als "StringBuilder" nicht und so kam es zu ständigen Fehler. Ich habe dazu gelernt  Blush  
Gruss
Stefan1