アプリ版:「スタンプのみでお礼する」機能のリリースについて

「作表条件」というフォームにテキストボックスとして「日付1」、「日付2」を設置しています。
元のテーブルには「日付」という項目があり、「日付1」から「日付2」までのデータを抽出するため、
クエリの条件式に

Between Nz([Forms]![作表条件]![日付1],#1800/01/01#) And Nz([Forms]![作表条件]![日付2],#9999/12/31#)

と記述しています。

ただ、元のテーブルの日付がNULL値の場合があり、その場合「日付1」および「日付2」が空欄だとNULL値のレコードが抽出されません。

「日付」がNULLの場合でも抽出できるようにするには、どのようにすればよいでしょうか?

どなたか教えてください。

A 回答 (7件)

No.5です。



> 少なくとも一方が空白以外なら指定範囲のものを抽出
> 双方が空白なら『日付』がNullを含むすべてのものを抽出

了解しました。
とりあえず、フォームのヘッダ(またはフッタ)に『日付1』『日付2』の
テキストボックス、及び、抽出を実行させるための『実行』コマンド
ボタンが設置されている場合は以下のようになります。

'『実行』コマンドボタンのクリック時イベント
Private Sub 実行_Click()
On Error Goto エラー処理

  '日付1・日付2の評価結果などを記録するための変数を用意
  Dim sDate1 As String, sDate2 As String, sRS As String
  'レコードソースに使用するテーブル/クエリの名前を定数として用意
  Const conTableName As String = "テーブル1"
  Const conQueryName As String = "クエリ1"

  '日付1・日付2の入力状況を確認
  '(後で使用するLen関数は、引数がNullだと演算結果も0では
  ' なくNullになってしまうため、Nullを予め空文字に変換)
  sDate1 = Nz(Me!日付1, "")
  sDate2 = Nz(Me!日付2, "")

  '入力状況で場合分け
  Select Case True
    Case Len(sDate1), Len(sDate2)
      '少なくとも一方が空白以外
      '(Len関数の結果が0以外なら、Trueとみなされます)
      sRS = conQueryName
    Case Else
      '双方が空白の場合
      sRS = conTableName
  End Select

  'レコードソースを切替
  Me.RecordSource = sRS

終了処理:
  Exit Sub

エラー処理:
  'エラー発生時は、エラー内容を表示の上、処理を中止
  MsgBox Err.Number & ":" & Err.Description, , Me.Name & " 実行"
  Resume 終了処理

End Sub


・・・以上です。

なお、変数や定数を設置せず、いっぺんに処理を行ってしまうなら、
以下のようにも書けます(更にエラー処理も省略)。
『日付1』の値などを繰り返し使う場合(→例えばクエリを用意する
代わりに、VBAでレコードソースに直接SQL文を適用する、等)は
上記のようにした方が効率的ですが、今回はこちらでもOkかと・・・
※こちらではLen関数を使用せず、「&」での結果が「""」(空文字)
  かどうかで判定しているため、テーブル/クエリの出てくる順序が
 逆になっているので注意してください(汗)

Private Sub 実行_Click()

  If (Me!日付1 & Me!日付2 & "") = "" Then
    '双方が空白
    '※最後の「 & ""」がないと、「""」ではなくNullになり、
    '  正しく判断されなくなるので注意
    Me.RecordSource = "テーブル1"
  Else
    '少なくとも一方が空白以外
    Me.RecordSource = "クエリ1"
  End Select

End Sub
    • good
    • 0
この回答へのお礼

詳しくご説明いただきありがとうございます。

早速参考にさせてもらいます。

お礼日時:2010/12/16 15:18

片方に値がないかもしれない、ことより、必ず2つの日付に値があるとき検索、と考える方がはっきりします。




自=値あり、至=値あり
自=値あり、至=値なし
自=値なし、至=値あり
自=値なし、至=値なし
片方に値なし、はある方の値代入でよい。
2~4は問題なく検索
2~は2~2と同意、
~4は4~4と同意、
双方無しは警告。

至は自があってこその値入力とすべき。

今回は、入力チェックでの対応と思います。
    • good
    • 0

>「日付1」および「日付2」が空欄だとNULL値のレコードが


> 抽出されません。

ご希望の動作は、テキストボックスが
  少なくとも一方が空白以外なら指定範囲のものを抽出
  双方が空白なら『日付』がNullのものを抽出
ということでよろしいでしょうか。

上記推測でよろしければ、以下の方法でできます。
(方法1はクエリのみの対応で済むが抽出速度が鈍化、
 方法2は抽出が比較的早いがマクロ又はVBAが必要)


【方法1】クエリにOr条件を追加する

1)当該クエリをデザインビューで開く
2)空白になっている『フィールド』欄に、以下の式を入力
 IsNull([Forms]![作表条件]![日付1] & [Forms]![作表条件]![日付2])
 ※入力を終了すると、先頭に「式1: 」が追加されます。
3)今追加した列の『表示』チェックボックスをオフに設定
4)『日付』フィールドに指定している「Between Nz(~)」の
 すぐ下の枠に「Is Null」を入力
5)「2」で追加した列の、「Between Nz(~)」と同じ行に
 「False」を入力
6)同じく列の、「Is Null」を入力したのと同じ行に「True」を
 入力
7)クエリを保存して閉じる


【方法2】フォームのレコードソースを差し替える
現在作成済みのクエリの他に、新たに、『日付』フィールド
の抽出条件に「Is Null」を指定したクエリを作成しておいて
下さい。
これを、マクロ又はVBAで、フォームのレコードソースとして
使用します。
※マクロなら『値の代入』アクションで、『式』にクエリ名を、
 『アイテム』に「[Forms]![作表条件].[RecordSource]」を
 指定します。
 VBAで、当該フォームへの記述なら、「Me.RecordSource」
 でもOkです。
 (これについては、必要なようでしたら補足説明します:
  その際はマクロ/VBAどちらを使用しているかお報せ下さい)


・・・以上です。
「クエリーの抽出条件について」の回答画像5
    • good
    • 0
この回答へのお礼

具体的なご返答誠にありがとうございます。

希望の動作は
  少なくとも一方が空白以外なら指定範囲のものを抽出
  双方が空白なら『日付』がNullを含むすべてのものを抽出

ということです。

説明不足ですいません。

結局、良く考えたら日付は必要なので、必須入力項目にしてNULL値を許さない方向で考えたいと思います。

ただ、参考のために、よろしければVBAを使った方法についてもう少し詳しく補足いただけませんでしょうか?

お礼日時:2010/12/13 16:33

#2です。


UNIONを使えばと書きましたが、確かにNo3の方のように段階を踏むというやりかたでも良いと思います。
あまりデータベースの扱いになれていないのであればNo3の方のやり方の方が視覚的にわかりやすいでしょう。

Accessですので、クエリを組み合わせて実現することも可能です。

つまり、

(1)NULLの物だけを集めたクエリ
(2)日付範囲を集めたクエリ
(3)(1)と(2)をくっつけるクエリ
フォームは(3)を参照

というやり方もあります。No3の方の考え方だと

(1)NULLの物だけを集め、テーブルにINSERT(UPDATE)するクエリ
(2)日付範囲を集め、テーブルにINSERT(UPDATE)するクエリ
で、フォームはクエリではなくテーブルのフィールドを参照。

という感じになりますかね。


蛇足ではありますが。

Accessは正直言って、一部、特殊なSQL記法を使うので、
Accessのやり方はOravleやPostgreSQLなどを扱う際に使えない事があるので。
もしAccess以外のDBを使うことになったら注意してください。

この辺はAccessがプログラム開発とデータベースをごちゃ混ぜにした形で、
そこを利便化させるために独自の手法を取る事ができるので。

Accessではクエリ等から簡単にフォームのフィールドに連携」させられますが、
一般的なDBではDBとプログラムは切り離されているので、
その辺の処理を作りこんだりしないといけません。

その反面、プログラムとDBの組み合わせの自由度が高いです。
また、Accessはセキュリティ面や、データロックといったような多重アクセス制御、
バックアップ等のデータ保守というのが非常に苦手なので、
重要性を伴うアプリケーション開発や、
多人数が扱うシステムには通常Accessは使いません。

Accessを使うにしても上記のOracle等を組み合わせて使います。
(AccessのテーブルやSQLを一時的なものとして使う)

ご参考まで。
    • good
    • 0
この回答へのお礼

いろいろとご指南ありがとうございます。

SQLやORACLEもそのうち使えるようになりたいものです。

お礼日時:2010/12/13 16:23

いったんテーブルに出力して、追加します。

2段階操作。でも可能です。


ユニオンクエリは結果がどうなるかほかより見えにくいかと思います。条件間違うと膨大です。使えば便利ですが。

ユニオンクエリの使い方が理解できてない、馴れない最初なら、手順面倒でもクエリデザインで確認しながら順次結果を出すのもいいでしょう。
たまたまうまくいった、で終わらせるのは良くないですから。
    • good
    • 0
この回答へのお礼

度々のご返答ありがとうございます。

参考にさせていただきます。

お礼日時:2010/12/13 16:21

No1の方が書かれているように、


NULLのデータと、範囲指定のデータをUNIONでくっつける形になると思います。
BETWEENはあくまで範囲指定ですので値でも何でもないNULLは拾えません。

また、「空白」と「NULL」はまったく別物です。
(空白は本当に長さ0の値ですが、NULLは何の値が入っているか分からない。(NULLという何らかのデータ))
開発環境等によっては、一緒くたに判定してくれる場合もありますが。
別物として扱うクセをつけましょう。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

UNIONですかー。
ちょっと敷居が高いので今までやった事ありませんでした。
チャレンジしてみます。

また、恥ずかしながら「空白」=「NULL」と理解していました。
ご指摘ありがとうございます。

お礼日時:2010/12/10 14:51

「日付」が


NULLで抽出したもの

NULL以外でー、BETWEEN使って抽出したもの

これらが合わさればいいのでは?、どうですか?。

NULLの分までBETWEEN使ってなんとか抽出しようとしてますか。
    • good
    • 0
この回答へのお礼

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

NULLの分までBETWEENで抽出しようとはしていませんが、どうしたらいいのかわからず困っていました。

お礼日時:2010/12/10 14:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!