Access (VBA)

Access VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : Access 2016)
検索時文字列の空白を無視して検索したい
投稿日時: 21/06/30 16:28:09
投稿者: kayagum01

 
某テーブル 氏名フィルド ➡ 田中 花子 のようにデータが入力されています。
検索ボックスで検索する場合は、田中花子と空白が無しで入力したいですが、
空白を入れないとデータが抽出されません。
 
関連クエリは作成しておりませんので、VBAコードを希望します。
 
今現在の検索コードです。
Private Sub 検索_Click()
 
    Me.Filter = "氏名 like'*" & txt氏名検索 & "*'"
 
    Me.FilterOn = True
     
 End Sub
 
よろしくお願いいたします。

回答
投稿日時: 21/06/30 16:55:36
投稿者: sk

引用:
Private Sub 検索_Click()
  
    Me.Filter = "氏名 like'*" & txt氏名検索 & "*'"
  
    Me.FilterOn = True
      
End Sub

Private Sub 検索_Click()
 
    Dim strCriteria As String
     
    If Trim(Nz(txt氏名検索, "")) <> "" Then
        strCriteria = "Replace([氏名],' ','',1,-1,1) like '*" & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'"
    End If
     
    Me.Filter = strCriteria
    Me.FilterOn = (strCriteria <> "")
     
End Sub
 
------------------------------------------------------------------------
 
以上のように、それぞれの値に含まれる全ての半角/全角スペースを
空文字列に置換した結果同士を比較するようになさればよろしいかと。

投稿日時: 21/07/01 13:59:58
投稿者: kayagum01

 
ご回答頂きましてありがとうございます!
 
早速引用して見ましたが、#Name?のようなエラーが出ております。
 
よろしくお願いいたします。

回答
投稿日時: 21/07/01 14:22:43
投稿者: sk

引用:
早速引用して見ましたが、#Name?のようなエラーが出ております。

・連結テキストボックスの[コントロールソース]プロパティに
 そのフォームのレコードソースであるテーブル/クエリに
 存在しないフィールドの名前が設定されている。
 
・演算テキストボックスの[コントロールソース]プロパティに
 そのフォームのレコードソースであるテーブル/クエリに
 存在しないフィールド、またはそのフォーム上に存在しない
 コントロールを参照する式が設定されている。
 
今のところ考えられるのは以上のいずれか。

投稿日時: 21/07/01 14:54:01
投稿者: kayagum01

 
早速ご回答頂きましてありがとうございます!
 
ご教示頂いた内容を元に今一度確認して見ましたが➁は該当がないかなと
思いますが、@に関してもイマイチ理解出来ていなく根本的な原因は探し出すことは
出来ておりません〜 困りました〜
 
@連結テキストボックスの[コントロールソース]プロパティに
 そのフォームのレコードソースであるテーブル/クエリに
  存在しないフィールドの名前が設定されている。
  
➁演算テキストボックスの[コントロールソース]プロパティに
 そのフォームのレコードソースであるテーブル/クエリに
  存在しないフィールド、またはそのフォーム上に存在しない
  コントロールを参照する式が設定されている。
 [/quote]

回答
投稿日時: 21/07/01 15:50:57
投稿者: sk

引用:
ご教示頂いた内容を元に今一度確認して見ましたが➁は該当がないかなと
思いますが、@に関してもイマイチ理解出来ていなく根本的な原因は探し出すことは
出来ておりません

ではとりあえず、以下に示すそれぞれの設定内容を
具体的に明記されることをお奨めします。
 
・#Name? エラーを返しているテキストボックスの
 [コントロールソース]プロパティの設定値
 
・そのフォームの[レコードソース]プロパティの設定値
 
・[レコードソース]プロパティに設定されているのが
 クエリの名前である場合は、そのクエリの SQL ビューの内容

投稿日時: 21/07/02 09:51:00
投稿者: kayagum01

ご回答頂きましてありがとうございます!
 
関連クエリは作成していません。
「50音順」というテーブルからフォームを作成しています。
テーブルには12個のフィルドがありまして、フォームは全てのフィルドのテキストボックスが
あります。その全てのテキストボックスが#Name? になっています。
 
・#Name? エラーを返しているテキストボックスの
 [コントロールソース]プロパティの設定値 ➡それぞれ12個のフィルドの名前と同じになっています。
 
 
・そのフォームの[レコードソース]プロパティの設定値 ➡50音順
  
・[レコードソース]プロパティに設定されているのが
 クエリの名前である場合は、そのクエリの SQL ビューの内容 ➡ クエリはなし
 
上手く伝わればいいですが…
 
よろしくお願いいたします。

回答
投稿日時: 21/07/02 11:14:14
投稿者: sk

引用:
「50音順」というテーブルからフォームを作成しています。
テーブルには12個のフィルドがありまして、フォームは全てのフィルドのテキストボックスが
あります。その全てのテキストボックスが#Name? になっています。

恐らく、フィールド[氏名]の値が Null であるレコードが
テーブル[50音順]に存在するからでしょう。
(フィルター実行時に Replace 関数の第 1 引数 Expression に対して
Null が渡されようとしたことで発生したエラーによるもの)
 
引用:
strCriteria = "Replace([氏名],' ','',1,-1,1) like '*" & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'"

strCriteria = "Replace(Nz([氏名],''),' ','',1,-1,1) like '*" & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'"
 
------------------------------------------------------------------------
 
以上のように書き換えてみて下さい。

投稿日時: 21/07/02 11:47:54
投稿者: kayagum01

ご回答頂きましてありがとうございます!
出来ました! 感謝感謝です!
 
せっかくですが、コードの意味まで教えて頂けますと大変ありがたいです!
 
 If Trim(Nz(txt氏名検索, "")) <> "" Then ➡?
 
   strCriteria = "Replace(Nz([氏名],''),' ','',1,-1,1) like '*" ➡?
 & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'" ➡?
  
 
    End If
 
Me.FilterOn = (strCriteria <> "") ➡?
 
よろしくお願いいたします。

回答
投稿日時: 21/07/02 13:34:30
投稿者: sk

まず、それぞれの関数についての解説は下記の各記事を参照して下さい。
 
Nz 関数:
https://support.microsoft.com/ja-jp/office/nz-%E9%96%A2%E6%95%B0-8ef85549-cc9c-438b-860a-7fd9f4c69b6c
 
Trim 関数:
https://support.microsoft.com/ja-jp/office/ltrim-%E9%96%A2%E6%95%B0%E3%80%81rtrim-%E9%96%A2%E6%95%B0%E3%80%81%E3%81%8A%E3%82%88%E3%81%B3-trim-%E9%96%A2%E6%95%B0-e340ced1-67df-435f-b078-1527a4eddea2
 
Replace 関数:
https://support.microsoft.com/ja-jp/office/replace-%E9%96%A2%E6%95%B0-6acf209b-01b7-4078-b4b8-e0a4ef67d181
 

引用:
If Trim(Nz(txt氏名検索, "")) <> "" Then

ここでは、テキストボックス[txt氏名検索]の値( Null である場合は
空文字列に置換)から先頭と末尾の半角/全角スペースを取り除いた結果が
空文字列ではないか否かを判定しています。
 
上記の判定により、次のいずれかに該当するケースでは
フィルター条件式を作成しない(フォームフィルターを
適用しない)ようにしています。
 
・テキストボックス[txt氏名検索]の値が Null である。
 
・テキストボックス[txt氏名検索]の値が空文字列である。
 
・テキストボックス[txt氏名検索]に入力された文字列が
 半角/全角スペースのみで構成されている。
 
要するに、[txt氏名検索]に入力された文字列の中に
半角/全角スペース以外の文字が含まれている時のみ
フォームフィルターを実行するようにする、ということです。
 
引用:
strCriteria = "Replace(Nz([氏名],''),' ','',1,-1,1) like '*" & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'"

「フィールド[氏名]の値( Null である場合は空文字列に置換)に
含まれる全ての半角/全角スペースを空文字列に置換した結果」の中に、
「テキストボックス[txt氏名検索]の値に含まれる全ての半角/全角
スペースを空文字列に置換した結果」が含まれている(部分一致する)
レコードを抽出するフィルター条件式を変数 strCriteria に渡しています。
 
ここでの「全ての半角/全角スペースを空文字列に置換」とは、
それぞれの対象文字列(フィールド[氏名]の値、
及びテキストボックス[txt氏名検索]の値)の中から
全ての半角/全角スペースを取り除いた結果を得ることを
意味します。
 
引用:
Me.FilterOn = (strCriteria <> "")

変数 strCriteria の値が空文字列に等しいか否かを判定する
比較演算の結果( True / False )をフォームの FilterOn プロパティに
代入し、フォームフィルターの実行状態を切り替えています。
 
やっていることは、以下に示すコードと本質的には同じです。
 
----------------------------------------------------------------
 
'変数 strCriteria の値が空文字列ではない場合
If strCriteria <> "" Then
    'フォームフィルターを適用する
    Me.FilterOn = True
'変数 strCriteria の値が空文字列である場合
Else
    'フォームフィルターの適用を解除する
    Me.FilterOn = False
End If
 
----------------------------------------------------------------

投稿日時: 21/07/02 15:43:25
投稿者: kayagum01

ご回答頂きましてありがとうございます!
申し訳ございません‼ もう一つ補足で教えてください!
 
strCriteria = "Replace(Nz([氏名],''),' ','',1,-1,1) like '*" & Replace(txt氏名検索, " ", "", 1, -1, vbTextCompare) & "*'"
 
中の 1,-1,1 どんな意味でしょうか? vbTextCompare 型が一致しませんとどのように繋がりますか?
 
 
初歩的な質問で本当に申し訳ございません!
よろしくお願いいたします。

回答
投稿日時: 21/07/02 16:40:35
投稿者: sk

引用:
Replace([氏名],' ','',1,-1,1)

引用:
中の 1,-1,1 どんな意味でしょうか?

Replace 関数の引数 start, count, compare を明示的に指定しているだけです。
 
それぞれの引数の意味や役割については、前述した Replace 関数の
解説記事を参照して下さい。
念のため、以下の参考記事も示しておきます。
 
即効テクニック より:
https://www.moug.net/tech/acvba/0120001.html
 
私が例示したコードでは、「引数 find に渡された文字列(半角スペース)を
バイナリ比較(半角スペースと全角スペースを区別する)ではなく
テキスト比較(半角スペースと全角スペースを区別しない)で
対象文字列の先頭から検索し、ヒットした全ての文字列
(全ての半角スペースと全角スペース)を空文字列に置換する」
ということを明らかに示す目的から、そのように記述しています。
 
ただはっきり申し上げて、今回の場合は start, count, compare の指定を
全て省略しても恐らく問題ないと思います。
 
-------------------------------------------------------------------------
 
strCriteria = "Replace([氏名],' ','') like '*" & Replace(txt氏名検索, " ", "") & "*'"
 
-------------------------------------------------------------------------
 
なお、vbTextCompare とは VBA のモジュールに記述することが出来る
組み込み定数の 1 つであり、その値は数値の 1 です。
「 vbTextCompare 」の代わりに「 1 」と記述しても、
VBA 側で実行される Replace 関数は正常に動作します。
 
一方、クエリやフォームフィルターで用いられる言語は SQL であり、
その中で「 vbTextCompare 」という VBA でしか通用しない定数の
名前を記述しても、その定数の値をデータベースエンジンが
認識することは出来ません。
なので直接 1 という数値が SQL 側の Replace 関数の
引数 compare に渡されるように記述しています。
 
引用:
Me.Filter = strCriteria

なお、Filter プロパティに渡される直前の変数 strCriteria の値を
コードの実行後に確認(デバッグ)したい場合は、
次のステートメントを挿入して下さい。
 
---------------------------------------------------------------
 
'変数 strCriteria の値をイミディエイトウィンドウに出力する
Debug.Print strCriteria
 
'変数 strCriteria に格納されているフィルター条件式を
'フォームフィルターの条件式とする
Me.Filter = strCriteria
 
---------------------------------------------------------------

投稿日時: 21/07/02 16:59:50
投稿者: kayagum01

 sk 様
ご回答頂きましてありがとうございます!
 
何度も初歩的な問題を質問したにもかかわらずご丁寧に対応して頂いて
心から感謝申し上げます。
 
本当に優しい方ですね〜 改めて感謝感謝です!