0

複雑なコードがありますが、要約すると、次のようになります。

RecordSet名前付きrstRecords;
という名前のグローバルstring変数StrLetters。;を実行するたびに内容を持つという名前
string変数。 A. _StrTextdifferentloop
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が終わると、メソッドは の値を使用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 の記事へのリンクを見つけることができませんでした。その記事に基づいて作成し、長年にわたってうまく機能しているコードを投稿します。

この実装で私が本当に気に入っている点の 1 つは、バッファーに初期サイズを設定できることです。任意の言語 (VB6、VB.Net、C#、Java などの不変文字列を含む) の StringBuilder/StringBuffer クラスの最も遅い部分は、新しく追加または挿入されたテキストに合わせてサイズを変更する必要がある場合です。最終的な文字列の大きさを推測できる場合は、EnsureCapacityメソッドを開始する前に (または実際にはいつでも) 呼び出して、代わりに 1 回の呼び出しでバッファーを適切なサイズにすることができます。

あなたの場合、何行あるかを調べて、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 に答える