Private Sub タブ1_Change()
Select Case Me.タブ1.Value 'Value=表示されいるページ番号(0から始まる)
Case 1 '2ページ目
With Me.サブフォームコントロール1
If .SourceObject = "" Then .SourceObject = "サブフォーム1"
End With
Case 2 '3ページ目
With Me.サブフォームコントロール2
If .SourceObject = "" Then .SourceObject = "サブフォーム2"
End With
Case 3
'略
End Select
End Sub
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を使わずにもっと上手い方法がないかなぁ。
最後に余談ですが、商品・サービスと顧客で申込日などが決まるテーブル、商品・サービスと顧客と年月で請求日や入金日が決まるテーブルみたいになると、どうでしょうか?
MSの公式ドキュメントだと、下記にそれらしき記述がありますね。
あと、Now() とか結果が固定されていない関数などは使えないことからも更新時に結果を保存していて、呼び出し時に再計算はしていないと推測できます。
最後のリンク先は知らなかったので非常に参考になりました。
ただ、リンク先でも言及されてますが、インデックスを設定できないので、メリットは大きく減少していると思います。
パフォーマンスアップに関してもリンク先では200万行で実験していますが、私自身はこのような大きなデータを扱うことはないので、たぶん使用することはないだろうと思います。
おお hatena 様、いらしてくれてありがとうございます。
どうもはっきりしないのですが、
https://hamachan.info/win7/access/data.html
>Access2010では、テーブルのデータ型に[集計]が追加され、テーブルに集計フィールドを作成できるようになりました。
>計算の結果は集計列に格納されます。
https://358dokari.com/access-datetype-kaisetu1#⑭_集計
>14 集計
>他の列の値を参照して式を作成し、その計算結果をテーブルに保存することができます。
それとこの英語サイトが table と query の場合でベンチマークをやって、
「結果の値を保存している」と判断しているようです。
https://codekabinett.com/rdumps.php?Lang=2&targetDoc=access-table-calculated-field-compute-quarter-date
hatena 様はどうお考えでしょうか。
「保存する」説のページのリンクをいくつか提示してもらえるとありがたいです。
すみません、自己レスです。
MS公式その他を読んでも分からなかったので質問させていただきましたが、
検索を続けると「保存する」が多数説で判明しました。
お騒がせしました。
表形式のレイアウトが適用されているか否かによるのではないかと。
レイアウトが適用されているのであれば、レイアウト内で横並びになっている
複数のテキストボックスを選択し、それらの[左スペース]プロパティの値と
[右スペース]プロパティの値の和が 0.5 cm になるよう、プロパティシートから
それぞれのプロパティの設定値を入力すればよいはず。
りんご様
前提をお話していませんでしたが、表示するだけではなく、60万件ほどの初期レコードに対し、
UI上に演算等をするコマンドボタンが10数個あり、レコードを追加、削除、演算をし、結果として、
集計結果(100万件)をクロス集計クエリを表示する仕様です。
hatena様
インデックスは早速試しました、体感レベルですが少なからずパフォーマンス改善したように思います。
SourceObjectを空にしておいて、タブの移動で計算させるというのは、パフォーマンス改善にかなり有効でした。
どうもありがとうございました。
お二人ともありがとうございます。
フィルタの方で成功しました。クエリの方もいくつかのパタンは試したのですが、ご教示いただいた内容も試してみたいと思います。
またよろしくお願いいたします。
特に問題ないと思いますが、気になるなら、仮のテーブルとクエリを作って試してみるのはどうでしょう?
全部のフィールドを選択して、プロパティシートの書式、右スペースを0.5にするとどうなります?
おおぅ、お見事です。
工夫すればいろいろ方法はあると思います。
例えば、
まずは、横1列のテキストボックスの間隔0になるようします。
現状、各テキストボックスが重なるように配置されているなら、すべてのテキストボックスを選択して、
[サイズ/間隔]-[左右の間隔を均等にする]をクリック。
間隔が空いているなら[サイズ/間隔]-[左右の間隔を狭くする]を間隔0になるまでクリック。
間隔0になったら、右端のテキストボックスを選択して、[左位置]の値を間隔×(テキストボックス数-1)分だけ増やします。
例えば、間隔5mmでテキストボックス数10なら 0.5×9=4.5cm増やします。
その後、すべてのテキストボックスを選択して、[サイズ/間隔]-[左右の間隔を均等にする]をクリックすると、5mmの間隔になります。
テキストボックスがどれだけ多くても左位置の設定は1回ですみますのでかなり楽できます。
5cmと3cmのフィールドなどバラバラのサイズで各5mm開ける、とかだと、フィールドの長さを考慮して地道に打ち込んでいくということですか?
フィールドの左端位置は数値でわかりますが、右端(終わりの場所)の情報がないようなので
やはり手動で計算していかないといけませんよね
配置しているフィールドもすべて手動で書き換える必要がありますか?
同じテーブルのデータを表示させるだけなのでフィールドはそのままでよいのでしょうか?
テーブルに適切なインデックスは設定されているでしょうか。
列見出しに設定するフィールド、抽出条件を設定するフィールド、並べ替えを設定するフィールドにインデックスを設定してみてください。
複数のテーブルを結合しているなら結合フィールドにもインデックスを設定してみてください。
フォームに関しては、デザインビューでは、タブの最初に表示されいるページのみにソースオブジェクトを設定しておいて、ページを変更したときにそのページのソースオブジェクトを設定するという方法が考えられます。
コード例
それはそうでしょう。詳しくないですが、Excel風に印刷したい時など、その場限りで使うものではないでしょうか。クロス集計結果をメイン画面に表示して普段使うならば、Excelでデータベースを組むでしょう。
時間と労力を費やしてその場凌ぎではどうにもならないと思います。個人の意見なので、解決策が他にあるかもしれませんが。
現在のフォームを作成した後、元のテーブルを編集し直したが、そのせいか?取り敢えず、もう1つテーブルもしくはクエリからフォームを作ってマクロを試してみると、どうなるでしょうか。
あと、マクロのWHERE条件式ですが、
[開くフォーム上のフィールド名]=[Forms]![フォーム名]![テキストボックス名]
というフォーマットになりますが、[F_詳細]のレコードソースに[ID]フィールドは存在してますか。
これはテキストボックス名ではないので注意してください。
バラメータのテキストボックスの標題は何が表示されてますか?
そこに表示されているフィールドまたはオブジェクトが見つからないということですので、それに間違いがないか、開いているか確認して下さい。
それ以外の原因はないです。
>りんごさん
ありがとうございます。再度確認しましたが、テキストボックスの名前は間違いありませんでした。
以前にテーブルでIDフィールドを作成し直していますが、その影響はありますでしょうか。両フォームでのテキストボックスのコントロールソースに間違はないです。
当て推量ですが、打ち間違い、もしくは、もともと存在したけど名前が変わってしまったのではないでしょうか?例えば、見た目は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がついてしまうけど日付をもたせるのと同じことなので
データベース的には問題ないですか?
レポート表示では重複を非表示、で対応します