VBA30_自作フォームに命を吹き込む(完結編)

こんにちは! Benです。
今日は先日完結しなかったオートフィルター自作の完結編です。

Private Sub CommandButton1_Click()
  Dim e As Boolean, i As Integer, j As Integer, S As String, T As String
  i = 3
  Do Until IsEmpty(Worksheets("Sheet1").Cells(i, 2))  '作物名のデータがなくなるまでループ
    With Worksheets("Sheet1").Cells(i, 2)
      For j = 1 To 2 '1は上のコンボボックス(Atai1&Hante1) 2は下
        S = Me.Controls("Hantei" & j).Value  'Sは判定コンボの文字列
        T = Me.Controls("Atai" & j).Value 'Tは値コンボの文字列
        If Len(S) = 0 Or Len(T) = 0 Then Exit For '判定か値が空白だったら飛ばす
        e = False 'eは条件合致判定 はじめは不合致(False)
        Select Case Left(S, 2)
          Case "と等"
          If .Value Like T Then e = True  '「と等しい」とき
          Case "で始"
          If .Value Like T & "*" Then e = True '「で始まる」とき
          Case "で終"
          If .Value Like "*" & T Then e = True '「で終わる」とき
          Case "を含"
          If .Value Like "*" & T & "*" Then e = True '「を含む」とき
        End Select
        If Right(S, 2) = "ない" Then e = Not (e)  '判定の語尾が「ない」のときFalseとTrueを入れ替える
        If j = 1 Then '一つ目の判定(Hantei1&Atai1コンボ)だけで既に結果決定のときはFor~Nextを脱出
          If Me.OptionButton1.Value And Not (e) Then Exit For  '判定1不合致でANDの場合は不合致決定
          If Me.OptionButton2.Value And e Then Exit For  '判定1合致でORの場合は合致決定
        End If
      Next
      Worksheets("Sheet1").Rows(i).EntireRow.Hidden = Not (e) 'Trueで非表示なので合致(e)の反対
      i = i + 1
    End With
  Loop
End Sub
今回もいきなりドーンとコードを載せました。
まず2行目の変数の定義ですが、eは条件に合致したかどうかのブール型変数で、Trueのときは指定した条件に合致したことを示します。iはループ用で、表の行番号です。データは3行目からなので、初期値i=3、一連の処理をした後、28行目でiを1増やして次の行へと進みます。4行目のDoでデータがなくなるまで(空白かどうか判定する関数IsEmptyがTrueになるまで)繰り返します。

jもループ用の変数ですが、こちらはコンボボックスのAtaiとHanteiの上が1、ORやANDのオプションボタンを挟んで下が2なのでループさせると上下のこコンボを一つの命令群で処理できます。6行目から25行目のFor~Nextループがそれに当たります。このコンボボックスの値をjのループで取得するにはMe.Controls("Hantei & j).Valueと長いので何回も使うときには面倒、ということで、初めに変数にその値を格納して使っちゃおうというのが、7行目と8行目のSとTです。Hanteiコンボは文字列型変数Sに、AtaiコンボはTに格納してそれ以降の処理にはSとTを使用してすっきりさせています。単純にしたかったので今回は省きますがコンボボックスの値は処理中には変化しないので配列変数とかにはじめに入れれば無駄な処理を省けます。

9行目はAtaiコンボかHanteiコンボのどちらかでも空白だった場合、Forループを強制的に抜けるというものです。Exit Forは「ループ処理をやめてNextの次の行に抜けなさい」というものです。10行目で変数eをまずFalseにして、11行目以降のSelect文で合致していたらeをTrueに変えます。前回復習したLeft関数で左側2文字を抜き出し、判定の種類だけを条件分岐でうまく処理しています。なお、Like演算子は英語の~のようなという意味で、ワイルドカードなどを指定して柔軟な判定ができるものです。

そのあと21行目でRight関数を使って語尾を判定し「ない」のときは結果を逆にするという処理をしています。それぞれ「含む」「含まない」のペアを全て条件分岐すると長くなるので、このようにしました。

22~24行目は、1回目(j=1)だけですでに判定ができてしまうとき、2回目をスキップする処理です。オプションボタンがANDで1回目の判定が不合致だった場合、2回目の判定を待つ必要もなく結果は不合致です。同じように1回目が合致でオプションボタンがORだったら、2回目がどんな結果でも合致です。27行目で行の非表示を指定します。eは合致でTrueだけど、Hiddenプロパティは、Trueで非表示と逆なので反対にするためにNot(e)とします。

20151220a.png
では実際に動かしてみましょう。シート上に実行ボタンを作ると便利です。(こちらの後半参照)ミニトマトとか増やすと「トマトで終わる」にすると「トマト」と両方抽出されます。上図はカボチャは一部をカボスにして、「カボ」「含む」などで実行したものです。色々試してみてはいかがでしょうか。その他の項目や「以上」などの数値評価なども残っていますが、それは本物のオートフィルターにゆだねましょう。というわけで長かったオートフィルター自作も完結です。長々とお付き合いくださり、ありがとうございます。

この記事へのコメント


この記事へのトラックバック