次は、今回のメイン。検索を実行する「検索実行」プロシージャの処理だ(リスト9)。
Private Sub 検索実行(検索対象 As String) Dim searchName As String searchName = 検索対象 If searchName = "" Then MsgBox "検索する対象を入力してください。" Else Dim i As Long Dim no As Long For i = 0 To 一覧リストボックス.ListCount - 1 If 一覧リストボックス.List(i) = searchName Then no = i 一覧リストボックス.ListIndex = no End If Next Index = no + 3 Worksheets("個人情報データ").Select Rows(Index).Select Dim 行番号 As Integer 行番号 = ActiveCell.Row IDラベル.Caption = Cells(行番号, 1) 氏名ラベル.Caption = Cells(行番号, 2) 性別ラベル.Caption = Cells(行番号, 3) 生年月日ラベル.Caption = Cells(行番号, 4) 郵便番号ラベル.Caption = Cells(行番号, 5) 住所ラベル.Caption = Cells(行番号, 6) 電話番号ラベル.Caption = Cells(行番号, 7) メールラベル.Caption = Cells(行番号, 8) End If End Sub
まず、文字列型のsearchName変数を宣言し、呼び出し元の引数「検索対象」を格納する(2〜3行目)。変数searchNameが空の場合は、警告メッセージを出して処理を抜けるようにしておく(5〜6行目)。
次に、「一覧リストボックス」内に表示されている項目の数だけループ処理を行う(10〜15行目)。
「一覧リストボックス」内に登録されているデータは、「配列」形式になっており、Listプロパティにループ変数「i」を指定している。条件分岐で、そのiに合致する「一覧リストボックス」内の値と変数searchNameの値が一致すれば、変数noにiを格納して、「一覧リストボックス」のListIndexに変数noの値を指定する(11〜14行目)。
10〜15行目により、各検索入力ボックスに入力した値と「一覧リストボックス」内の同じデータが選択状態になる。
11行目にあるように、検索は「完全一致」検索であって「あいまい検索」ではない点に注意していただきたい。先にも書いたが、同じデータが存在する場合は、最初に合致したデータのみが表示される。その場合は、重複することのない「電話番号」での検索をお勧めする。
変数Indexには、変数noの値に3を加算した値を指定する(16行目)。3を加算しているのは、データの登録が3行目から始まっているためだ。
「個人情報データ」シートを選択状態にして表示し(17行目)、変数Indexに該当する行を選択状態にする(18行目)。
Integer型の「行番号」変数を宣言し(20行目)、アクティブな行番号を格納する(21行目)。
最後に、「ID」「氏名」「性別」「生年月日」「郵便番号」「住所」「電話番号」「メール」ラベルのCaptionプロパティに、アクティブになっている行の各列の値を表示する(23〜30行目)。列の値は、1〜8列までの値を各ラベルのCaptionに指定することで、アクティブなセルのデータが、各ラベルの中に表示される。
最後は「一覧リストボックス」から値を選択したときの処理だ(リスト10)。
Private Sub 一覧リストボックス_Change() On Error GoTo エラー If 判定 = 1 Then 検索氏名テキストボックス.Text = 一覧リストボックス.List(一覧リストボックス.ListIndex) End If If 判定 = 2 Then 検索住所テキストボックス.Text = 一覧リストボックス.List(一覧リストボックス.ListIndex) End If If 判定 = 3 Then 検索電話番号テキストボックス.Text = 一覧リストボックス.List(一覧リストボックス.ListIndex) End If エラー: Exit Sub End Sub
エラーが発生するので、On Error GoTo文でエラー処理を行っておく(2行目)。
変数「判定」が1の場合は、「検索氏名テキストボックス」の値に、「一覧リストボックス」内の値で、Listプロパティの「一覧リストボックス」のListIndexに該当する値を指定する(3〜5行目)。これで、「一覧リストボックス」から選択した値が、「検索氏名テキストボックス」内に表示される。
次は、変数「判定」が2の場合だ。「検索住所テキストボックス」の値に、「一覧リストボックス」内の値で、Listプロパティの「一覧リストボックス」のListIndexに該当する値を指定する(7〜9行目)。これで、「一覧リストボックス」から選択した値が、「検索住所テキストボックス」内に表示される。
最後は、変数「判定」が3の場合だ。「検索電話番号テキストボックス」の値に、「一覧リストボックス」内の値で、Listプロパティの「一覧リストボックス」のListIndexに該当する値を指定する(11〜13行目)。これで、「一覧リストボックス」から選択した値が、「検索電話番号テキストボックス」内に表示される。
エラーが発生した場合は、「エラー:」という行(15行目)以下のコードが実行される。この場合は処理を抜ける(16行目)。
「データ検索」を実行すると図8のようになる。この場合は「データ検索」であるため、フォーム上に配置していた「削除」ボタンは非表示となっている。
以上で、「データ検索」処理は終わりだ。こういった処理の場合、一番面倒なのは「どのように検索結果を表示させるか」という点だと思う。今回の場合、別に「一覧リストボックス」はなくても、各入力ボックスに検索項目を入力させて、「実行」ボタンクリックで検索結果を表示させてもよかったはずなのだ。
しかし「一覧リストボックス」を追加しているのは、できるだけユーザーに間違ったデータを入力させないようにしたいという思いからだ。間違った検索結果を入力すると当然データは表示されない。それを解消する意味でも「一覧リストボックス」を追加したのだが、これが何万件ものデータになったら、「果たして一覧リストボックスの意味はあるのか?」という疑問も湧く。
例えば、何万件ものデータから、「一覧リストボックス」に表示された、該当する「氏名」を探すのは不可能に近い。そういった場合は、データ登録時に「ひらがな」のデータを登録させておいて、この「ひらがな」で「降順」「昇順」ソートさせてから、「一覧リストボックス」にデータを表示させると見つけやすくなるだろう。
今回は、そこまで手が回らなかったが、読者の皆さんでぜひ挑戦してみてほしい。では、なぜ今回、筆者の手が回らなかったのか、それは、仕様が変わると、フォームの入力ボックスに「氏名」の「読み」の入力欄を設け、保存するExcelのデータにも「読み」の項目を追加しなければならない。また、「検索」時にも「読みで検索」といった項目も追加しなければならない。
意外と簡単にできそうに思うかもしれないが、仕様が途中で変わるということは、プログラムの作業において、関連付けている箇所の変更も必要となり、思った以上に大掛かりな作業になるのだ。だから、何かを作る場合は、事前にじっくりと検討して、しっかりとした仕様を決めておく必要がある。途中での仕様の変更は、最悪な結果をもたらす恐れがあることに気付いてほしい。
また、データ件数が多くなった場合は、必ずしも「一覧リストボックス」から選択する必要はなく、「名前」「電話番号」が分かっている場合は、直接「入力ボックス」に入力して検索すればいい。あくまでも「一覧リストボックス」は、ユーザーの入力間違いを防止するためのものであることを認識しておいていただきたい。
次回は前回の冒頭で紹介した「メニュー画面」をようやく作る。さらに、「データ削除」について解説する予定だ。お楽しみに。
【2016/10/17】Windows 10、Excel 2016に対応しました。
PROJECT KySS 薬師寺 国安(やくしじ くにやす)
1950年生まれ。フリーVBプログラマ。高級婦人服メーカーの事務職に在職中、趣味でVBやActiveXに取り組み、記事を執筆。2003年よりフリー。.NETやRIAに関する執筆多数。Windowsストアアプリも多数公開中(約270本)。
Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
PROJECT KySSは、1997年に薬師寺聖と結成したコラボレーション・ユニット
Copyright © ITmedia, Inc. All Rights Reserved.