Excel VBA Append для TextBox медленный
У меня есть пользовательская форма, которая генерирует большой объем текста и помещает его в текстовое поле.
У меня есть следующая функция, чтобы добавить следующую строку текста в текстовое поле:
Sub AddLineToSQL(sLine As String) frmSQL.txtSQL.Value = frmSQL.txtSQL.Value & sLine & vbCr End Sub
При добавлении нескольких сотен строк текста требуется время для обработки (до 20 секунд).
- Управление данными из текстового поля и значений инвертированного дня / месяца
- сохранение данных в текстовом поле для Excel в vb.net
- Текст текстового поля исчезает при вводе текста Excel VBA - часть 2
- Ячейка, подключенная средствами управления, продолжает терять формулу
- Текстовое поле ActiveX на листе листа Excel заменяет границу и шрифт при утрате фокуса
Проблема заключается в том, что есть возможность добавить более тысячи строк текста.
У нас есть старая форма, которая делает в основном одно и то же, но я пытаюсь создать более чистый пользовательский интерфейс. старая форма написала текст на листе, и, похоже, он работает намного быстрее, чем добавление в текстовое поле.
Есть ли более эффективный способ добавления текста в текстовое поле, чем то, что у меня выше?
должен ли я просто делать то, что делал старая форма, и писать строки на листе?
Благодаря,
отметка
- Код VBA / Macro для получения значения текстового поля
- VBA - Как я могу дать код ошибки на основе суммы моих значений текстового поля в форме пользователя?
- Excel 2010 не может вставляться в текстовое поле формы
- VBA, чтобы проверить, существует ли текст в текстовом поле, а затем проверить, находится ли дата в правильном формате
- Код устранения неполадок для макросов и текстовых полей
- Как активировать входной режим с VBA на текстовом поле неактивного x, вставленного в рабочий лист?
- Автоматическое создание текстовых полей на основе количества строк
- Выделить текст в Userform TextBox
Не добавляйте строки в строку в TextBox. Вместо этого конкатенируйте String со всеми строками, а затем установите String как значение TextBox.
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
если ваше количество текста будет большим, тогда вы можете использовать этот класс:
' 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
просто поместите его в любой модуль класса и назовите его после «StringBuilder»,
то вы можете протестировать его так же, как в ответе Акселя:
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
Мой тест показал значительное сокращение времени для «i» циклов более 50 тыс.