我为一个 Access 数据库开发了一些代码,该代码使用如下语句操作字符串:
myString = Left(myString, somePosition) & Right(myString, someOtherPosition)
上面是一个循环的一部分,该循环具有数千次迭代,变量 myString 有数千个字符长。
我知道上面的代码在Java中是不好的做法,应该使用StringBuffer而不是字符串。
我的代码需要大量时间才能运行(大约 7 分钟(,我怀疑问题可能与正在进行的繁重字符串操作有关。您能否确认 VBA 中是否有类似于 StringBuffer 的内容可以提高我的代码效率?
更新:使用StringBuilder的完整代码
Function SelectColumns2(str As String, columns As String, separator As String) As String
'column_number is the number of the column we are reading when we loop through a line
'z is the counter of the field (a portion of str between two separators)
'i is the counter of the str (the position of the modified string)
Dim column_number As Integer, i As Double, z As Integer, leftPosition As Double
'stringbuilder that stores the string that will represent the final file
Dim sb As StringBuilder, leftStr As StringBuilder, rightStr As StringBuilder
Set sb = New StringBuilder
Set leftStr = New StringBuilder
Set rightStr = New StringBuilder
sb.Append str
column_number = 1
i = 1 ' full str
z = 0 ' full field
While sb.Length >= i
z = z + 1
If Mid(sb.Text, i, 1) = separator Then
If InStr(1, columns, "/" & column_number & "/") = 0 Then
leftStr.Append left(sb.Text, i - z)
rightStr.Append right(sb.Text, sb.Length - i)
sb.Clear
sb.Append leftStr.Text
sb.Append rightStr.Text
leftStr.Clear
rightStr.Clear
i = i - z
End If
column_number = column_number + 1
z = 0
ElseIf Mid(sb.Text, i, 1) = Chr(10) Then
If InStr(1, columns, "/" & column_number & "/") = 0 Then
leftPosition = max((i - z - 1), 0)
If leftPosition = 0 Then
leftStr.Append left(sb.Text, leftPosition)
rightStr.Append right(sb.Text, sb.Length - i)
sb.Clear
sb.Append leftStr.Text
sb.Append rightStr.Text
Else
leftStr.Append left(sb.Text, leftPosition)
rightStr.Append right(sb.Text, sb.Length - i + 1)
sb.Clear
sb.Append leftStr.Text
sb.Append rightStr.Text
End If
leftStr.Clear
rightStr.Clear
i = i - z
End If
column_number = 1
z = 0
End If
i = i + 1
Wend
SelectColumns2 = left(sb.Text, sb.Length - 1)
End Function
可以使用CreateObject
创建 .Net 字符串生成器类。 请注意,您必须安装相关的 .Net 库,并且 VBA 不支持重载,因此它的处理方式与 VB.Net 中的处理方式略有不同。
示例代码:
Public Sub TestSB()
Dim sb As Object
Set sb = CreateObject("System.Text.StringBuilder")
sb.Append_3 "Hello"
sb.Append_3 " "
sb.Append_3 "World"
sb.Append_3 "!"
Debug.Print sb.ToString
End Sub
或者,您可以构建自己的字符串生成器。这个答案提供了一个字符串生成器类,这个问题也展示了一些示例代码。
对于非常简单的实现,您可以使用Mid。
例如,对于输入的相当大的字符串,此代码在大约 0.1 毫秒内运行:
Public Function ChopString() As String
Dim Source As String
Dim LeftPart As Long
Dim RightPart As Long
Dim Result As String
Source = String(100000, "x")
LeftPart = 30000
RightPart = 40000
Result = Space(LeftPart + RightPart)
Mid(Result, 1) = Left(Source, LeftPart)
Mid(Result, 1 + LeftPart) = Right(Source, RightPart)
ChopString = Result
End Function
对于几个 K 的较小字符串,它的运行速度要快得多。