0

我有一个复杂的代码,但总而言之,我有这个:

一个RecordSet命名的rstRecords
全局string变量命名StrLetters
一个string名为的变量,每次运行时StrText都有一个内容; 一个。differentloop
While Loop

每次loop去的next时候,它Add more content to the string StrLetters。喜欢:

Do While Not rstRecords.EOF
   'Codes Here
    Here I call a method named FeedLetter, that has lot of codes but also feed this string
Loop

Private Sub FeedLetter()

   'Lot of code
   'And Here I feed that string

   StrLetters = StrLetters + StrText

End Sub

当它有很多记录时,您将鼠标放在变量上StrLetters时,它会显示此工具提示<Out Of Memory>。以及以下错误,String Out of Space.

当 Theloop结束时,一个方法将使用 the 的值StrLetters并打印在纸上。

我知道它被解雇了,因为在VB6变量中有一个Max Lengh Value.
我只是想知道解决这个问题的方法...

更新

这是发生错误的地方(cStringBuilderClassDave 给出的方法)。

我打电话:

Buffer.CapacityIncrement = Len(strIncommingContent)
Buffer.Append (strIncommingContent)

错误发生在这里:

    Public Sub EnsureCapacity(ByVal lngMinimum As Long)
Dim lngDiff As Long
   If ((m_lngCapacity < lngMinimum) And (lngMinimum > 0)) Then
      ' If current capacity isn't enough, then figure out how many capacity increments you need to meet
      ' the given minimum
      lngDiff = lngMinimum - m_lngCapacity
      If (lngDiff < m_lngCapacityIncrement) Then
         ' The If...ElseIf... is quicker than the math in the ElseIf
         lngDiff = m_lngCapacityIncrement
      ElseIf (lngDiff > m_lngCapacityIncrement) Then
         ' Note that the division is using \ operator instead of /.  \ truncates decimal part
         lngDiff = ((lngDiff \ m_lngCapacityIncrement) + 1) * m_lngCapacityIncrement
      End If
      m_str = m_str & String$(lngDiff, vbNullChar)
      m_lngCapacity = (m_lngCapacity + lngDiff)
   End If
End Sub
4

1 回答 1

1

我找不到指向我所指的那篇非常古老的 Visual Basic Programmers Journal 文章的链接。我将发布基于该文章创建的代码,并且多年来一直运行良好。

我真正喜欢这个实现的一件事是它允许您为缓冲区设置初始大小。任何语言(具有不可变字符串,如 VB6、VB.Net、C#、Java 等)中的任何 StringBuilder/StringBuffer 类中最慢的部分是它必须调整自身大小以适应新附加或插入的文本。如果您可以很好地猜测最终字符串的大小,则可以EnsureCapacity在开始之前(或实际上在任何时候)调用该方法,以便在一次调用中使缓冲区大小合适。

在您的情况下,如果您可以找出您的行中有多少行RecordSet并将其乘以要添加的平均大小字符串,您将获得对最终字符串大小的粗略估计。在对 的调用中使用该值EnsureCapacity。您还可以设置必须扩展缓冲区时将使用的增量大小。在我的代码中,缓冲区增加了 64 个字符块。例如,如果您知道每个Append操作将是大约 1500 个字符,则将CapacityIncrement属性设置为至少 1500,因为这样会更快一些。我仍然建议使用我描述的最终字符串大小方法。

Option Explicit

Private m_str As String
Private m_lngLength As Long             ' Current length (char count)
Private m_lngCapacity As Long           ' Current capacity (length of buffer)
Private m_lngCapacityIncrement As Long  ' Number of characters to add when incrementing capacity

Private Sub Class_Initialize()
   m_lngCapacityIncrement = 64
End Sub

Public Sub Append(ByVal str As String)
Dim lngLen As Long
   lngLen = Len(str)
   If lngLen = 0 Then Exit Sub
   EnsureCapacity (m_lngLength + lngLen)
   Mid$(m_str, m_lngLength + 1, lngLen) = str
   m_lngLength = m_lngLength + lngLen
End Sub

Public Property Get Capacity() As Long
   Capacity = m_lngCapacity
End Property

Public Property Get CapacityIncrement() As Long
   CapacityIncrement = m_lngCapacityIncrement
End Property

Public Property Let CapacityIncrement(ByVal lngNewValue As Long)
   If lngNewValue > 0 Then m_lngCapacityIncrement = lngNewValue
End Property

Public Sub EnsureCapacity(ByVal lngMinimum As Long)
Dim lngDiff As Long
   If ((m_lngCapacity < lngMinimum) And (lngMinimum > 0)) Then
      ' If current capacity isn't enough, then figure out how many capacity increments you need to meet
      ' the given minimum
      lngDiff = lngMinimum - m_lngCapacity
      If (lngDiff < m_lngCapacityIncrement) Then
         ' The If...ElseIf... is quicker than the math in the ElseIf
         lngDiff = m_lngCapacityIncrement
      ElseIf (lngDiff > m_lngCapacityIncrement) Then
         ' Note that the division is using \ operator instead of /.  \ truncates decimal part
         lngDiff = ((lngDiff \ m_lngCapacityIncrement) + 1) * m_lngCapacityIncrement
      End If
      m_str = m_str & String$(lngDiff, vbNullChar)
      m_lngCapacity = (m_lngCapacity + lngDiff)
   End If
End Sub

Public Property Get Length() As Long
   Length = m_lngLength
End Property

Public Function GetString() As String
   GetString = left$(m_str, m_lngLength)
End Function

Public Sub Reset()
   m_str = ""
   m_lngLength = 0
   m_lngCapacity = 0
   m_lngCapacityIncrement = 64
End Sub
于 2013-08-09T19:41:51.003 回答