[三流君] −−> [VBAで楽しく] −−> [バックナンバー一覧]
−−> No.126 Access Like演算子でパターンマッチングしてみた

Access Like演算子でパターンマッチングしてみた

メルマガ発行内容

<Access Like演算子でパターンマッチングしてみた>

どうも、三流プログラマーのKen3です。 最近、質問もらうけど、 なかなか、解答できてない三流プログラマーのKen3です。 ※私のレベルで手に余る高度な質問が多くて。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba126.lzh にdb126.mdb(Access2000版)が保存されています。

/* * 1. 今回のキッカケ */

ヤバイ・・・ほったらかしの問題が、多いんだよね。 http://www.ken3.org/backno/backno_vba22.html#107 の No.107 Access サブフォームの明細データを検索、メインを移動 で、 メンバーを検索、親のグループを移動、なんて処理を作ったんだけど、 イロイロと課題を残したままでした。 まぁ、クリアしたい課題は、 テーブルにはフルネームで入っているけど検索は一部でしたい (複数レコードが該当(メンバー名で同じ名前)した場合) なんて感じの処理かなぁ。 親テーブル名:T_バンド名 バンドID オートナンバー バンド名称 テキスト 備考 メモ型 子テーブル名:T_メンバー 個人ID オートナンバー バンドID 長整数型(親テーブルとリンクする) 名前 文字型 楽器 文字型 出身地 文字型 生年月日 日付型 *今回関係ないけど 備考 文字型 *今回関係ないけど と、テーブルがあって、データが (野球のデータ入れるけどカンベンしてね、あっ阪神優勝おめでとう・・・) テストデータ 親テーブル名:T_バンド名 ^^^^^^^^^^^^ バンドID バンド名称 備考 1 BOOWY 伝説のバンド? 2 てすと モーニング娘はメンバー多いしバンドじゃないし(笑) 3 てすとですよ う〜ん、音楽関係、無知(笑) 4 プロ野球 野球選手 テストデータ 子テーブル名:T_メンバー ^^^^^^^^^^^^ 個人ID バンドID 名前 楽器 出身地 生年月日 備考 1 1 氷室 群馬 2 1 布袋 群馬 3 1 松井 群馬 4 1 高橋 福島 5 2 Ken3 東京 6 2 ZZZ 神奈川 7 2 AAA 東京 8 3 ジャガイモ 北海道 9 3 リンゴ 青森 10 3 メロン 北海道 11 3 コメ 新潟 12 2 高橋 愛 どこ? 13 4 高橋 雅裕 不明 14 4 高橋よしのぶ 不明 15 4 高橋ひさのり 不明 なんて感じのデータがあった時、 名前の検索で、高橋が指定された時に、 現在のDlookupで検索だと、対応できない。 今回は、リストボックスを使って、選択してみたいと思います。 --- 枠外・余談 --- 高橋と言えば高橋 雅裕でしょ(オイオイ) 高橋 愛?ダレそれ?・・・オイオイ 高橋と言えば、思い浮かぶのは、人それぞれだと思います。 プロ野球だと、高橋よしのぶ/ひさのり(漢字知らなくて(笑)) 高橋 雅裕?ってダレって人も多いと思います。 名古屋電気高から大洋ホエルズに83(4)〜 96年に千葉ロッテへ移籍 Ken3が好きだった選手の一人なんですね。 ^^^^^^^^^^^^^^^^^^^^^^^^^^ ピーク時は、 88年は遊撃手としては打率.293、守備率.989と12球団トップだったが、 タイトルは全て立浪に持っていかれる。 ※88〜89年、山下を超える連続守備機会無失策の新記録(353)も達成したが、  翌年からは、あれ?ポロポロと失策王の道へ、、外野へコンバート? 月刊ホエールズの「まーちゃんのおしゃべり泥棒」なんてのもあったなぁ。 今、名ショートと言えば、ヤクルト宮本選手や巨人の川相選手って感じだけど。

/* * 2.データが複数存在するかDCount関数とLike演算子で判断する */

まずは、データが複数存在するか、判断しますか。 元のソースは、
Private Sub btn検索_Click()
    Dim str検索条件     As String
    Dim str検索されたID As String
    
    'フォームの値を元に検索条件を作成する
    str検索条件 = "名前 = '" & Me!txt検索 & "'"

    'str検索条件を条件にバンドIDをT_メンバーテーブルから検索する
    str検索されたID = "" & DLookup("バンドID", "T_メンバー", str検索条件)

    '結果のテスト表示
    If str検索されたID = "" Then '検索できなかった?
        MsgBox Me!txt検索 & "は、見つかりませんでした"
    Else
        'データを移動させる
        DoCmd.GoToControl "バンドID"  'コントロールをIDへ移動
        DoCmd.FindRecord str検索されたID    'データを検索する
    End If

End Sub
こんな感じです、 ここに、高橋でパターンが一致するデータを数えるか。 データを数えるのって? Dcount関数があったから、これを使ってみますか。 Dcount関数のヘルプを見ると、 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expression.DCount(Expr, Domain, Criteria) =DCount("[受注コード]", "受注", "[出荷先都道府県] = '愛知県'") ってことは、 =DCount("フィールド名", "テーブル/クエリー", "検索条件") って感じだから、 nRCount = DCount("メンバー名", "T_メンバー", "名前 Like '*高橋*'") とすればOKかなぁ。 ※テストで確認したいときは、イミディエイト ウインドウを使って、 ? DCount("名前", "T_メンバー", "名前 Like '*高橋*'") 5  って感じで、テストすると、簡単ですよ。 ↑確認イメージ画面。 オイ、なんだよ条件に指定してある、 "名前 Like '*高橋*'"って? あっ、これですか? 通常 名前 = '高橋'なんて感じでイコールの完全一致なんだけど、 Like演算子を使用して、*や?を使って、パターンのマッチングが出来るんですよ。 名前 Like '*高橋*' とすることで、高橋を含むデータを取り出すことができます。 ※Like演算子、知っとくと便利ですよ。 さてと、カウント処理を組み込んでみましょう。
Private Sub btn検索_Click()
    Dim str検索条件     As String
    Dim str検索されたID As String
    Dim nRCNT           As Integer  '検索されたレコード数
    
    'フォームの値を元に検索条件を作成する
    'Like演算子と*を前後に勝手に付けるNo.126で追加、ついでにtrimも
    str検索条件 = "名前 Like '*" & Trim(Me!txt検索) & "*'"

    'データを条件指定で検索して、該当数を求める
    nRCNT = DCount("名前", "T_メンバー", str検索条件)

    '検索結果によって、処理を分ける
    Select Case nRCNT
        Case 0: 'レコード数=0 見つからなかった
            str検索されたID = "" 'IDに見つからなかった印として、""を代入
            MsgBox Me!txt検索 & "は、見つかりませんでした"
        Case 1: '1件見つかった(単独の時)
            'str検索条件を条件にバンドIDをT_メンバーテーブルから検索する
            str検索されたID = "" & DLookup("バンドID", "T_メンバー", str検索条件)
            '↑バンドIDがほしかったので、DLookupでバンドIDを検索する
        Case Is >= 2:  '2件以上の時(Case Elseでも可能)
            '複数データがあったので、別フォームから選択させる
            MsgBox "複数見つかったよ、選んでね"
    End Select

    'データを移動させる
    If str検索されたID <> "" Then 'バンドIDがセットされている?
        DoCmd.GoToControl "バンドID"  'コントロールをIDへ移動
        DoCmd.FindRecord str検索されたID    'データを検索する
    End If

End Sub
変更したポイントは、 ^^^^^^^^^^^^^^^^^^^^ str検索条件 = "名前 Like '*" & Trim(Me!txt検索) & "*'" で、検索条件を 名前 Like '*高橋*' とテキストボックスの前後に*を+した。 次に、メンバーテーブルから、名前のパターンが一致するレコード件数を nRCNT = DCount("名前", "T_メンバー", str検索条件) のように、DCount関数を使い、求めます。 あとは、求められた件数によって、分岐させてます。 Select Case nRCNT Case 0: 'レコード数=0 見つからなかった str検索されたID = "" 'IDに見つからなかった印として、""を代入 MsgBox Me!txt検索 & "は、見つかりませんでした" Case 1: '1件見つかった(単独の時) 'str検索条件を条件にバンドIDをT_メンバーテーブルから検索する str検索されたID = "" & DLookup("バンドID", "T_メンバー", str検索条件) '↑バンドIDがほしかったので、DLookupでバンドIDを検索する Case Is >= 2: '2件以上の時(Case Elseでも可能) '複数データがあったので、別フォームから選択させる MsgBox "複数見つかったよ、選んでね" End Select 普通に、 Case 0:だったら、該当データ無しにして、 Case 1:だったら、1件見つかったので(複数じゃないので)     親のバンドIDをそのまま求めます。 Case Is >= 2: 初めて書いたけど、2以上なら、複数なのでさらに選択処理を行う。     0と1以外のCase Elseって書き方でもいいけど、複数を強調したかったので、     気分で、Case Is >= 2としてみました。 なんとか、分岐したね。 あとは、複数時の選択処理ですね。 --- 余談・補足 --- イミディエイト ウインドウ? って感じの人は、 http://www.ken3.org/vba/iwind.html に イミディエイト ウインドウ(Ctrl+G) と Debug.Print なんて感じて、軽く書いてあるので、見てください。 関数の簡単なテスト実行など、できます。

/* * 3.データを選択後、結果を返すフォームを作成する */

ここまで、なんとか、できたので、 あとは、 高橋 愛 高橋 雅裕 高橋よしのぶ 高橋ひさのり を 選択させる処理を作成するか。 http://www.ken3.org/backno/backno_vba19.html#91 の No.91 Access ダイアログフォームって?何? acDialogとPublic変数を使用 で、 ダイアログフォームとPublic変数を使用して、 リストボックスから選択した値を返す方法をテストしてました。 この方法を使ってみたいと思います。 フォームを1つ作ります。 フォーム名: F_名前選択 リストボックス lst名前 選択ボタン btn選択 キャンセルボタン btnキャンセル 上記、3つのコントロールを配置します。 ↑画面イメージ リストボックス(lst名前)は、 ^^^^^^^^^^^^^^^^^        子テーブル名:T_メンバー 親テーブル名:T_バンド名   個人ID オートナンバー バンドID オートナンバー <--> バンドID 長整数型(親テーブルとリンクする) バンド名称 テキスト 名前 文字型 備考 メモ型 楽器 文字型 バンドIDでテーブルをつなげて、 バンドID,バンド名称,名前 を表示するように設定します。 まず、リストボックスのプロパティで、 値集合ソースを選択して、..のビルドボタンを押します ↑ビルドを押す画面イメージ すると、クエリーウィザードが起動するので、 テーブルをつなげて、表示データを作ります ↑クエリーの作成イメージ あとは、列見出しや幅のプロパティを調整します。 ここで、フォームを実行すると、 データがリストボックスに表示されると思います。 ↑リストボックス、フォームのイメージ あれれ、全部のデータが表示されているよ。 まぁまぁ、それは、最後に取っといて(オイオイ) 次に、標準モジュールに、Public変数とフォームの起動関数を書きます。 Public str選択バンドID As String 'グローバルでIDのエリアを取る 'フォームを開き、選択されたバンドIDを返す
Function SELECT_メンバー名()

    Dim stDocName As String
    Dim stLinkCriteria As String

    str選択バンドID = ""  'グローバル変数の初期化

    stDocName = "F_名前選択"
    'acDialog指定でフォームを開く
    DoCmd.OpenForm stDocName, , , stLinkCriteria, , acDialog

    'フォーム終了後、
    SELECT_メンバー名 = str選択バンドID  'リターン値として返す

End Function
グローバルで、確保した変数、 str選択バンドIDを””で初期化してから、 F_名前選択フォームを開きます。 acDialog指定なので、フォームが閉じられたら、制御が戻ってきます。 フォーム側でグローバル変数に選択結果がセットされているので、 SELECT_メンバー名 = str選択バンドID として、リターン値で値を返します。 F_名前選択フォーム側には、 まず簡単なのが、btnキャンセルの処理。 これは、キャンセルボタンがクリックされたら、何もしないでフォームを閉じます。
Private Sub btnキャンセル_Click()
    DoCmd.Close  '何もしないで閉じる
End Sub
クリックイベントに、DoCmd.Closeを書いただけでした。 次は、本命、選択ボタンがクリックされた時。 これも、あっけないんだけど、
Private Sub btn選択_Click()
    'リストボックスの値をグローバルにセットする
    str選択バンドID = Me!lst名前.Value
    '↑連結列でリストボックス(1列目)はバンドIDにしてあるので
    '値をそのまま代入してみた
    'フォームを閉じる
    DoCmd.Close  '閉じる
End Sub
クリックイベントで、 リストボックスの値をグローバルstr選択バンドIDにセットして、 フォームを閉じました。 フォームが閉じられると、 stDocName = "F_名前選択" 'acDialog指定でフォームを開く DoCmd.OpenForm stDocName, , , stLinkCriteria, , acDialog 'フォーム終了後、 SELECT_メンバー名 = str選択バンドID 'リターン値として返す と、 SELECT_メンバー名 = str選択バンドID の代入処理が走り、選択した値がFunction関数で返る、そんな仕組みです。 ※なんか、スムーズじゃないんだけどね。。。

/* * 4.リストボックスに条件を追加する */

さて、ここまで出来たので、あとは、 F_名前選択のリストボックスで、 条件指定してデータを表示すればOKかなぁ。 条件指定の方法、簡単な方法は、 リストボックスのクエリーに条件を追加します。 追加する条件は、名前の条件に、 Like "*" & Forms![F_Main]![txt検索] & "*" を追加します。 ↑クエリーに条件を追加したイメージ Forms![F_Main]![txt検索] と、メインフォームの検索条件、[高橋 ]と入力されているので、 それを使用しただけでした。 SELECT_メンバー名の関数で、メンバー選択後のバンドIDが返ってくるので、
Private Sub btn検索_Click()
    Dim str検索条件     As String
    Dim str検索されたID As String
    Dim nRCNT           As Integer  '検索されたレコード数
    
    'フォームの値を元に検索条件を作成する
    'Like演算子と*を前後に勝手に付けるNo.126で追加、ついでにtrimも
    str検索条件 = "名前 Like '*" & Trim(Me!txt検索) & "*'"

    'データを条件指定で検索して、該当数を求める
    nRCNT = DCount("名前", "T_メンバー", str検索条件)

    '検索結果によって、処理を分ける
    Select Case nRCNT
        Case 0: 'レコード数=0 見つからなかった
            str検索されたID = "" 'IDに見つからなかった印として、""を代入
            MsgBox Me!txt検索 & "は、見つかりませんでした"
        Case 1: '1件見つかった(単独の時)
            'str検索条件を条件にバンドIDをT_メンバーテーブルから検索する
            str検索されたID = "" & DLookup("バンドID", "T_メンバー", str検索条件)
            '↑バンドIDがほしかったので、DLookupでバンドIDを検索する
        Case Is >= 2:  '2件以上の時(Case Elseでも可能)
            '複数データがあったので、別フォームから選択させる
            MsgBox "複数見つかったよ、選んでね"
            str検索されたID = SELECT_メンバー名() '複数選択のフォーム処理
    End Select

    'データを移動させる
    If str検索されたID <> "" Then 'バンドIDがセットされている?
        DoCmd.GoToControl "バンドID"  'コントロールをIDへ移動
        DoCmd.FindRecord str検索されたID    'データを検索する
    End If

End Sub
追加したのは、 Case Is >= 2: で2件以上を判断したら、 str検索されたID = SELECT_メンバー名() '複数選択のフォーム処理 と、複数のデータを選択してみました。 ↑高橋を検索したイメージ -【けんぞう!】--------------------------------------------------------- 転職関係、在宅プログラマー、SOHOの広告まとめました http://www.ken3.org/etc/500yen/zaitaku.html いろいろとあるので転機の人はぜひ 登録料無料、匿名で探せるので在宅で小金稼ぎの人も見てね ~~~~~~~~~~~~~~~~ オレ様、私は、SE様だ、月給30万以上ボーナス100万を探すのもありだよ。 私にみたいにVBA少しできるぐらいだと仕事無いよ・・・なんて冷たく、 と軽く言われても匿名なら気にならないし(笑) 逆にこんな簡単な仕事で月給27万貰えるの?って会社もあるし、世の中イロイロ。 http://www.ken3.org/etc/500yen/job.html ------------------------------------------------------------------------ 

/* * 5.終わりの挨拶 */

今回は、Like演算子を使用して、検索文字の一部を入力させて、 名前 Like '*高橋*'みたいな、パターンマッチングに挑戦してみました。 今回の、サンプルファイルは、 http://www.ken3.org/vba/lzh/vba126.lzh にdb126.mdb(Access2000版)が保存されています。 ※実際にデータを検索しながら、試してみてください。 なんか、処理的にまだまだなんだけど、何かの参考となれば幸いです。 Excel/Access大好き、三流プログラマーKen3でした。


ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、

種類別のリンク や 広告など

気になったジャンル↓を選択してください。

人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

※↑文章の味付けが変わっていて、お口に合うかわかりませんが。。。
※※読んで、気分を悪くされたらスミマセン。

Blogとリンク:[三流君の作業日記]/ [VBAやASPのサンプルコード]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]