最終更新日 :
VB Tips

結び目型コレクション(その3)

さて、結び目型コレクションについてのページも3つ目、一応の最終回を迎えました。 今回は宣言通り、結び目型コレクションを使った応用的なクラスを作成する例を挙げていきたいと思います。
なんと。アンドゥバッファ管理クラス(UndoBuffer)と、文字列リスト(StringList)の2つもあるじゃないですか。 さらに、その文字列リストを使ってオートコンプリートの機能も実装してみます。

1.UndoBufferクラスのメンバと動作
プロパティ : (Get)Description, (Get)Latest
メソッド : Add, Clear, Execuse, GetDescriptions, RemoveFirst
イベント : DescriptionProc, Execuse
Private変数 : mKnot(KnotManagerオブジェクト)

このクラスは、さすがサンプルだけあってKnotManagerだけで成り立っています。以下の3つについて説明を加えたいと思います。

Public Sub Add(ByVal Element, ByVal Description)
このメソッドで、アンドゥの情報が詰まった変数(使用者が自由に設定。ただし、ユーザー定義型は不可。)をElementで指定し、 それに対しての説明(例えば、"ファイル名の変更"など)をDescriptionで指定します。配列の要素(整数型)などで指定できるように、 Variant型で受け取ります。メソッド内部では、これらの組をArray()関数で一つの配列としてKnotItemに組み込みます。 追加する場所は最後部固定です。

Public Event DescriptionProc(ByVal Description, Break As Boolean)
このイベントは、GetDescriptionsメソッドを実行したときに呼び出されるイベントです。BreakにTrueが代入されるまで何回も呼び出されます。 こうして呼び出される説明をリストボックスなどに追加していくと履歴リストができます。なお、説明は最後に追加されたアンドゥ情報から順番に通知されます。

Public Event Execuse(ByVal Element, Cancel As Boolean)
このイベントは、Execuseメソッドを実行したときに呼び出されます。実際にアンドゥ作業をする部分(開発者が実装する)はここになります。 このイベントが終了すると、自動的にアンドゥバッファの最後の情報は自動的に削除されます。これを防ぐ(アンドゥをキャンセルする)為には、CancelをTrueに設定してイベントを終了することで可能です。
2.StringListクラスのメンバと動作
プロパティ : (Get)ListItems
メソッド : Add, Clear, Remove
Private変数 : mKnot(KnotManagerオブジェクト)

このクラスも、KnotManagerだけで成り立っています。このオブジェクトでは、文字列を追加するときにちょっとした作業を行っているので以下でちょっと説明します。

Public Function Add(ByVal NewItem As String) As Long
With mKnot
c = .Count
If c > 0 Then
' 要素が既にある場合は挿入する位置を検索します。
' 最初から並べ方が辞書的な並びでソートされているので、
' 二分探索法を使用します。(ただし数が多い場合)

If c > .LadderBase * 5 Then
二分探索という手段を用います。この検索方法は、VBM99年3月号の「考え方を考える」などを参考にしてください。ここでは単純な二分探索ではなく、Ladderコレクションを用いた近似的な検索を行っています。
Else
' 数がそれほど多くない場合、Ladderコレクションを使って検索します。
こちらでは、二分探索に対応して逐次探索を行います。しかし、Ladderコレクションを用いた探索と混合させているので、単純に一つ一つ調べるよりかは高速です。
End If
' 先ほどと同様に今度は一つずつ進めながら挿入位置を決める
Do
ここで、一つずつKnotItemを調べていきます。
Loop
' この時点では挿入位置は決定している。
' 内容が同じならば挿入しない。

If ki2 Is Nothing Then
ki2がNothingであるということは、挿入位置が最初か最後であるということです。
ElseIf ki2.Value = NewItem Then
既にリストに入っている文字列と同じならば追加しません。
Else
ki2.InsertNext ki
End If
Else
' リストの最初の項目に指定します。
.AttachListItems ki
End If
End With


言葉で説明すると、こんなところです。実際のコードは、サンプルをダウンロードしてみてください。
3.AutoCompleterクラスのメンバと動作
プロパティ : (Get)ListItems, NoCase, TextBox
メソッド : AddText, Clear, ComplementText
Private変数 : mNoCase, mStrList(StringListオブジェクト), mTargetText_Alone(TextBox)

このクラスは、厳密に言えばKnotLibを直接使用していないのですが、StringListクラスを使用したサンプルとして紹介します。テキストボックスを対象としたオートコンプリートの機能を提供するクラスです。 その中枢の関数(メソッド)を解説します。

Public Sub ComplementText(TargetBox As TextBox)
Dim t As String, v As Variant, i As Long
Static b As Boolean

' 補完実行中もしくはテキストボックスのカーソルが一番右端に来ていなければこの先を実行しません。
If b Or TargetBox.SelStart < Len(TargetBox.Text) Then Exit Sub
b = True ' 補完実行中のフラグを立てます

' StringListのアイテムを配列の形で一括して受け取ります。
v = mStrList.ListItems
With TargetBox

' テキストボックスの文字を変数に代入します。その際に大文字小文字を区別するかによってテキストを編集します。
If mNoCase Then t = LCase(.Text) Else t = .Text

If Len(t) = 0 Then b = False: Exit Sub ' テキストが長さ0ならば実行中止です。

For i = 0 To UBound(v)
' 左から入力されたテキストと一致する部分がある配列の要素を探し出します。
' 一致するものがあれば、テキストボックスの内容を変更します。

Next
End With
b = False ' 補完終了。


この関数により、テキストボックスに自動的に文字列が追加されます。この関数を真似ることでこのサンプルでは実装されていない、テキストボックス以外に文字列変数を補完する関数も作ってみてはどうでしょうか。
それでは、ダウンロードして、実際に試してみてください。

Copyright (C) 1999 Satoshi Tadaフィードバックはこちら
Home