前回までで、MadiamarkerからのSQLite3データベースへのインポートと、データ入力のフォーマットを作成した。
今回からは入力したデータを検索する仕組みを作ってみたいと思う。
検索ユーザーフォーム全景
まずはシンプルに仕上げてみる。
項目 | 内容 |
---|---|
タイトル | タイトル |
オブジェクト名 | Textbox_Title |
項目 | 内容 |
---|---|
タイトル | 検索 |
項目 | 内容 |
---|---|
タイトル | |
オブジェクト名 | ListBox_Result |
入力した値と部分一致したものを抽出するのが普通だが今回はちょっと違うものを作ってみる。
『入力した値とレーベンシュタイン距離が短いものを順に表示する』
レーベンシュタイン距離についてはこちらを参照
なぜ今回レーベンシュタイン距離を取り上げたかというと
・知らない考え方で単純におもしろそう
・作品との予想外の出会いがありそう
2つ目は単純に部分一致では目につくことのない、
「あれ?そういやこんな作品も持ってたなぁ」ということが起きるんじゃないかということを期待している。
ユーザーフォーム内コード
Private Sub CommandButton1_Click() Dim myDBHandle As Long SQLite3Initialize SQLite3OpenV2 "C:\XXX\CDBookManager.db3", myDBHandle, _ SQLITE_OPEN_READONLY, "" Dim mySQL As String Dim myStmtHandle As Long mySQL = "select タイトル from CDBookManager" SQLite3PrepareV2 myDBHandle, mySQL, myStmtHandle Dim ReturnValue As Variant Dim ColCount As Long Dim i As Long Dim n As Long Dim myArray() As Variant Dim myVar As Variant Dim colType As Long Dim colValue As Variant ReturnValue = SQLite3Step(myStmtHandle) ColCount = SQLite3ColumnCount(myStmtHandle) ReDim myArray(ColCount) ReDim myVar(n) Do Until ReturnValue = SQLITE_DONE For i = 0 To ColCount - 1 colType = SQLite3ColumnType(myStmtHandle, i) colValue = ColumnValue(myStmtHandle, i, colType) myArray(i) = colValue Next i '① myArray(ColCount) = Levenshtein3(TextBox_Title.Value, myArray(0)) myVar(n) = myArray n = n + 1 ReDim Preserve myVar(n) ReturnValue = SQLite3Step(myStmtHandle) Loop ReDim Preserve myVar(n - 1) SQLite3Finalize myStmtHandle SQLite3Close myDBHandle ListBox_Result.List = WorksheetFunction.Transpose(WorksheetFunction.Transpose(myVar)) End Sub
SQLite for ExcelでのSelect文の使用方法については以下を参照。
さしあたっての処理だがデータベースから『タイトル』を全件抽出している。 総件数が少ないため問題ないと考えている。
今回のキモは①の部分にある。 『Levenshtein3』関数で算出したレーベンシュタイン距離を、抽出結果に1列追加している。
Levenshtein3関数のコードはこちらから。
[excel] Levenshtein VBAでの距離 [excel-vba] - CODE Q&A 問題解決
その結果をリストボックスにそのまま表示している。
無事にタイトルとレーベンシュタイン距離が表示されている。
まとめ
今回はレーベンシュタイン距離を付与するというところまででした。
次回は抽出結果をレーベンシュタイン距離の値に応じて並び替えてみたいと思います。