DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

VBA で StringBuilder

今日はExcelVBAの話。


VBAで処理の高速化のために調べものしてたら
文字列連結の高速化手法が紹介されていました。

・文字列の連結で時間がかかるとき | Excel VBAのお勉強
http://www.excel-wing.com/study/jitumu/779

・文字列を高速に連結する(Midステートメント):Excel VBA|即効テクニック|Excel VBAを学ぶならmoug
http://www.moug.net/tech/exvba/0140045.html

とても勉強になるんだけど、
プロのプログラマとしては、このままでは使えない。

いちいち、バッファ容量などを気にしてMidステートメントを使うとかいうテクニックだと、道具として使いにくいわけですよ。

ということで応用しておきました。
ちょっとの工夫で、バッファ容量など気にせず文字列連結できます。


----------
StringBuilderクラスモジュール
  Option Explicit

  Const BufferBlockSize As Long = 1000000

  Private Buffer As String
  Public LengthIndex As Long

  Sub Initialize()
    LengthIndex = 0
    Buffer = VBA.String(BufferBlockSize, " ")
  End Sub

  Sub Clear()
    Call Initialize
  End Sub

  Sub Add(Value As String)
    Dim NewLengthIndex As Long
    NewLengthIndex = LengthIndex + Len(Value)
    Do While (Len(Buffer) < NewLengthIndex)
      Buffer = Buffer + VBA.String(BufferBlockSize, " ")
    Loop

    Mid(Buffer, LengthIndex + 1) = Value
    LengthIndex = LengthIndex + Len(Value)
  End Sub

  Public Property Get Text() As String
    Text = Left(Buffer, LengthIndex)
  End Property

----------
使い方と、動作確認コード
Option Explicit

  Sub 文字列連結でMidステートメントとの比較()

    Dim Str1 As String
    Dim Str2 As String
    Dim Str3 As String
    Dim lng As Long
    Dim strTime As String
    Dim dblTimer As Double

    Dim LoopCount As Long
    LoopCount = 200000

    '―――――――――――――――
    '通常の連結
    '―――――――――――――――
  ' dblTimer = Time
  '
  ' Str1 = ""
  ' For lng = 1 To LoopCount
  ' Str1 = Str1 & "あいうえおかきくけこ"
  ' Next lng
  '
  ' strTime = "通常:" & Time - dblTimer

    '―――――――――――――――
    'Midステートメント使用
    '―――――――――――――――

    dblTimer = Time

    'あらかじめ必要な文字数分を確保
    Str2 = VBA.String(LoopCount * 10, "a")
    Dim lngPos As Long
    lngPos = 1 'ループ内で開始する文字位置
    For lng = 1 To LoopCount
      Mid(Str2, lngPos, 10) = "あいうえおかきくけこ"
      lngPos = lngPos + 10
    Next lng
    Str2 = Left(Str2, lngPos - 1)

    strTime = strTime & vbCrLf & "Mid:" & Time - dblTimer

    '―――――――――――――――
    'StringBuilder
    '―――――――――――――――

    dblTimer = Time

    Dim StrBuilder As StringBuilder
    Set StrBuilder = New StringBuilder

    For lng = 1 To LoopCount
      Call StrBuilder.Add("あいうえおかきくけこ")
    Next
    Str3 = StrBuilder.Text

    strTime = strTime & vbCrLf & "Mid:" & Time - dblTimer

    '―――――――――――――――
    '比較
    '―――――――――――――――

    If (Str1 <> "") And (Str1 <> Str2) Then
      MsgBox "Str1<>Str2"
    End If

    If Str2 <> Str3 Then
      MsgBox "Str1<>Str2"
    End If


    '時間発表
    MsgBox strTime

  End Sub

これで、Midステートメントと同じ速度なのに
バッファ容量などを考えなくてもよい
手軽に利用できるStringBuilderクラスを作ることができました。

VBAの文字列処理の高速化したい場合は、使ってみてください。
スポンサーサイト

| 未分類 | 00:07 | comments:0 | trackbacks(-) | TOP↑

COMMENT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。