SELECT
MT_test.[クラス], MT_test.点数
FROM
MT_test INNER JOIN
(SELECT [クラス]
FROM MT_test
WHERE 点数=100
GROUP BY [クラス]
HAVING Count(点数)=1
) AS Q1
ON MT_test.[クラス] = Q1.[クラス];
Private Sub cmdFilter_Click()
Dim strFilter As String
If Not IsNull(Me.申込開始日検索) And Not IsDate(Me.申込開始日検索) Then
MsgBox "日付ではありません。"
Me.申込開始日検索.SetFocus
Exit Sub
End If
If Not IsNull(Me.申込終了日検索) And Not IsDate(Me.申込終了日検索) Then
MsgBox "日付ではありません。"
Me.申込終了日検索.SetFocus
Exit Sub
End If
If Not IsNull(Me.入金開始日検索) And Not IsDate(Me.入金開始日検索) Then
MsgBox "日付ではありません。"
Me.申込開始日検索.SetFocus
Exit Sub
End If
If Not IsNull(Me.入金終了日検索) And Not IsDate(Me.入金終了日検索) Then
MsgBox "日付ではありません。"
Me.申込終了日検索.SetFocus
Exit Sub
End If
If Not IsNull(Me.申込開始日検索) Then
strFilter = strFilter & " AND 申込日 >= #" & Me.申込開始日検索 & "#"
End If
If Not IsNull(Me.申込終了日検索) Then
strFilter = strFilter & " AND 申込日 <= #" & Me.申込終了日検索 & "#"
End If
If Not IsNull(Me.入金開始日検索) Then
strFilter = strFilter & " AND 申込日 >= #" & Me.入金開始日検索 & "#"
End If
If Not IsNull(Me.入金終了日検索) Then
strFilter = strFilter & " AND 申込日 <= #" & Me.入金込終了日検索 & "#"
End If
If Not IsNull(Me.使途検索) Then
strFilter = strFilter & " AND 使途='" & Me.使途検索 & "'"
End If
Me.Filter = Mid(strFilter, 6)
If strFilter = "" Then
Me.FilterOn = False
Else
Me.FilterOn = True
End If
End Sub
入金日が確定していない場合、どうしますか?
入金日の抽出条件を入金開始日から入金終了日またはIs Nullとすると、入金日未確定のレコードを絞り込めなくなります。申込日で絞り込んでも、またはIs Nullだから復活、困りますね。これをクエリ1とします。
最終的に、クエリ1をもとにクエリ2を作って、申込日で絞り込むようにしました。これもセオリーがあれば、誰か教えて下さい。
入金日未確定を含めない、入金び日未確定を含める、入金日未確定のみと、切り替えるにはどうすればいいか?
まだ途中ですが、確定を1、未確定を2として、Switch(ほにゃらら,1) Or Switch(ほにゃらら,2) Or (Switch(ほにゃらら,1) Or Switch(ほにゃらら,2))みたいな事をやってみました。Switchを使わずにもっと上手い方法がないかなぁ。
最後に余談ですが、商品・サービスと顧客で申込日などが決まるテーブル、商品・サービスと顧客と年月で請求日や入金日が決まるテーブルみたいになると、どうでしょうか?
Private Sub Form_BeforeInsert(Cancel As Integer)
Dim num As Long
num = DLookup("連番","テーブル","ID=" & DMax("ID","テーブル"))+1
If num >= 44 Then num = 1
Me.連番 = Num
End Sub
当て推量ですが、打ち間違い、もしくは、もともと存在したけど名前が変わってしまったのではないでしょうか?例えば、見た目はIDと表示されているけど、テキストボックスの名前をプロパティシートで確認すると、IDD、みたいな。
入力支援機能を活用すると良いですよね。[Forms]![F_一覧]まで入力、次に!を押すと候補が表示されると思います。
ご丁寧にありがとうございました。
最初の方法でやります。スキルがないので。
フォームの場合、フィールド数100程度であれば、プロパティシートの数値を手作業で調整入力します。フィールド数1000程度になると、サイズと位置をVBAで調整入力したいと思います。以上、個人的な意見です。時間と労力に見合う方法を選べばいいんじゃない。
7mm、8mmくらいでしたら、配置タブのサイズ/間隔から広めを選んで出来そうです。
レポートの場合、詳しくないので他の方に聞いて下さい。
無理して一気にやろうとせずに、やりたいことを分解して、1つずつ実現するようにすればどうでしょう。
ということなので、まずは、グループ毎の100点の人数を取得するクエリを考えます。
下記のような集計クエリで取得できます。
結果は下記です。
このカウントが1のレコードを抽出したいのですから、カウントの抽出条件を1に設定します。
このクエリのSQL
このクエリ(Q_100_1)とMT_testを結合すればご希望の結果になります。
クエリを一つに纏めたいなら、それぞれのSQLをサブクエリを使ってまとめて、整理すると下記のようなSQLになります。
そのフォームにコマンドボタンを配置して、そのクリック時でレポートを開くようにして、引数で条件を設定するといいでしょう。
例えば、日付を条件に抽出するなら、
DoCmd.OpenReport メソッド (Access) | Microsoft Docs
当て推量ですが、レポートのレコードソースをテーブルからクエリに変更して、もう一度整えるのはどうでしょう。
コード例
入金日が確定していない場合、どうしますか?
入金日の抽出条件を入金開始日から入金終了日またはIs Nullとすると、入金日未確定のレコードを絞り込めなくなります。申込日で絞り込んでも、またはIs Nullだから復活、困りますね。これをクエリ1とします。
最終的に、クエリ1をもとにクエリ2を作って、申込日で絞り込むようにしました。これもセオリーがあれば、誰か教えて下さい。
入金日未確定を含めない、入金び日未確定を含める、入金日未確定のみと、切り替えるにはどうすればいいか?
まだ途中ですが、確定を1、未確定を2として、Switch(ほにゃらら,1) Or Switch(ほにゃらら,2) Or (Switch(ほにゃらら,1) Or Switch(ほにゃらら,2))みたいな事をやってみました。Switchを使わずにもっと上手い方法がないかなぁ。
最後に余談ですが、商品・サービスと顧客で申込日などが決まるテーブル、商品・サービスと顧客と年月で請求日や入金日が決まるテーブルみたいになると、どうでしょうか?
フィルターは使った事がないので、選択クエリでやってみます。
日付の抽出条件をBetween [Forms]![フォーム名]![申込開始日検索テキストボックス] And [Forms]![フォーム名]![申込終了日検索テキストボックス]とします。
抽出条件の範囲指定をNz([Forms]![フォーム名]![申込開始日検索テキストボックス],100/01/01)、Nz([Forms]![フォーム名]![申込終了日検索テキストボックス],9999/12/31)と変更します。
ここはセオリーがわからないので、アドバイスがあればどなたかお願いします。
選択クエリからフォームを作成し、検索テキストボックスを配置、更新後VBA処理にフォームの再クエリ、こんな感じでどうでしょうか?
とりあえず下記を参考にチャレンジしてみては。
複数条件の抽出フォームの設計 その1 - hatena chips
データベースがやりたいわけじゃない、自動入力がやりたい、レポートを印刷したいという事でしたら、Excelで自動入力する方法、ワードにインポートする方法を検討してみるのはどうでしょうか?
データベースがやりたいという事でしたら、複合主キーや複数テーブルを頑張るしかないですね。
日付テーブルは作らずに始めてもいいんじゃない。点呼記録テーブルは、日付と従業員の複合主キーを設定する感じでしょう。
いずれにしてもIDでの主キーはつくらずに日付でやっても問題ないということになりますか?
正規化という考え方が参考になります
データベース的な視点で言えば破綻はしていないので運用自体は可能でしょう
データベースとしてのメリットを得られないというだけですね
これは別な話ですね。特に関係はないです
『日付が決まると何かが決まった』、『Xが決まるとYが決まった』、これを探してテーブルを作りました。重複データ云々だからどうすることはなくなります。
日付テーブルは作らずに、点呼記録テーブル『日付と従業員が決まると、諸々決まる』とする場合、今日のAさんは法定速度遵守、今日のBさんは車間距離保持、これが可能になります。みんなの注意事項を揃えるには、何か工夫が必要になるでしょう。
日付テーブルを作らなくても、データベースだからインポート振り分けは避けられないと思います。従業員テーブルに登録して、点呼記録テーブルに登録するように。インポートしたテーブル1つだけでは、データベースになりませんよね。
日付テーブルをつくる目的は重複データをつくらないことでしょうか?
1対多にインポートすると、日付テーブル、点呼記録テーブル、インポートして日付でリレーションするならどちらにも日付が残ることになりますよね?
それだったら日付テーブルをなくして、点呼記録テーブルだけでも問題ないのではないか、と思ってしまいました
(インポートのときにそれぞれのテーブルに振り分ける必要があり、複雑になりそうなので)
もし僕の理解が間違っていたらすみません
ありがとうございます。しばらくアクセスを離れていたのですっかり忘れていました。おかげさまで思い出しました。
連結コントロールの「初期値」は新規レコードでの入力前の値を設定するものですが、新規レコードで確認してますか。
こういう事でしょうか?
新しい選択肢をテキストボックス①に入力したら、ボタンを押して追加クエリ①『T_分類①にテキストボックスの入力内容を追加するクエリ』。ここから始めて試行錯誤するのは、どうでしょうか?
途中送信してしまいました
日付でリレーションする場合、日付テーブルと点呼記録テーブル双方に日付というフィールドができるということになりますか?
それですと日付テーブル自体をなくし、点呼記録テーブルのみで
hatenaさんのコードで運用すると
すべての点呼記録テーブルに指示事項IDがついてしまうけど日付をもたせるのと同じことなので
データベース的には問題ないですか?
レポート表示では重複を非表示、で対応します
EXCEL上では1対多というか
日付 氏名 開始時間 車両番号 指示事項
のような並びで1行1件で日付や指示事項は重複して入っています
ACCESSにインポートする仕組みができたらEXCEL上では指示事項の入力はせずに
インポートしたときに付与させる方向で考えています
日付でリレーションする場合、日付テーブルと点呼記録テーブル双方に日付というフィールドができるということになりますか?
それですと日付テーブル自体をなくし、点呼記録テーブルのみで
hatena
ということは、EXCEL上のデータでいわゆる1対多の状態になっているということですね
ならば単純に「1」側のデータ(「日付」と「注意事項のID」)をインポートしてから「多」側のデータ(「注意事項のID」を除いたそのほかすべて)をインポートすればいいです
DB設計におけるナチュラルキーとサロゲートキーという考え方の話になるんですがわざわざキーを作らなくても
日付テーブルの「日付」と点呼記録テーブルの「日付」でリレーションを組めばいいですよ
ありがとうございます
また説明不足があって恐縮なのですが、EXCELのデータにはすべての行(点呼記録レコード)に注意事項のIDが入力されています(VLOOKUPでマスタから文字列を表示させています)
ACCESSでインポートすることになったならEXCELでは注意事項自体を入力しません(本当はだめだけど書類上出来上がってればいいので、実際に注意事項などを意識していないため)
はじめからACCESSで入力すればいいじゃないか、と思われると思いますが、
数日間の平均値、週間、月間などの総計、前回からの空き時間などの計算やそれに伴う調整が必要で、その計算をACCESSですべてやるのは大変そうでした。(日をまたいだときや空き時間が短いと前日の労働時間として合算しないといけなかったりするので)EXCELだとオートフィルもあるしもろもろ手軽にできます
ですから最終的にACCESSに入れて管理する、という運用にしたいです
点呼記録テーブルと日付テーブルはそれぞれIDでリレーションするのだと思いますが
それぞれにインポートしてIDはどのようにあわせるのでしょうか?
点呼記録テーブルと日付テーブルの2つのテーブルへインポートするとして、
点呼記録テーブルへのインポートはそのままデータ形式を合わせてインポートすればいいです(不要な行はデータ形式不一致でエラーになって取り込まれないので)
日付テーブルへのインポートはそのままだと注意事項の行に日付がないので注意事項の行に日付をつける作業が必要です
最近似たような話題がありましたAccess2019のアクションカタログを利用して、空白セルに前行の値をコピーしたい
ACCESSの機能でやるなら取り込める形式の仮テーブルを作って取り込んだ後注意事項の行に日付をつけて、注意事項の行だけ抽出して本番テーブル(日付テーブル)へ追加とすればいいです
VBAでやるなら、1行ずつチェックしながら日付があれば日付を変数に確保、注意事項が出てきたら日付テーブルへ追加とすればいいですね
(どうせ全データチェックすることになるので点呼記録テーブルへのインポート作業も組み込んでしまえばいいと思います)
1対多の状態でインポート
リレーションシップで参照整合性をつけているなら日付データがないと点呼記録が入力できないので日付テーブルへのインポートの後、点呼記録テーブルへのインポートという順番でインポートします
VBAで全部やるなら注意事項は各日付の後に出てくるので最後の行からチェックする(先に注意事項の行が見つけられる)ように取り込めばいいです
1対多の状態のデータをそのまま取込ということは普通やりません
日付別注意事項テーブルは、日付が決まると注意事項が決まった、ただそれだけです。レコード数がある条件で少なくなるとか意図していません。
「11/11,法定速度遵守,11/11,車間距離保持」のように複数選べる場合、日付が決まると注意事項が決まった、とはなりません。さらに、「11/11,新人,法定速度遵守,11/11,ベテラン,車間距離保持」のようになる場合、日付と従業員のグループが決まると注意事項が決まった、こんなテーブルも必要になるでしょう。
ちゃんとやった事がないのであれですが、みんなインポートの前か後にデータを整えているんじゃないでしょうか?加工して1側のテーブルに追加クエリ、加工して多側のテーブルに追加クエリみたいな感じで。
詳しい解説ありがとうございました
日付テーブルに分けた方が前回の注意事項IDをみるときに格段に少なくなるし
データベース設計的にも正しいということですね
(別途質問をしようと思いましたが関連ですのでこちらでさせていただきます)
そのようにしようと思いましたが一部の出勤データがEXCELからのインポートでした
一行に、(画像のように)ACCESSのレポートに表示する状態で入力されています
この場合、1対多の状態でインポートするには難しい処理が必要となりそうですが
どのようにしたらよいでしょうか?
訂正。組み合わせて追加クエリの従業員ID:1,1,1,2,2,2…
日付テーブル
日付クエリ(日付:降順、トップ1を表示;デザインタブのクエリ設定『すべて』を『1』に変更。)
↓
追加クエリに変更。(レコードの追加:式1が日付、式2が注意事項ID。)
選択クエリに注意事項IDを加える。
DLookupはたしかに重いですが、今回は、おそらく、新規レコードが作成されるときに取得すればいいだけですので、その時に一回呼び出されるだけですよね。どんなに件数が多かろうと1秒もかかりません。たぶんユーザーから見れば一瞬です。
DLookupやDCountは重いから避けるべきというのは、クエリの演算フィールドに使う場合です。
レコード件数分、繰り返し呼び出されるので、重くなる場合があります。
画像について
フォームではそのような表示は不可能なので、レポートでの話ですね。
そのようなレイアウトにするなら、日付テーブル(あるいは営業日テーブル)を用意して、そこに注意事項のIDを格納するようにすればいいかと思います。
フォームでの入力は、メインフォームのソースを日付テーブル、サブフォームのソースに画像のデータのテーブルを設定すればいいでしょう。
メインフォームに前回の回答のVBAを設定すればいいでしょう。
あるいは、事前に日付テーブルにまとめて(1ヶ月分ずつとか)日付、注意事項ID(連番)をVBAで追加するような運用でもいいでしょう。その場合、DLookupを使わずに、前のレコードの連番に1加算していけばいいだけです。
>りんごさん
DLookupは激重だと聞きますが、昔のイメージが強いだけで、最近のPCかつインデックス設定をすれば常用して問題ないということですか?
説明不足で誤解を招いてしまってすみません
文章ではむずかしいので画像にしてみました
vb.net自体に価値があっていずれ覚える必要があるなら頑張ってくださいですが、デスクトップのアイコンが問題なだけならショートカットを作ってアイコンを変更する(VBS(インストーラもどき)をつくる)とか、VBSをEXE化してリソースを弄ってアイコンを設定するとか別な方法もありそうです
お久しぶりです。
かなり期間が空いてしまいましたが、
バックグラウンドプロセスが残らなくなりましたので、お知らせ致します。
結果としてはaccessの問題ではなく、社内のネットワークが原因だったようです。
新しいネットワークに変更になった途端にバックグラウンドプロセスが全く出なくなりました。
大変お騒がせしました…。
ただし結局起動用のaccessをvb.netにて新たに作成指示があり、現在格闘中です(アイコンが全て同じな為、間違った操作をしている方が複数いるそうです)
色々ご対応下さり、ありがとうございました。
これに関しては、最初の質問と矛盾しています。上の回答は最初の質問に沿った回答です。
上の回答ではまずいのなら、現状の関連するテーブル構成を提示して、そのテーブル名を使って、具体的にどのような処理をしたいのか説明してください。
少なくとも、社員マスター、指示事項マスター、連番のあるテーブルの3つのテーブルが関連するはずです。
新規レコードを入力したときという意味なら、フォームの挿入前処理のイベントプロシージャで連番フィールドに入力すればいいでしょう。
IDフィールド順で連番をふるのなら、IDが最大のレコードの連番を取得して、それに+1したものでいいですね。44だったら1にする。
IDフィールドにインデックスを設定しておけば、レコード件数が多くて遅いということはないはずです。
改定がわかる何かを用意して、複合主キーにすると変化に対応出来るかもしれません。
もしかして、アルコール検知器使用の有無、体調確認のチェックなどの定期点検項目の話だったのでしょうか?データの登録は、地道にやるのがセオリーだと思います。例えば、見出し『項目1、酒気帯びの有無』を選んで、明細『Aさん、無、Bさん、無…』を登録したら、見出し『項目2、日常点検状況』を選んで、明細『Aさん、レ、Bさん、レ、…』みたいに。
>hatenaさん
レコードを作成したときに自動で作成したいです
必ずしもレコードに保存しなくても、計算で同じ指示事項が表示されるのでしょうけど
いちおうレコードに保持する方向で考えています(印刷や再発行したときにずれていると信憑性を疑われそうなので)
IDは連番ですが、一日に複数人おり、会社としての指示事項になるので全員同じものにする必要があります(これを書き忘れていてすみません)
なのでIDでやると不都合がありそうです
ID.Value Mod 44 は、レコード作成時にVBAで計算してフィールドに格納するかんじですか?
>りんごさん
価格改定への対処のように策定日をつくる、とかですかね
基本的には自社でやっていることでも、本当に指示したくてやっているわけでもなく
お役所仕事のルールを守るため、なので変更はないとは思ってます
あっても推奨する指示項目の追加だと思います
例えば飲酒運転関連はあとから増えたものかもしれませんが、安全運転するための項目がすでに40以上あるので
さすがにこれ以上は監査する機関も思いつかないかな、と
お遊びをやってみました。
例えば、目標が1、2、3の3つある。ある日、Aさん、Bさん、Cさんの目標がそれぞれ1、2、3だった場合、どうするか。
まず、演算フィールドを作ってみた。式1:IIf(目標=3ならば、1、目標+1)。演算すると、2、3、1。
そして とある日、Aさん、Bさん、Cさんの目標として追加クエリする。
現実では、こんなに単純にはできないでしょう。上限が永遠に変わらないなんて事はあってはならないし、中身も時代に合わせて変わらなければいけないはずなので。例えば、目標1『AAA』が明日『???』に変わったらどうする?昨日までの目標1『AAA』はどうなる?昔から『???』だった事にする?急に廃止になったら、連番や上限どうする?
「指示事項」が格納されたマスターテーブルがあり、そこに44件のレコードが登録されており、それを表示したいということが目的ですか。
レコードを作成したときに、指示事項マスターから引っ張ってきて表示するのでしょうか。その時、表示したものは、その後もレコードに保持しておくものですか(後からそのレコードを表示したときでも変わらない)。
ID が連番になっているなら、
ID.Value Mod 44
で余りを計算してそれを使えばいいかと思います。うまくいきました!
ありがとうございました。