Access VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


158 / 2272 ツリー ←次へ | 前へ→

【12753】複数抽出 ゆか 15/3/23(月) 15:21 質問[未読]
【12756】Re:複数抽出 かるびの 15/3/24(火) 4:22 回答[未読]
【12758】Re:複数抽出 ゆか 15/3/24(火) 14:14 質問[未読]
【12764】Re:複数抽出 かるびの 15/3/25(水) 2:08 回答[未読]
【12775】Re:複数抽出 ゆか 15/3/25(水) 18:56 質問[未読]
【12777】Re:複数抽出 かるびの 15/3/26(木) 2:26 回答[未読]
【12782】Re:複数抽出 ゆか 15/3/28(土) 17:08 質問[未読]
【12783】Re:複数抽出 かるびの 15/3/29(日) 2:09 回答[未読]
【12787】Re:複数抽出 ゆか 15/3/30(月) 20:51 質問[未読]
【12790】Re:複数抽出 かるびの 15/3/31(火) 2:43 回答[未読]
【12793】Re:複数抽出 ゆか 15/3/31(火) 22:23 お礼[未読]

【12753】複数抽出
質問  ゆか  - 15/3/23(月) 15:21 -

引用なし
パスワード
   こんにちは。

先日は、質問に教えて下さりありがとうございます。
別スレッドでも他の方が質問されているのですが
理解力が低くいまいちわからないためスレッドを立てさせていただきました。
ご多忙と存じますが、ご教授いただければ幸いです。

テーブル:利用者
利用者ID(主キー):テキスト型
請求コード:数値型
利用施設:テキスト型(テーブル:施設のルックアップ)
金融機関コード:数値型
支店コード:数値型
預金種目コード:数値型
口座番号:数値型
口座名義人:テキスト型
住所:テキスト型
連絡先:テキスト型
備考:メモ型
利用開始日:日付/時刻型
利用終了日:日付/時刻型
利用終了者:Yes/No型

をフォームウィザードの複数アイテムでフォームをそのまま作成し、
フォーム名を「利用者一覧」と名付け、へッダー部分に下記を追加しました。

テキストボックス(コントロールソース:非連結)
txt_利用者ID
txt_t口座名義人
txt_利用者名
txt_利用施設 (当初はコンボボックスで選択可能にしたかったのですが、全くうまくいかなかたっためテキストになっています。)
txt_開始日
txt_終了日
txt_口座番号

チェックボックス(コントロールソースなし)
利用終了者

ボタン
名前:cmdFilter 標題:抽出
名前:cmfFilterOff 標題:抽出解除

を作成、それらで複数抽出できるように下記のようにくみました。

Private Sub cmdFilter_Click()
  Dim strFilter As String, strExp As String, aryOpe As Variant


  If Not IsNull(Me.txt利用者ID) Then
    strFilter = " AND " & BuildCriteria("Me.txt利用者ID", _
      dbLong, Me.txt利用者ID)
  End If
  
  
   If Not IsNull(Me.txt口座番号) Then
    strFilter = " AND " & BuildCriteria("Me.口座番号", _
      dbLong, Me.txt口座番号)
  End If
  
 
  If Not IsNull(Me.txt口座名義人) Then
    strFilter = strFilter & " AND Me.口座名義人 Like '*" & Me.txt口座名義人 & "*'"
  End If
  
 
  If Not IsNull(Me.txt利用者名) Then
     strFilter = strFilter & " AND Me.利用者名 Like '*" & Me.txt利用者名 & "*'"
  End If
  
 
   If Not IsNull(Me.txt利用施設) Then
     strFilter = strFilter & " AND Me.利用施設 Like '*" & Me.txt利用施設 & "*'"
  End If
  
  
  If Not IsNull(Me.txt開始日) Then
    strFilter = strFilter & " AND Me.開始日 >= #" & Nz(Me.txt開始日) & "#"
  End If
  
  
  If Not IsNull(Me.txt終了日) Then
    strFilter = strFilter & " AND Me.終了日 <= #" & Nz(Me.txt終了日) & "#"
  End If


If Not IsNull(Me.利用終了者) Then
    strFilter = "(" & strFilter & ") or [Yes/No型利用終了者]=True"
End If


  Me.Filter = Mid(strFilter, 8)
  If strFilter = "" Then
    Me.FilterOn = False
   Else
    Me.FilterOn = True
  End If
 
End Sub

Private Sub cmdFilterOff_Click()
  Me.Filter = ""
  Me.FilterOn = False
  Me.txt_利用者ID = Null
  Me.txt_口座名義人 = Null
  Me.txt_利用者名 = Null
  Me.txt_利用施設 = Null
  Me.txt_開始日 = Null
  Me.txt_終了日 = Null
  Me.txt_口座番号 = Null
  Me.利用終了者 = Null
End Sub

この場合、クエリ式に演算子気がありませんと言われ、
下記の部分がひっかかってしまいます。

Me.Filter = Mid(strFilter, 8)
  If strFilter = "" Then
    Me.FilterOn = False
   Else
    Me.FilterOn = True
  End If

上記をうまく抽出するにはどのようにしたら宜しいでしょうか。
御面倒をおかけしますが、何卒よろしくお願いいたします。

【12756】Re:複数抽出
回答  かるびの  - 15/3/24(火) 4:22 -

引用なし
パスワード
   >If Not IsNull(Me.利用終了者) Then
>    strFilter = "(" & strFilter & ") or [Yes/No型利用終了者]=True"
>End If
 第1に、「利用終了者」というフィールドは存在しますが、
「Yes/No型利用終了者」というフィールドは存在しません。
 単なる間違いですかね。

 第2に、このコードだと、
「利用終了者」チェックボックスがFalseの場合でも、
「利用終了者」フィールドがTrueであるレコードが抽出されていまいます。
 こんな動作で良いのでしょうか。


>Me.Filter = Mid(strFilter, 8)
 以下は基本的なデバッグの方法の一つです。
 
 このコードの直前の行に
   Debug.Print "Mid関数前:" & strFilter  
というコードを挿入し、直後の行に
   Debug.Print "Mid関数後:" & strFilter  
というコードを挿入してください。

 次に、VBEにおいて、イミディエイトウィンドウを開いてください。
具体的には、VBEのメニューの「表示(V)」→「イミディエイト ウィンドウ(I)」
のコマンドを実行してください。

 その上で、cmdFilter_Clickのイベントプロシージャを実行してみてください。

 イミディエイトウィンドウに、「Debug.Print ××」のコードが実行された時点
におけるstrFilter変数に格納された値が表示されます。

 それを見て、予定どおりの値になっているかよく確認してください。


 同じことを角度を変えてお尋ねしますが、
「Mid(strFilter, 8)」の「8」は、なぜ「8」なのですか。


 以下蛇足です。
>If Not IsNull(Me.利用終了者) Then
 「利用終了者」チェックボックスのTripleStateプロパティは、
どのように設定されていますか。
 おそらく、Falseが設定されていると思います。

 そうだとすると、チェックボックスは、TrueかFalseのいずれかの値しか返さず、
Nullはありえません。
 したがって、常に「If Not IsNull(Me.利用終了者) Then」の条件を
充たすことになります。
 つまり、「If Not IsNull(Me.利用終了者) Then」という条件には、
意味がないということです。


>If Not IsNull(Me.txt開始日) Then
 txt開始日に「2015/13/32」という値が入力された場合、これはNullでないので、
上記If文に該当することになります。
 しかし、「2015/13/32」なんて日付はないので、
Filterプロパティへの代入のところでエラーになります。
 そのため、IsNull関数の代わりにIsDate関数を使って、
有効な日付かどうかチェックした方がいいと思います。
 

>テーブル:利用者
>利用者ID(主キー):テキスト型
>請求コード:数値型
>利用施設:テキスト型(テーブル:施設のルックアップ)
>金融機関コード:数値型
>支店コード:数値型
>預金種目コード:数値型
>口座番号:数値型
>口座名義人:テキスト型
>住所:テキスト型
>連絡先:テキスト型
>備考:メモ型
>利用開始日:日付/時刻型
>利用終了日:日付/時刻型
>利用終了者:Yes/No型

 施設利用についての情報と、利用者についての情報が混在しています。
 それぞれ別テーブルに分けた方が良いでしょう。
 例えば、次のとおりです。

「施設利用」テーブル
利用ID   オートナンバー 主キー
施設ID   長整数型
利用者ID  長整数型
利用開始日 日付型
利用終了日 日付型
備考    メモ型

「利用者マスタ」テーブル
利用者ID  オートナンバー 主キー
氏名    テキスト型
住所    テキスト型
連絡先   テキスト型
利用終了者 Yes/No型

 金融機関コード、支店コード、預金種目コード、口座番号、口座名義人の
各フィールドですが、
利用者の預金口座を入力するのか、施設設営者の預金口座を入力するのか
わからなかったので、振り分けてはいません。
 利用者の預金口座なら、これらのフィールドは「利用者マスタ」テーブルに設けることになると思います。

 「請求コード」フィールドですが、
「利用者」テーブルに置くのではなく、
「請求」テーブルに長整数型の「利用ID」フィールドを設けるべきだと思います。

【12758】Re:複数抽出
質問  ゆか  - 15/3/24(火) 14:14 -

引用なし
パスワード
   かるびの様

ご多忙の中、返信ありがとうございます!


> 第1に、「利用終了者」というフィールドは存在しますが、
>「Yes/No型利用終了者」というフィールドは存在しません。
> 単なる間違いですかね。
他のところで、「Yes/No型〇〇〇」と書いてあったので、
書く必要があるものだと思っていました…。

> 第2に、このコードだと、
>「利用終了者」チェックボックスがFalseの場合でも、
>「利用終了者」フィールドがTrueであるレコードが抽出されていまいます。
> こんな動作で良いのでしょうか。
Falseの場合はFalseのみ、TrueのときはTrueのもののみ抽出できるようにしたいです。


>>Me.Filter = Mid(strFilter, 8)
> 以下は基本的なデバッグの方法の一つです。
> 
> このコードの直前の行に
>   Debug.Print "Mid関数前:" & strFilter  
>というコードを挿入し、直後の行に
>   Debug.Print "Mid関数後:" & strFilter  
>というコードを挿入してください。
>
> 次に、VBEにおいて、イミディエイトウィンドウを開いてください。
>具体的には、VBEのメニューの「表示(V)」→「イミディエイト ウィンドウ(I)」
>のコマンドを実行してください。
>
> その上で、cmdFilter_Clickのイベントプロシージャを実行してみてください。
>
> イミディエイトウィンドウに、「Debug.Print ××」のコードが実行された時点
>におけるstrFilter変数に格納された値が表示されます。
>
> それを見て、予定どおりの値になっているかよく確認してください。
予定通りの値には、なっておりませんでした・・・。

やはり
Me.Filter = Mid(strFilter, 8)でひっかかり、イミディエイトウィンドウには
Mid関数前: AND Me.txt利用者ID=100250001 AND Me.開始日 >= ## AND Me.終了日 <= ##と表示されています。因みに
>>If Not IsNull(Me.txt開始日) Then
> txt開始日に「2015/13/32」という値が入力された場合、これはNullでないので、
>上記If文に該当することになります。
> しかし、「2015/13/32」なんて日付はないので、
>Filterプロパティへの代入のところでエラーになります。
> そのため、IsNull関数の代わりにIsDate関数を使って、
>有効な日付かどうかチェックした方がいいと思います
上記で教えていただいたように、IsNullをIsDateに変更させていただきました。


> 同じことを角度を変えてお尋ねしますが、
>「Mid(strFilter, 8)」の「8」は、なぜ「8」なのですか。
色々な所でMid(strFilter, 6)が使われていたのですが、
フィルター項目が6項目の物ばかりだったので、項目数の数だと思い
フィルター項目が8あったので、8にしてみました!


> 以下蛇足です。
>>If Not IsNull(Me.利用終了者) Then
> 「利用終了者」チェックボックスのTripleStateプロパティは、
>どのように設定されていますか。
> おそらく、Falseが設定されていると思います。
> そうだとすると、チェックボックスは、TrueかFalseのいずれかの値しか返さず、
>Nullはありえません。
> したがって、常に「If Not IsNull(Me.利用終了者) Then」の条件を
>充たすことになります。
> つまり、「If Not IsNull(Me.利用終了者) Then」という条件には、
>意味がないということです。

トリプルステートは、仰る通り「いいえ」になっていました。
そうなんですね!そういう意味だということを初めて知りました。
教えて下さり、ありがとうございます!


> 施設利用についての情報と、利用者についての情報が混在しています。
> それぞれ別テーブルに分けた方が良いでしょう。
> 例えば、次のとおりです。
>
やはり分けたほうが宜しいのですね。
当初は何個かに分けていたのですが、
いまいちリレーションシップを作成する際に
一対多がいまいちわからなくなり、
一つのテーブルにまとめちゃったのが宜しくなかったのですね。
リレーションをマスターして、次回からはきちんと組めるように努めます!

【12764】Re:複数抽出
回答  かるびの  - 15/3/25(水) 2:08 -

引用なし
パスワード
   >Me.Filter = Mid(strFilter, 8)でひっかかり、
 このコードを
   strFilter = Mid(strFilter, 8)
   Me.Filter = strFilter
に変えてください。
 そして、前回のレスで紹介した「Debug.Print ××」のコードを
「strFilter = Mid(strFilter, 8) 」のコードの前後に入れてください。
 その上で、イミディエイトウインドウにどのような文字列が表示されるのか
確認してみてください。


>イミディエイトウィンドウには
>Mid関数前: AND Me.txt利用者ID=100250001 AND Me.開始日 >= ## AND Me.終了日 <= ##と
>表示されています。
 
 エラーになる一つの原因は、「Me.txt利用者ID」です。

 Filterプロパティに設定する文字列の基本は、
   フィールド名 = 値
です。
 「Me.txt利用者ID」は、フィールド名ではなく、テキストボックス名です。
 「Me.txt利用者ID」の部分をフィールド名へと変えてください。

 フィールドとテキストボックスをごっちゃにしている人をよく見かけますが、
両者は全然別のものなので、きちんと区別する必要があります。
 フィールド名は、テーブル又はクエリにおける列の見出しのことです。
 フォームには、フィールドという概念はありません。

 また、書いてよいフィールド名は、
フォームのレコードソースたるテーブル又はクエリに存在するフィールド名に限ります。


 「Me.開始日」や「Me.終了日」についても同様です。


 もう一つの原因は、「Me.開始日 >= ## 」です。
 #と#の間には、例えば「2015/03/24」のような文字列が入っていなければいけないわけですが、
それが入っていないということです。

>上記で教えていただいたように、IsNullをIsDateに変更させていただきました。
 おそらく、「If Not IsNull(Me.txt開始日) Then」における「IsNull」を「IsDate」に
変えただけなんでしょう。
 そのようにすれば、「Me.開始日 >= ## 」という条件式が生成されてしまいます。
 でも、それではだめですよ。

 「If Not IsNull(Me.txt開始日) Then」は、「txt開始日の値がNullでなければ」
という条件なわけですが、
IsDate関数を使うのであれば、「txt開始日の値が日付として使える文字列であれば」という
条件にする必要があります。

 IsNull(××)において「××」がNullのときにIsNull関数が何を返すのか、
「××」がNullでなければIsNull関数が何を返すのか、
IsDate(××)において「××」が日付として使用可能な文字列のときに
IsDate関数が何を返すのか、
「××」が日付として使用不可な文字列のときに
IsDate関数が何を返すのか、
をヘルプで確認してみてください。


>フィルター項目が6項目の物ばかりだったので、項目数の数だと思い
>フィルター項目が8あったので、8にしてみました!
 ヘルプでMid関数を調べて、Mid関数の2番目の引数が何を意味するものなのか確認してください。

【12775】Re:複数抽出
質問  ゆか  - 15/3/25(水) 18:56 -

引用なし
パスワード
   かるびの さん

有難うございます!

IsDate関数やMid関数について調べてみました。

Is date関数って=dateと同じだったんですね!
「Is Date
式を日付に変換できるかどうかを調べ、結果をブール値で返します。」
strFilter = strFilter & " AND Me.終了日 <= #" & Nz(Me.利用終了日) & "#"
が何をいれてみたらよいかが見当もつきませんでした。
すみません。

Mid関数も調べてみました。
Mid(string, start [, length ] )
「必ず指定します。Long データ型 の値を指定します。引数 string の先頭の位置を 1 として、どの位置から文字列を取り出すかを先頭からの文字数で指定します。start で指定した値が、string の文字数より大きい場合、Mid 関数は、長さ 0 の文字列 ("") を返します。」
ということだったので、文字数の最大値を設定すればいいってことで
宜しいでしょうか?理解力が低くて申し訳ありません。


> このコードを
>   strFilter = Mid(strFilter, 8)
>   Me.Filter = strFilter
>に変えてください。
> そして、前回のレスで紹介した「Debug.Print ××」のコードを
>「strFilter = Mid(strFilter, 8) 」のコードの前後に入れてください。
> その上で、イミディエイトウインドウにどのような文字列が表示されるのか
>確認してみてください。
>
>> エラーになる一つの原因は、「Me.txt利用者ID」です。
>
> Filterプロパティに設定する文字列の基本は、
>   フィールド名 = 値
>です。
> 「Me.txt利用者ID」は、フィールド名ではなく、テキストボックス名です。
> 「Me.txt利用者ID」の部分をフィールド名へと変えてください。
>
> フィールドとテキストボックスをごっちゃにしている人をよく見かけますが、
>両者は全然別のものなので、きちんと区別する必要があります。
> フィールド名は、テーブル又はクエリにおける列の見出しのことです。
> フォームには、フィールドという概念はありません。
>
> また、書いてよいフィールド名は、
>フォームのレコードソースたるテーブル又はクエリに存在するフィールド名に限ります。
>
>
> 「Me.開始日」や「Me.終了日」についても同様です。

早速フィールド名に変更してみました!
ただ、

> もう一つの原因は、「Me.開始日 >= ## 」です。
> #と#の間には、例えば「2015/03/24」のような文字列が入っていなければいけないわけですが、
>それが入っていないということです。
>
>>上記で教えていただいたように、IsNullをIsDateに変更させていただきました。
> おそらく、「If Not IsNull(Me.txt開始日) Then」における「IsNull」を「IsDate」に
>変えただけなんでしょう。
> そのようにすれば、「Me.開始日 >= ## 」という条件式が生成されてしまいます。
> でも、それではだめですよ。
>
> 「If Not IsNull(Me.txt開始日) Then」は、「txt開始日の値がNullでなければ」
>という条件なわけですが、
>IsDate関数を使うのであれば、「txt開始日の値が日付として使える文字列であれば」という
>条件にする必要があります。
>
> IsNull(××)において「××」がNullのときにIsNull関数が何を返すのか、
>「××」がNullでなければIsNull関数が何を返すのか、
>IsDate(××)において「××」が日付として使用可能な文字列のときに
>IsDate関数が何を返すのか、
>「××」が日付として使用不可な文字列のときに
>IsDate関数が何を返すのか、
>をヘルプで確認してみてください。
>

がいまいちわかっていないためか、パラメータの入力をして下さい。
という表示がでて、イミディエイトには
Mid関数前: AND Me.口座番号=843803 AND Me.口座名義人 Like '**' AND Me.利用者名 Like '**' AND Me.利用施設 Like '**'
Mid関数後:座番号=843803 AND Me.口座名義人 Like '**' AND Me.利用者名 Like '**' AND Me.利用施設 Like '**'

と出てきました。益々こんがらって来ました。
物わかりが悪く、本当に申し訳ありません。

【12777】Re:複数抽出
回答  かるびの  - 15/3/26(木) 2:26 -

引用なし
パスワード
   >Is date関数って=dateと同じだったんですね!
>「Is Date
>式を日付に変換できるかどうかを調べ、結果をブール値で返します。」
>strFilter = strFilter & " AND Me.終了日 <= #" & Nz(Me.利用終了日) & "#"
>が何をいれてみたらよいかが見当もつきませんでした。

 第1に、IsDate関数ですが、Is と Date の間にスペースは入りません。


 第2に、IsDate関数とDate関数は、機能が全然異なる関数です。


 第3に、IsDate関数がどのような働きをするものなのかを把握するため、
次の操作を行ってみてください。 
 イミディエイトウィンドウにカーソルを移し、
   ? IsDate("2015/3/25")
と手入力し、エンターキーを押してみてください。
 次の行にIsDate関数の返り値が表示されます。

   ? IsDate("2015/13/32") 
とか
   ? IsDate("あいう")  
とか
   ? IsDate("")  
とか
   ? IsDate(Null)
も試してみてください。
 どういうときにTrueになり、どういうときにFalseになるか確認してください。


 第4に、IsDate関数を使うとすれば、
「If Not IsNull(Me.txt終了日) Then」とのコードで使います。
「strFilter = strFilter & " AND Me.終了日 <= #" & Nz(Me.利用終了日) & "#"」
のコードでは、IsDate関数は使いません。


>Mid関数も調べてみました。

>ということだったので、文字数の最大値を設定すればいいってことで
>宜しいでしょうか?理解力が低くて申し訳ありません。

 違います。

 イミディエイトウィンドウに
   ? Mid("あいうえおかきくけこ",2)
と手入力し、エンターキーを押してください。
 次の行にMid関数適用の結果が表示されます。
 
   ? Mid("あいうえおかきくけこ",5)
とか
   ? Mid("あいうえおかきくけこ",9)
も実行してみてください。
 その上でヘルプの説明をもう一度読み直してみてください。
 これでMid関数が何をする関数なのかイメージがつかめると思います。


>Mid関数前: AND Me.口座番号=843803 AND Me.口座名義人 Like '**' AND Me.利用者名 Like '**' AND Me.利用施設 Like '**'
   
 2つの問題点があります。

 まず、一つめ。
 問題となるのは「Me.」です。

 「Me.口座番号」というのは、「Me」テーブルの「口座番号」フィールド
という意味になります。
 しかし、「口座番号」フィールドが所属しているのは
「利用者」テーブルであり、「Me」なんて名前のテーブルは存在しませんよね。
 したがって、「『Me』テーブルの『口座番号』フィールド」
というフィールドは、存在しないフィールドです。
 上記の文字列中に「Me.」が入り込まないようにする必要があります。
 

 二つめ。
 例えば、「Me.口座名義人 Like '**'」です。
 「*」が二つ連続してしまっている点が問題です。

 そうならないようにするために、「If Not IsNull(Me.txt口座名義人) Then」
という条件分岐を入れているわけですが、
txt口座名義人の値が長さ0の文字列である場合、それはNullではないので、
条件成就となり、
「strFilter = strFilter & " AND Me.口座名義人 Like '*" & Me.txt口座名義人 & "*'"」
というコードが実行され、strFilter中に「Me.口座名義人 Like '**'」という
文字列が含まれてしまうわけです。
 「If Not IsNull(Me.txt口座名義人) Then」に加えて
「txt口座名義人の値が長さ0の文字列でない場合」という条件を付加する必要があります。

 もっとも、「口座名義人 Like '**'」という抽出条件だと、
口座名義人フィールドがNullでないレコードが全て抽出されるので、
この点についての対策を取らなくても、今回に限っては問題ないと思います。


>Mid関数前: AND Me.口座番号=843803 AND Me.口座名義人 Like '**' AND Me.利用者名 Like '**' AND Me.利用施設 Like '**'
>Mid関数後:座番号=843803 AND Me.口座名義人 Like '**' AND Me.利用者名 Like '**' AND Me.利用施設 Like '**'

 Mid関数前は「 AND Me.口座番号=843803・・・」だったものが、
Mid関数後には     「座番号=843803・・・」となってしまっていますが、
その理由は、上記のイミディエイトウィンドウを使った実験により、
もうおわかりですよね。

 それがわかれば、「strFilter = Mid(strFilter, 8)」において
Mid関数の引数に何を指定したらよいか考えてみてください。

【12782】Re:複数抽出
質問  ゆか  - 15/3/28(土) 17:08 -

引用なし
パスワード
   かるびのさん

いつも本当にありがとうございます!!!
そして、返信が遅くなってすみません。
IsDateについて色々試してみました!
?IsDate("2015/03/32")
False
?IsDate("2015/03/30")
True
?IsDate("H32/3/5")
True
?IsDate("平成32/2/1")
True
?IsDate("3月31日")
True
の様に、日付表示で対応されるものは正しいと表示されることはわかりました。

また
? Mid("あいうえおかきくけこ",2)
いうえおかきくけこ
? Mid("あいうえおかきくけこ",9)
けこ
? Mid("あいうえおかきくけこ",5)
おかきくけこ
? Mid("あいうえおかきくけこ",1)
あいうえおかきくけこ
? Mid("あいうえおかきくけこ",15)

という結果も出て、Mid(抽出対象,抽出対象の最初を指定)
のような意味であるということまでは認識でしました。
そして、イミディエイトウィンドウも?を遣えば答えが出てくるともわかりました。
ありがとうございます!


> 2つの問題点があります。
>
> まず、一つめ。
> 問題となるのは「Me.」です。
>
> 「Me.口座番号」というのは、「Me」テーブルの「口座番号」フィールド
>という意味になります。
> しかし、「口座番号」フィールドが所属しているのは
>「利用者」テーブルであり、「Me」なんて名前のテーブルは存在しませんよね。
> したがって、「『Me』テーブルの『口座番号』フィールド」
>というフィールドは、存在しないフィールドです。
> 上記の文字列中に「Me.」が入り込まないようにする必要があります。

非常に混乱しております。
Private Sub cmdFilter_Click()
  Dim strFilter As String, strExp As String, aryOpe As Variant


  If Not IsNull(利用者ID) Then
    strFilter = " AND " & BuildCriteria("利用者ID", _
      dbLong, 利用者ID)
  End If
  
  
   If Not IsNull(口座番号) Then
    strFilter = " AND " & BuildCriteria("口座番号", _
      dbLong, 口座番号)
  End If
  
 
  If Not IsNull(口座名義人) Then
    strFilter = strFilter & " AND 口座名義人 Like '*" & 口座名義人 & "*'"
  End If
  
 
  If Not IsNull(利用者名) Then
     strFilter = strFilter & " AND 利用者名 Like '*" & 利用者名 & "*'"
  End If
  
 
   If Not IsNull(利用施設) Then
     strFilter = strFilter & " AND 利用施設 Like '*" & 利用施設 & "*'"
  End If
  
  
  If Not IsDate(利用開始日) Then
    strFilter = strFilter
  End If
  
  
  If Not IsDate(利用終了日) Then
    strFilter = strFilter
  End If


If Not IsNull(利用終了者) Then
    strFilter = "(" & strFilter & ") or 利用終了者"
End If

 Debug.Print "Mid関数前:" & strFilter
  strFilter = Mid(strFilter, 6)
   Me.Filter = strFilter
Debug.Print "Mid関数後:" & strFilter
  If strFilter = "" Then
    Me.FilterOn = False
   Else
    Me.FilterOn = True
  End If
 
End Sub

Private Sub cmdFilterOff_Click()
  Me.Filter = ""
  Me.FilterOn = False
  利用者ID = Null
  口座名義人 = Null
  利用者名 = Null
  利用施設 = Null
  利用開始日 = Null
  利用終了日 = Null
  口座番号 = Null
  利用終了者 = Null
End Sub

と直してみて抽出したのですが、
レコードの一番上を抽出すことが出来る様になりました!
ただ、テキストボックスに入力したものと全く無関係という…。
理解力のなかさに呆れてしまわれてると思いますが、
ご教授いただければ幸いです。
何卒、宜しくお願いいたします。

【12783】Re:複数抽出
回答  かるびの  - 15/3/29(日) 2:09 -

引用なし
パスワード
   >> 「Me.口座番号」というのは、「Me」テーブルの「口座番号」フィールド
>>という意味になります。
>> しかし、「口座番号」フィールドが所属しているのは
>>「利用者」テーブルであり、「Me」なんて名前のテーブルは存在しませんよね。
>> したがって、「『Me』テーブルの『口座番号』フィールド」
>>というフィールドは、存在しないフィールドです。
>> 上記の文字列中に「Me.」が入り込まないようにする必要があります。
>
>非常に混乱しております。

 ここは、VBAとSQLは違うよということです。

 イベントプロシージャのコードは、VBAというプログラミング言語で書かれています。
 これに対し、Filterプロパティに設定する値、言い換えれば、strFilterに格納する値は、
SQLというプログラミング言語で書く必要があります。

 SQLといっても、文法自体はかなり単純であり、
SQLでクエリを作るという経験がないと、
SQLが独自のプログラミング言語であるということ自体意識しにくいと思います。
 しかし、VBAとSQLは全く異なる言語です。
 そのため、VBAで使えた言葉がSQLでは使えないとか、
SQLで使えた言葉がVBAでは使えないといったことあります。

 「Me」は、その例の一つであり、VBAでは「このフォーム」という意味ですが、
SQLでは特別の意味を持ちません。
 また、SQLでは、「A.B」とあった場合、AテーブルのBフィールドという意味になります。
これ以外の意味を持つことはありません。
 他方、VBAでは、「A.B」とあった場合、AテーブルのBフィールドという意味にはならず、
AオブジェクトのBプロパティとか、
Aオブジェクトに対するBメソッドとか、
Aオブジェクトの、(その下位概念である)Bオブジェクト
など幅広い意味を持ちます。
 したがって、strFilterに格納された値(文字列)中に、
VBA用語である「Me」を入れてはいけないということです。


>If Not IsNull(利用者ID) Then
>  strFilter = " AND " & BuildCriteria("利用者ID", _
>      dbLong, 利用者ID)
>End If

 本題ではありませんが、フィールドの名前とテキストボックスの名前を同じにするのは、
やめた方がいいと思います。
 両者を混同してしまいがちだからです。
 テキストボックスの名前は、元のとおり「txt_利用者ID」の方がいいと思います。


>If Not IsDate(利用開始日) Then
>  strFilter = strFilter
>End If

 2つの問題があります。

 まず、「If Not IsDate(利用開始日) Then」ということの意味ですが、
「『利用開始日』テキストボックスの値が日付ではない場合」という意味になります。
 この場合は、何もする必要はないわけですが、
これとは逆に、「利用開始日」テキストボックスの値が日付である場合には、
何か処理をする必要があるのではないですか。


 次に、「利用開始日」テキストボックスに入力された値を使った抽出条件が書かれていません。
 これでは、「利用開始日」テキストボックスや「利用終了日」テキストボックスに
どんな値を入力しても、それをフィルタに反映させることはできず、
「利用開始日」テキストボックスなどに入力した値を使ってのレコードの抽出はできません。

 元の
>strFilter = strFilter & " AND Me.開始日 >= #" & Nz(Me.txt開始日) & "#"
というコードのうち、フィールド名のところだけを直せば良かったのに
(IF文も直す必要がありますが)。


>  strFilter = Mid(strFilter, 6)
 Mid関数の第2引数がなぜ「8」ではだめなのか、本件では「6」でなければならないのはなぜか
ということを御理解いただけたようで、何よりです。

【12787】Re:複数抽出
質問  ゆか  - 15/3/30(月) 20:51 -

引用なし
パスワード
   かるびの様

クエリの公式がよくわからなかったら、VBAで違う言語にしてくれると
思っていたら、激しく勘違いをしていることはわかりました!
ただ、自分自身がいまVBAを使っているのかSQLを使っているのかも
混乱してきたので、まずはtxt○○を当てはめてみることにしました!


Private Sub cmdFilter_Click()
  Dim strFilter As String, strExp As String, aryOpe As Variant


  If Not IsNull(Me.txt利用者ID) Then
    strFilter = " AND " & BuildCriteria("利用者ID", _
      dbLong, Me.txt利用者ID)
  End If
  
  
   If Not IsNull(Me.txt口座番号) Then
    strFilter = " AND " & BuildCriteria("Me.txt口座番号", _
      dbLong, 口座番号)
  End If
  
 
  If Not IsNull(Me.txt口座名義人) Then
    strFilter = strFilter & " AND 口座名義人 Like '*" & Me.txt口座名義人 & "*'"
  End If
  
 
  If Not IsNull(Me.txt利用者名) Then
     strFilter = strFilter & " AND 利用者名 Like '*" & Me.txt利用者名 & "*'"
  End If
  
 
   If Not IsNull(Me.txt利用施設) Then
     strFilter = strFilter & " AND 利用施設 Like '*" & Me.txt利用施設 & "*'"
  End If
  
   
  If Not IsDate(Me.txt開始日) Then
    strFilter = strFilter & " AND 開始日 >= #" & Nz(Me.txt開始日) & "#"
  End If
  
  
  If Not IsDate(Me.txt終了日) Then
    strFilter = strFilter & " AND 終了日 =< #" & Nz(Me.txt終了日) & "#"
  End If
  
  
If Not IsNull(Me.利用終了者) Then
    strFilter = "(" & strFilter & ") or 利用終了者"
End If

 Debug.Print "Mid関数前:" & strFilter
  strFilter = Mid(strFilter, 6)
   Me.Filter = strFilter
Debug.Print "Mid関数後:" & strFilter
  If strFilter = "" Then
    Me.FilterOn = False
   Else
    Me.FilterOn = True
  End If
 
End Sub

Private Sub cmdFilterOff_Click()
  Me.Filter = ""
  Me.FilterOn = False
  Me.txt利用者ID = Null
  Me.txt口座名義人 = Null
  Me.txt利用者名 = Null
  Me.txt利用施設 = Null
  Me.txt開始日 = Null
  Me.txt終了日 = Null
  Me.txt口座番号 = Null
  Me.txt利用終了者 = Null
End Sub

結果は、お蔭様で利用者名と口座名義人名はばっちり検索できるようになりました!
ありがとうございます!

利用施設も、施設名での検索は不可能ですが、
ルックアップ時の数字であれば検索ができるようになりました!

ただ、利用者IDや口座番号は
抽出条件でデータ型が一致しません。
Mid関数前: AND 利用者ID=1となり、
利用終了者にチェックを入れると実行時エラー3075
不要な')'があると指摘されます。
開始日、終了日においては検索機能を果たさず、
Mid関数前: AND 開始日 >= ##
となります。

ちょっとずつ理解できはじめましたが、
理解力が乏しく、かるびの様に多大なる負担をお掛けいまして
大変申し訳ありません。本当にいつも感謝しております。ありがとうございます。

【12790】Re:複数抽出
回答  かるびの  - 15/3/31(火) 2:43 -

引用なし
パスワード
   >ただ、自分自身がいまVBAを使っているのかSQLを使っているのかも
>混乱してきたので、
 今自分が書いているのが、VBAなのかSQLなのかは、あまり神経質になる必要はない
と思います。
 ただ、Filterプロパティに設定する文字列中に書いていけないVBA用語があるということを
頭の片隅に置いておけば十分だと思います。


>ただ、利用者IDや口座番号は
>抽出条件でデータ型が一致しません。
とのことですが、
>strFilter = " AND " & BuildCriteria("利用者ID", _
>      dbLong, Me.txt利用者ID)
のコードを見る限り、利用者IDは、「dbLong」つまり長整数型ですね。

 他方、テーブル構成を見てみると、利用者IDはテキスト型だと書いてありました。
 
 だから、データ型が一致しないというエラーになります。


>利用終了者にチェックを入れると実行時エラー3075
>不要な')'があると指摘されます。
 strFilter変数に何が格納されているか確認してみましょう。
 「strFilter = "(" & strFilter & ") or 利用終了者"」のコードで付与した
「(」は、Mid関数を通すことで消されてしまっているはずです。
 だから、このコードで付与した「)」が余計な括弧になってしまっています。

 これへの対策は、ちょっと面倒ですね。
 strFilterへ格納する順番を変えるというのが1つの方法です。
 もっとも、ただ順番を変えるだけではだめです。
strFilter変数の冒頭5文字は、Mid関数により消してしまうわけですから、
「(」が冒頭の「 AND 」よりも後になるようにして、strFilter変数へ格納しなければいけません。

 他の方法として、先頭の「 AND 」の前に「(」を付加するのではなく、
Replace関数を使って、先頭の「 AND 」が「 AND (」となるように文字列を変える
という方法もありですね。


>開始日、終了日においては検索機能を果たさず、
>Mid関数前: AND 開始日 >= ##
>となります。

 これについては、何度も指摘しているんですが。
 「If Not IsDate(Me.txt開始日) Then」を日本語で言えば、どんな意味になるのか、
そして、そういう条件でいいのかを考え直してみてください。


 余談になりますが、「If Not IsDate(Me.txt開始日) Then」というコードの書き方は、
私は良くないと思っています。
 1つは、「= True」を省略している点です。
 ネット上でコード例を見てみると、
「= True」を省略しているコード例の方がはるかに多いのですが、
数か月後にコードを読み直したときに、
「= True」が省略されていると、意味が取りにくいんですよね。
 慣れの問題だとは思うのですが、私は、「= True」は省略しないようにしています。

 もう1つは、「Not」です。
 「Not」があるために意味が取りにくくなっています。
 ここは、「Not」と使わずにコードを書いた方が、
後でコードを見たときに意味を取りやすいと思います。
 なお、「Not」と使わずにコードを書くためには、
「If Not IsDate(Me.txt開始日) Then」というコードの日本語訳がしっかりできていないと、
「Not」を使わないコードは書けませんよ。

【12793】Re:複数抽出
お礼  ゆか  - 15/3/31(火) 22:23 -

引用なし
パスワード
   かるびの様

無事に全て抽出することが出来る様になりました!
ありがとうございます!

まだまだ、完璧に理解しているわけではありませんが、
こうすれば抽出表示が出来、解除がされるということがわかりました。

そして、最初にかるびのさんが
何故説明時にデータ型など書いたほうが親切なのか
身を以て学ぶことが出来ました!
本当にありがとうございます。

まだまだわからないことばかりで尋ねることもあると思いますが、
その時はまたどうぞ宜しくお願いいたします。

本当に本当にありがとうございました!

158 / 2272 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
1078188
(SS)C-BOARD v3.8 is Free