Access VBA質問箱 IV

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

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


28 / 500 ページ ←次へ | 前へ→

【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番目の引数が何を意味するものなのか確認してください。
・ツリー全体表示

【12763】Re:複数条件での抽出
回答  かるびの  - 15/3/25(水) 0:54 -

引用なし
パスワード
   >コードが実行される前にまずエラーメッセージが出るようです。

 エラーメッセージが出るとき、strFilterにはどんな文字列が格納されていますか。
 次の方法で確認してみてください。

 まず、「Me.Filter = Mid(strFilter, 6)」の直前の行に
   Debug.Print strFilter
というコードを挿入します。

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

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

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


 strFilter中の日付に関する条件式は、
   日付 >= #2015/3/24#  
のようになっていなければいけないのですが、
「2015年3月24日」などとなっていたり、「2015/03」(日にちなし)となっていたりしませんか。


>書式を日付にしているからでしょうか・・?
 strFilter変数は、テキストボックスのValueプロパティ値を基に生成しているところ、
書式をどのように設定しても、テキストボックスのValueプロパティ値には影響しませんから、
書式設定は関係ないと思います。


>そもそも間違った日付を入力できないように、
>入力規則などを設定したほうがいいでしょうか?
 入力規則でもいいでしょう。
 
 ちなみ、私は、入力規則はあまり好きではないです。
 入力規則だと、細かな設定がやりにくいからです。

 私なら、
Private Sub txt開始日_BeforeUpdate(Cancel As Integer)
  If IsDate(Nz(txt開始日.Value,"")) = False Then
    Msgbox "おかしな日付です。"
    Cancel = True
  End
End Sub
とします。
 12755のレスでは、cmdFilter_Clickイベントでメッセージを出すコードを紹介したところですが、
入力チェックをするなら、BeforeUpdateで行うのが常道です。
・ツリー全体表示

【12762】OnMouseDownでShiftを取得するには?
質問  キンパレ  - 15/3/25(水) 0:39 -

引用なし
パスワード
   初めて投稿します。
至らぬ点があればご指摘ください。
よろしくお願い致します。

【質問】
フォーム上にラベルT1〜T30があったとします。
ラベルをクリックすることでキャプションをメッセージボックスで表示
するようにする場合、

Private Sub T1_Click()
  
  MsgBox Me.T1.Caption
  
End Sub

というプロシージャをT1〜T30まで個別に記述したのでは大変ですから、

Private Sub Form_Open(Cancel As Integer)

  For i = 1 To 30
    Me("T" & i).OnClick = "=msg(" & i & ")"
  Next i

End Sub

Private Function msg(n As Integer)

  MsgBox Me("T" & n).Caption

End Function

このようにフォームオープン時に一括設定にできますよね。

これをClickイベントではなくMouseDownイベントで引数を取得したい場合は
どのように記述すれば良いのでしょうか。
たとえばShiftを押しながら右クリックした場合にMsgBoxを出すようにします。
個別に記述すると下記のようになります。

Private Sub T1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  If Shift = 2 Then
    MsgBox Me.T1.Caption
  End If
  
End Sub

これを前述のOnClickのように纏めて設定するようにしたいのですが、
引数の部分をどのように記述すれば良いかがわかりませんでした。
引数なしで書くと下記のような感じです。

Private Sub Form_Open(Cancel As Integer)

  For i = 1 To 30
    Me("T" & i).OnMouseDown = "=msg(" & i & ")"
  Next i

End Sub

色々と検索してみたのですが、調べ方が悪いのかどうしても
該当する情報に辿りつけませんでした。
ご教示いただければ幸いです。
どうぞ宜しくお願いいたします。
・ツリー全体表示

【12761】Re:数値の種類をカウントするには
回答  hatena  - 15/3/24(火) 18:38 -

引用なし
パスワード
   ▼まなび さん:
>月別に、複数回来ている人も1回と数えて、実質何人の方が来られたかをカウントする方法はありますか?
>データの抽出範囲をひと月で区切って、そこに出てくる参加者の番号の種類をカウントできればと思うのですが、番号の種類自体をカウントする方法が分かりませんでした。

下記のような集計クエリを作成します。

フィールド 参加者番号 年月: Format([参加日],"yyyy/mm")
集計    グループ化 グループ化

この集計クエリからさらに集計クエリを作成して、下記のように設定します。

フィールド 年月    参加人数: 参加者番号
集計    グループ化 カウント

以上です。


サブクエリを使えば一つのSQLで可能です。

SELECT 年月, Count(参加者番号) AS 参加人数
FROM
(SELECT DISTINCT 参加者番号, Format([参加日],"yyyy/mm") AS 年月 FROM 参加日履歴)
AS T
GROUP BY 年月;
・ツリー全体表示

【12760】数値の種類をカウントするには
質問  まなび  - 15/3/24(火) 17:32 -

引用なし
パスワード
   アクセスの初心者です。

参加日ID(オートナンバー)
参加者番号
参加日(年月日)

という“参加日履歴”というテーブルを作りました。
各参加者の属性などの情報のテーブルをメインフフォームとして、上記の参加日履歴をサブフォームとして埋め込んで使っています。それぞれ参加者さんが、会に参加されるたびに参加した日を入力して使っています。

月別に、複数回来ている人も1回と数えて、実質何人の方が来られたかをカウントする方法はありますか?
データの抽出範囲をひと月で区切って、そこに出てくる参加者の番号の種類をカウントできればと思うのですが、番号の種類自体をカウントする方法が分かりませんでした。
月別ののべ参加人数はすぐに出るのですが・・・。
どなたかご回答いただけますと大変ありがたいです。よろしくお願い致します。
・ツリー全体表示

【12759】Re:複数条件での抽出
質問  木葉  - 15/3/24(火) 16:00 -

引用なし
パスワード
   ひとまず日付の部分だけでも、と思い直してみたのですが、
コードが実行される前にまずエラーメッセージが出るようです。

書式を日付にしているからでしょうか・・?

開始日のフォーカス喪失時などでも試してみましたが、同じような結果でした。


そもそも間違った日付を入力できないように、
入力規則などを設定したほうがいいでしょうか?

規則の条件の書き方も全く分からないのでできれば避けたいのですが…
・ツリー全体表示

【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」という条件には、
>意味がないということです。

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


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

【12757】Re:複数条件での抽出
発言  木葉  - 15/3/24(火) 11:14 -

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

お返事ありがとうございます!

>ここにいう「注意」というのは、エラーメッセージのことではないですかね
そうですね、そう言った方が適切ですね…ごめんなさい
頭にパッと「エラーメッセージ」が出てこなくて^^;(老化?)

> そういうエラーメッセージを出したくないので、IsDate関数を使うことを勧めたわけですが、
>ちょっと舌足らずでしたね
ありゃ、配慮いただきありがとうございます!
確かに、エラーメッセージそのままだと、エラーの原因が明確ではないですね。
(試してみたら「例えば数値型のフィールドに文字列を入力しました」と出ました。他の人から見たらなんのこっちゃですね。)

コードまで出していただきありがとうございます!

前に回答してくださった箇所も修正の途中なのですが、じっくり直していきます!


取り急ぎ、ありがとうございました!
・ツリー全体表示

【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」フィールドを設けるべきだと思います。
・ツリー全体表示

【12755】Re:複数条件での抽出
回答  かるびの  - 15/3/24(火) 3:28 -

引用なし
パスワード
   >長さ0の文字列ですか…そこまで考えていませんでした!
>これって「""」で表される文字の事でしょうか?
 そうです。


>>>If Not IsNull(txt開始日) Then
>のままでも、テキストボックスに「13/32」と入力して検索ボタンを押してみると、
>もう一度注意が出てきてコードは実行されません。
>IsDate関数は省いても問題はないですか?

 それで不満がないなら、IsDate関数を省いても構いません。

 ここにいう「注意」というのは、エラーメッセージのことではないですかね。
 そういうエラーメッセージを出したくないので、IsDate関数を使うことを勧めたわけですが、
ちょっと舌足らずでしたね。

 なお、私であれば、txt開始日に入力された値が日付としておかしなものである場合は、
「日付としておかしい」旨のメッセージを出して、コード実行を終了させてしまいます。

If IsDate(txt開始日.Value) = False Then
  Msgbox "開始日がおかしな日付です。"      
  Exit Sub
Else
  strFilter = strFilter & " AND 日付 >= #" & txt開始日.Value & "#"    
End If
・ツリー全体表示

【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

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

【12752】Re:複数条件での抽出
質問  木葉  - 15/3/23(月) 14:33 -

引用なし
パスワード
   ▼かるびの様:
お返事ありがとうございます!大変おそくなりました;


> コンボボックスの接頭語ですが、「cbo」の方がいいと思います。
> 「cmb」だと、コマンドボタンを意味する「cmd」と見間違えやすいからです。

あ、なるほど…確かにそうですね!直しておきます。


> 長さ0の文字列の場合にも対応しようというのであれば、Nz関数が使えると思います。

長さ0の文字列ですか…そこまで考えていませんでした!
これって「""」で表される文字の事でしょうか?


> それから、「.Value」は省略しない方がいいと思います。

なるほど、細かい点までありがとうございます!
加えておきます!


> txt発地都道府県の値を変数に受けるか、又はWithステートメントを使えば、
>テキストボックスを参照する回数を1回にできます。
>
> ただし、使う変数を増やすと、その分のメモリー領域を要することになるため、
>コードが遅くなると言われています。
>
> ちなみに私は、無駄に多くの変数を使っています。
> その方がコード内容を読み返したときに理解しやすいし、
>デバッグのときにコードが返す値を確認しやすいからです。

そうだったのですね…
withはエクセルでちょっとだけ使っていましたが苦手だと感じていたので、
私も変数に頼ります。
どのみち時間はかかりますが^^;


>>If Not IsNull(txt開始日) Then
> 例えば、txt開始日の値が「2015/13/32」だとしたら、どうなるか考えてみてください。
>
> Nullじゃないから、このIf文は通ります。
> そうすると、この値を使った条件式がstrFilterに代入されます。
> でも、この値は日付ではないので、Filterプロパティへの代入ででエラーになります。
>
> IsDate関数を使うと、日付として使える文字列かどうかチェックできます。

なるほどです。今試してみたのですが、注意はしてくれるけど入力自体はできるのですね…。
疑問に思ったのですが、
>>If Not IsNull(txt開始日) Then
のままでも、テキストボックスに「13/32」と入力して検索ボタンを押してみると、
もう一度注意が出てきてコードは実行されません。
IsDate関数は省いても問題はないですか?
足元がおぼつかない感じになるのであればこちらも修正させていただこうと思います!
・ツリー全体表示

【12751】畏まりました。
お礼  ゆか  - 15/3/23(月) 8:23 -

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

ご多忙の中ありがとうございます。
そのようにさせていただきます。
・ツリー全体表示

【12750】Re:別スレッドへ
発言  かるびの  - 15/3/21(土) 23:40 -

引用なし
パスワード
    12748や12749は、当初の「更新クエリについて」とは別の話になってしまっているので、
別にスレッドを立てた方がいいと思います。

 そのときは、12748については、「利用者一覧」フォームに関し、
そのレコードソース、
txt_利用者ID、txt_t口座名義人、txt_利用者名、txt_利用施設、txt_開始日、txt_終了日
及びtxt_口座番号の各コントロールソース
の情報を追加してください。
 また、12748については、どううまくいかないのか、つまり、何らかのエラーが出るのか、
エラーはでないが、予期したとおりの抽出ができないのかなどについても追加してください。
・ツリー全体表示

【12749】クエリのCSV出力について
質問  ゆか  - 15/3/21(土) 21:45 -

引用なし
パスワード
   そして、もう一つずっと詰まっていることがあります。

送付用というクエリがあるのですが

SELECT DISTINCT 利用者.請求コード, 請求.請求年月, 利用者.金融機関コード, 利用者.支店コード, 利用者.預金種目コード, 利用者.口座番号, 利用者.口座名義人, 請求.請求額, 請求.新規コード, Format([利用者].[利用者ID],"00000000000000") AS 利用者
FROM 利用者 INNER JOIN 請求 ON 利用者.利用者ID = 請求.利用者ID
WHERE (((請求.領収済)<>0))
ORDER BY 請求.請求年月, Format([利用者].[利用者ID],"00000000000000");

できちんと表示されていたものが、何故か
クエリ式'Format([利用者].[利用者ID],"のコンパイルエラーが発生しました

発生後の式は

SELECT DISTINCT 利用者.請求コード, 請求.請求年月, 利用者.金融機関コード, 利用者.支店コード, 利用者.預金種目コード, 利用者.口座番号, 利用者.口座名義人, 請求.請求額, 請求.新規コード, Format([利用者].[利用者ID],"00000000000000") AS 利用者
FROM 利用者 INNER JOIN 請求 ON 利用者.利用者ID = 請求.利用者ID
WHERE (((請求.領収済)<>0))
ORDER BY 請求.請求年月, 請求.請求年月;

何がよろしくないのでしょうか。
初歩的な事ばかりお尋ねして申し訳ありませんが、
何卒よろしくお願いいたします。
・ツリー全体表示

【12748】Re:更新クエリについて
質問  ゆか  - 15/3/21(土) 18:45 -

引用なし
パスワード
   先日は、親切丁寧に教えて下さりありがとうございました。
お蔭様で、うまく更新することが出来ました。
ありがとうございます。
そして、少しステップアップを試みました!
アクセス2010で、「複数のアイテム」で利用者のフォームを作成し、
複数の抽出が出来る様に試みました。
試みてはや4日、全くうまくいきません。
木葉さんのコメントもみているのですが、???が頭にうかんでばかりです。
もしよろしければ、何がいけないのか教えていただけませんでしょうか。
宜しくお願いいたします。

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

テーブル:施設
施設ID(主キー):オートナンバー型
施設名:テキスト型

テーブル:請求
請求No(主キー):オートナンバー型
請求年月:数値型
振替日:テキスト型
請求額:通貨型
新規コード:数値型
領収済:数値型
備考:メモ型

リレーションシップ
利用者:利用者ID 請求:利用者ID(一対多)

フォーム:利用者一覧
ヘッダー部分に下記を追加
テキストボックス
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("利用者ID", _
      dbLong, Me.txt_利用者ID)
  End If
  
   If Not IsNull(Me.txt_口座番号) Then
    strFilter = " AND " & BuildCriteria("口座番号", _
      dbLong, 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 IsNull(Me.txt_利用施設) Then
     strFilter = strFilter & " AND 利用施設 Like '*" & Me.txt_利用施設 & "*'"
  End If
  
  If Not IsNull(Me.txt_開始日) Then
    strFilter = strFilter & " AND 開始日 >= #" & Nz(Me.txt_開始日) & "#"
  End If
  
  If Not IsNull(Me.txt_終了日) Then
    strFilter = strFilter & " AND 終了日 <= #" & Nz(Me.txt_終了日) & "#"
  End If
  
If Not IsNull(Me.利用終了者) Then
    Me.Filter = "利用終了者 = '" & 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


拙文な上に長文で申し訳ありませんが、
どうぞ宜しくお願いいたします。
・ツリー全体表示

【12747】Re:複数条件での抽出
回答  かるびの  - 15/3/21(土) 0:57 -

引用なし
パスワード
    些細な点をいくつか。

>If Not IsNull(cmb取引先) Then
 cmb取引先というコンボボックス名ですが、ハンガリアン記法と呼ばれる命名法ですね。
 これは、変数名やコントロール名に
変数のデータ型を示す接頭語やコントロールの種類を示す接頭語を付ける命名法です。
 コンボボックスの接頭語ですが、「cbo」の方がいいと思います。
 「cmb」だと、コマンドボタンを意味する「cmd」と見間違えやすいからです。
 ま、趣味の問題だから、どっちでもいいんですけどね。
 

>If Not IsNull(txt発地都道府県) Then
 Nullの場合だけを除外するのでいいのかなあ。
 txt発地都道府県の値が長さ0の文字列である場合にどうなるか考えてみてください。
 
 長さ0の文字列の場合にも対応しようというのであれば、Nz関数が使えると思います。

 もっとも、手入力では長さ0の文字列をテキストボックスには入力できないので、
そこまで心配する必要はないかもしれません。
 

 それから、「.Value」は省略しない方がいいと思います。
 最近のエクセルVBAについての掲示板を見ていると、このような指摘をときどき見かけます。
 省略すると、その分、コンピュータが補ってくれるわけですが、
コンピュータ内部で補うための処理が必要になるので、その分コードの実行が遅くなるらしいです。


>If Not IsNull(txt発地都道府県) Then
>strFilter = strFilter & " AND 発地都道府県 Like '*" & txt発地都道府県.Value & "*'"
>End If
 エクセルVBAの本に書いてあったのですが、
オブジェクトの参照というのは、VBAコードの中では時間がかかる処理なのだそうです。
 だから、オブジェクトの参照というのは、回数を減らした方がいいそうです。
 これがアクセスの場合にあてはまるかどうかわからないのですが、
同じVBAなので、多分アクセスの場合にもあてはまるのだろうと思います。

 上記コードでは、「If Not IsNull(txt発地都道府県)」でtxt発地都道府県を1回参照し、
「strFilter = strFilter & " AND 発地都道府県 Like '*" & txt発地都道府県.Value & "*'"」
でtxt発地都道府県をもう1回参照し、
結局計2回txt発地都道府県を参照することになります。
 txt発地都道府県の値を変数に受けるか、又はWithステートメントを使えば、
テキストボックスを参照する回数を1回にできます。

 ただし、使う変数を増やすと、その分のメモリー領域を要することになるため、
コードが遅くなると言われています。

 ちなみに私は、無駄に多くの変数を使っています。
 その方がコード内容を読み返したときに理解しやすいし、
デバッグのときにコードが返す値を確認しやすいからです。


>If Not IsNull(txt開始日) Then
 例えば、txt開始日の値が「2015/13/32」だとしたら、どうなるか考えてみてください。

 Nullじゃないから、このIf文は通ります。
 そうすると、この値を使った条件式がstrFilterに代入されます。
 でも、この値は日付ではないので、Filterプロパティへの代入ででエラーになります。

 IsDate関数を使うと、日付として使える文字列かどうかチェックできます。
・ツリー全体表示

【12746】Re:複数条件での抽出
お礼  木葉  - 15/3/19(木) 10:02 -

引用なし
パスワード
   ひとまず完成いたしましたのでコードを載せておきます


Private Sub cmdFilter_Click()

Dim strFilter As String

If Not IsNull(cmb取引先) Then
strFilter = " AND " & "取引先コード Like '" & cmb取引先.Value & "'"
 End If

If Not IsNull(txt発地都道府県) Then
strFilter = strFilter & " AND 発地都道府県 Like '*" & txt発地都道府県.Value & "*'"
End If

If Not IsNull(txt発地) Then
strFilter = strFilter & " AND 発地 Like '*" & txt発地.Value & "*'"
End If

If Not IsNull(txt着地都道府県) Then
strFilter = strFilter & " AND 着地都道府県 Like '*" & txt着地都道府県.Value & "*'"
End If

If Not IsNull(txt着地) Then
strFilter = strFilter & " AND 着地 Like '*" & txt着地.Value & "*'"
End If

If Not IsNull(txt開始日) Then
strFilter = strFilter & " AND 日付 >= #" & txt開始日.Value & "#"
End If

If Not IsNull(txt終了日) Then
strFilter = strFilter & " AND 日付 <= #" & txt終了日.Value & "#"
End If

  Me.Filter = Mid(strFilter, 6)

    Me.FilterOn = True

End Sub

いかがでしょうか?

動作は完全に私の希望していたものでした!

もしお時間ありましたら、不備や過不足などあればご指摘いただきたいと思います。
・ツリー全体表示

【12745】Re:複数条件での抽出
発言  木葉  - 15/3/19(木) 9:54 -

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

お返事ありがとうございます。

なるほど!
ご丁寧に説明していただきありがとうございます!


最初にご回答いただいた時の質問の解説も合わせて、ありがとうございます。


全体を繋げることはできました!

>Mid関数を使用します。
いろんなサイトを見て回っていたのですが、もしかするとこれは、
Me.Filter = Mid(strFilter, 6)

でしょうか?
複数条件での抽出を解説しているサイトでは大体上の記述があったので、
「これはなんだろう?」と不思議に思っていました。

先頭にある AND を除くためでしたか
・ツリー全体表示

【12744】Re:複数条件での抽出
回答  かるびの E-MAIL  - 15/3/19(木) 0:52 -

引用なし
パスワード
   >それぞれの抽出するコード自体は書ききることができました。
>今はまだそれぞれが孤立している状態で、
>ここから条件をつなげていく方法が今ひとつわかりません…。

 各条件式をAND演算子やOR演算子でつないでいきます。
 例えば、
  氏名 Like "山田*" AND (生年月日 >= #1980/02/01# OR 体重 < 75)
です。
 こういう文字列を作り、この文字列をFilterプロパティに設定します。


 次に、このような文字列を作るVBAのコードをどうするかですが、
 No.12728の質問にあった
>>>strFilter = strFilter & " AND 発地都道府県 Like '*" & Me.txt発地都道府県 & "*'"
というコードは、重要なテクニックが使われているコードです。

 例えば、次のコードを実行したら、strFilterにはどんな文字列が格納されることになるか
イメージできますか。
   strFilter = strFilter & " AND 発地都道府県 Like '*東京*'"
   strFilter = strFilter & " AND 発地都道府県 Like '*神奈川*'"
   strFilter = strFilter & " AND 発地都道府県 Like '*静岡*'"

 答えは、
" AND 発地都道府県 Like '*東京*' AND 発地都道府県 Like '*神奈川*' AND 発地都道府県 Like '*静岡*'" 
という文字列ですね。これでは見づらいので、整形すると、
   " AND 発地都道府県 Like '*東京*'
    AND 発地都道府県 Like '*神奈川*'
    AND 発地都道府県 Like '*静岡*'" 
ですね。
 2行目と3行目にうまくAND演算子が入っています。

 つまり、
>>>strFilter = strFilter & " AND 発地都道府県 Like '*" & Me.txt発地都道府県 & "*'"
のコードは、上例の2行目と3行目にうまくAND演算子が入れるための
重要なテクニックです。


 ただ、
   " AND 発地都道府県 Like '*東京*'
    AND 発地都道府県 Like '*神奈川*'
    AND 発地都道府県 Like '*静岡*'" 
という文字列をFilterプロパティに代入すると、エラーになります。
 原因は、先頭にある「 AND 」です。
 先頭の「 AND 」だけを取り除く必要があります。

 ここも定番のテクニックがあります。
 Mid関数を使用します。
 Mid関数を使って、
   " AND 発地都道府県 Like '*東京*'
    AND 発地都道府県 Like '*神奈川*'
    AND 発地都道府県 Like '*静岡*'" 
という文字列から6字目以降を取り出します。
 そうすると、 
   "発地都道府県 Like '*東京*'
    AND 発地都道府県 Like '*神奈川*'
    AND 発地都道府県 Like '*静岡*'" 
という文字列を取得できます。
 
・ツリー全体表示

28 / 500 ページ ←次へ | 前へ→
ページ:  ┃  記事番号:
1078227
(SS)C-BOARD v3.8 is Free