Reputation: 3
I've got a user-form that generates a large amount of text and puts it into a Textbox.
I have the following function to append the next line of text to the textbox:
Sub AddLineToSQL(sLine As String)
frmSQL.txtSQL.Value = frmSQL.txtSQL.Value & sLine & vbCr
End Sub
When adding several hundred lines of text it takes a while to process (up to 20 seconds).
The problem with this is that there is the possibility of adding more than a thousand lines of text.
We have an old form that does basically the same thing, but I'm trying to create a cleaner user experience. the old form wrote the text to a worksheet, and it seems to work much quicker than appending to the textbox.
Is there a More efficient way to append text to a textbox than what I have above?
should I just do what the old form did and write lines to a worksheet?
Thanks,
Mark
Upvotes: 0
Views: 2732
Reputation: 29421
should your amount of text be veeery large then you could use this class:
' Class: StringBuilder
' from http://stackoverflow.com/questions/1070863/hidden-features-of-vba
Option Explicit
Private Const initialLength As Long = 32
Private totalLength As Long ' Length of the buffer
Private curLength As Long ' Length of the string value within the buffer
Private buffer As String ' The buffer
Private Sub Class_Initialize()
' We set the buffer up to it's initial size and the string value ""
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
Public Sub Append(Text As String)
Dim incLen As Long ' The length that the value will be increased by
Dim newLen As Long ' The length of the value after being appended
incLen = Len(Text)
newLen = curLength + incLen
' Will the new value fit in the remaining free space within the current buffer
If newLen <= totalLength Then
' Buffer has room so just insert the new value
Mid(buffer, curLength + 1, incLen) = Text
Else
' Buffer does not have enough room so
' first calculate the new buffer size by doubling until its big enough
' then build the new buffer
While totalLength < newLen
totalLength = totalLength + totalLength
Wend
buffer = Left(buffer, curLength) & Text & Space(totalLength - newLen)
End If
curLength = newLen
End Sub
Public Property Get Length() As Integer
Length = curLength
End Property
Public Property Get Text() As String
Text = Left(buffer, curLength)
End Property
Public Sub Clear()
totalLength = initialLength
buffer = Space(totalLength)
curLength = 0
End Sub
just place it in any Class Module and name it after "StringBuilder"
then you can test it similarly as per Axel answer:
Sub test()
Dim i As Long
Dim sb As StringBuilder
Dim sTxtSQL As String
Dim timeCount As Long
timeCount = Timer
Set sb = New StringBuilder
For i = 1 To 50000
sb.Append "This is row " & CStr(i) & vbCrLf
Next i
sTxtSQL = sb.Text
MsgBox Timer - timeCount
frmSQL.txtSQL.Value = sTxtSQL
frmSQL.Show
End Sub
My test showed significant time reduction for "i" loops over 50k
Upvotes: 0
Reputation: 61915
Do not appending line by line to the TextBox. Instead do concatenating a String with all lines and then set that String as the TextBox value.
Sub test()
Dim sTxtSQL As String
For i = 1 To 5000
sTxtSQL = sTxtSQL & "This is row " & i & vbCrLf
Next
frmSQL.txtSQL.Value = sTxtSQL
frmSQL.Show
End Sub
Upvotes: 2