Microsoft Access 掲示板

上限ありの連番フィールドをつくりループさせるには

24 コメント
views
4 フォロー

IDを元に直前のレコードを参照して元レコードの連番フィールドに+1(連番に上限をつけて上限になると1に戻す仕組みにする)するというような仕組みやDLookUpを使うと
全レコードを対象に検索がされるのでどんどん重くなっていきますか?

具体的にやりたいことは、運送業で点呼記録簿を作成する必要があり
毎日、違った”指示事項”というものを記載しなければなりません
推奨されているものが44項目ほどあり、それをレコードを作成するたびに順繰り表示させたいです
44項目ある必要はないので日付に連動させて表示させるのが軽くて手間もかからないのでしょうか?
いずれにせよ、テーブルに格納するわけではなく、テキストボックスを表示させて都度計算させたほうがよいのでしょうか?
レポートで表示させるときは、10人以下でせいぜい一年分です

EXCELではIF文で上のセルをみて項目セルが44になっていなければ+1して、VLOOKUPでマスタから
文字列を取り出しています

みづ
作成: 2021/11/04 (木) 17:25:08
通報 ...
1

「指示事項」が格納されたマスターテーブルがあり、そこに44件のレコードが登録されており、それを表示したいということが目的ですか。
レコードを作成したときに、指示事項マスターから引っ張ってきて表示するのでしょうか。その時、表示したものは、その後もレコードに保持しておくものですか(後からそのレコードを表示したときでも変わらない)。

ID が連番になっているなら、ID.Value Mod 44 で余りを計算してそれを使えばいいかと思います。

2
りんご 2021/11/05 (金) 01:23:03 c564b@0e907

上限ありの連番フィールドをつくりループさせるには

 お遊びをやってみました。
 例えば、目標が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』はどうなる?昔から『???』だった事にする?急に廃止になったら、連番や上限どうする?

3
みづ 2021/11/05 (金) 15:42:04 58219@732d2

>hatenaさん
レコードを作成したときに自動で作成したいです
必ずしもレコードに保存しなくても、計算で同じ指示事項が表示されるのでしょうけど
いちおうレコードに保持する方向で考えています(印刷や再発行したときにずれていると信憑性を疑われそうなので)
IDは連番ですが、一日に複数人おり、会社としての指示事項になるので全員同じものにする必要があります(これを書き忘れていてすみません)
なのでIDでやると不都合がありそうです
ID.Value Mod 44 は、レコード作成時にVBAで計算してフィールドに格納するかんじですか?

>りんごさん
価格改定への対処のように策定日をつくる、とかですかね
基本的には自社でやっていることでも、本当に指示したくてやっているわけでもなく
お役所仕事のルールを守るため、なので変更はないとは思ってます
あっても推奨する指示項目の追加だと思います
例えば飲酒運転関連はあとから増えたものかもしれませんが、安全運転するための項目がすでに40以上あるので
さすがにこれ以上は監査する機関も思いつかないかな、と

4
りんご 2021/11/05 (金) 19:58:09 c564b@0e907 >> 3

価格改定への対処のように策定日をつくる、とかですかね

 改定がわかる何かを用意して、複合主キーにすると変化に対応出来るかもしれません。

変更はないとは思ってます。あっても推奨する指示項目の追加だと思います。

 もしかして、アルコール検知器使用の有無、体調確認のチェックなどの定期点検項目の話だったのでしょうか?データの登録は、地道にやるのがセオリーだと思います。例えば、見出し『項目1、酒気帯びの有無』を選んで、明細『Aさん、無、Bさん、無…』を登録したら、見出し『項目2、日常点検状況』を選んで、明細『Aさん、レ、Bさん、レ、…』みたいに。

5

 上限ありの連番フィールドをつ...
 テーブル  レポート
IDを元に直前のレコードを参照して元レコードの連番フィールドに+1(連番に上限をつけて上限になると1に戻す仕組みにする)するというような仕組みやDLookUpを使うと
全レコードを対象に検索がされるのでどんどん重くなっていきますか?

レコードを作成したときに自動で作成したいです
必ずしもレコードに保存しなくても、計算で同じ指示事項が表示されるのでしょうけど
いちおうレコードに保持する方向で考えています(印刷や再発行したときにずれていると信憑性を疑われそうなので)

新規レコードを入力したときという意味なら、フォームの挿入前処理のイベントプロシージャで連番フィールドに入力すればいいでしょう。
IDフィールド順で連番をふるのなら、IDが最大のレコードの連番を取得して、それに+1したものでいいですね。44だったら1にする。

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フィールドにインデックスを設定しておけば、レコード件数が多くて遅いということはないはずです。

6
hatena 2021/11/06 (土) 03:24:08 修正 >> 5

IDは連番ですが、一日に複数人おり、会社としての指示事項になるので全員同じものにする必要があります(これを書き忘れていてすみません)
なのでIDでやると不都合がありそうです

これに関しては、最初の質問と矛盾しています。上の回答は最初の質問に沿った回答です。

上の回答ではまずいのなら、現状の関連するテーブル構成を提示して、そのテーブル名を使って、具体的にどのような処理をしたいのか説明してください。

少なくとも、社員マスター、指示事項マスター、連番のあるテーブルの3つのテーブルが関連するはずです。

7
みづ 2021/11/08 (月) 16:41:59 58219@732d2

>りんごさん
DLookupは激重だと聞きますが、昔のイメージが強いだけで、最近のPCかつインデックス設定をすれば常用して問題ないということですか?画像1

説明不足で誤解を招いてしまってすみません
文章ではむずかしいので画像にしてみました

8

DLookupは激重だと聞きますが、昔のイメージが強いだけで、最近のPCかつインデックス設定をすれば常用して問題ないということですか?

DLookupはたしかに重いですが、今回は、おそらく、新規レコードが作成されるときに取得すればいいだけですので、その時に一回呼び出されるだけですよね。どんなに件数が多かろうと1秒もかかりません。たぶんユーザーから見れば一瞬です。

DLookupやDCountは重いから避けるべきというのは、クエリの演算フィールドに使う場合です。
レコード件数分、繰り返し呼び出されるので、重くなる場合があります。

画像について

フォームではそのような表示は不可能なので、レポートでの話ですね。
そのようなレイアウトにするなら、日付テーブル(あるいは営業日テーブル)を用意して、そこに注意事項のIDを格納するようにすればいいかと思います。

フォームでの入力は、メインフォームのソースを日付テーブル、サブフォームのソースに画像のデータのテーブルを設定すればいいでしょう。
メインフォームに前回の回答のVBAを設定すればいいでしょう。

あるいは、事前に日付テーブルにまとめて(1ヶ月分ずつとか)日付、注意事項ID(連番)をVBAで追加するような運用でもいいでしょう。その場合、DLookupを使わずに、前のレコードの連番に1加算していけばいいだけです。

9
りんご 2021/11/09 (火) 06:05:20 c564b@0e907
日付注意事項ID
2021/11/543
2021/11/844

日付テーブル

日付注意事項ID式1:Date()式2:IIf([注意事項ID]=44,1,[注意事項ID]+1)
2021/11/8442021/11/91

日付クエリ(日付:降順、トップ1を表示;デザインタブのクエリ設定『すべて』を『1』に変更。)

追加クエリに変更。(レコードの追加:式1が日付、式2が注意事項ID。)

日付従業員ID
2021/11/8
2021/11/91
2021/11/92
2021/11/95
出勤者を登録。
点呼項目ID項目評価
1
1
1未評価
2
2×
2未評価
3
点呼明細テーブル
日付従業員ID点呼項目ID項目評価
2021/11/911未評価
2021/11/912未評価
2021/11/913未評価
2021/11/921未評価
2021/11/912未評価
2021/11/913未評価
組み合わせて追加クエリ。
日付従業員ID点呼項目ID項目評価注意事項ID
2021/11/911未評価1
2021/11/912未評価1

選択クエリに注意事項IDを加える。

10
りんご 2021/11/09 (火) 14:12:56 c564b@0e907 >> 9

訂正。組み合わせて追加クエリの従業員ID:1,1,1,2,2,2…

11
みづ 2021/11/10 (水) 17:48:31 58219@732d2

詳しい解説ありがとうございました

日付テーブルに分けた方が前回の注意事項IDをみるときに格段に少なくなるし
データベース設計的にも正しいということですね

(別途質問をしようと思いましたが関連ですのでこちらでさせていただきます)
そのようにしようと思いましたが一部の出勤データがEXCELからのインポートでした
一行に、(画像のように)ACCESSのレポートに表示する状態で入力されています
この場合、1対多の状態でインポートするには難しい処理が必要となりそうですが
どのようにしたらよいでしょうか?

12
りんご 2021/11/11 (木) 01:16:30 c564b@0e907 >> 11

データベース設計的にも正しいということですね

 日付別注意事項テーブルは、日付が決まると注意事項が決まった、ただそれだけです。レコード数がある条件で少なくなるとか意図していません。
 「11/11,法定速度遵守,11/11,車間距離保持」のように複数選べる場合、日付が決まると注意事項が決まった、とはなりません。さらに、「11/11,新人,法定速度遵守,11/11,ベテラン,車間距離保持」のようになる場合、日付と従業員のグループが決まると注意事項が決まった、こんなテーブルも必要になるでしょう。

1対多の状態でインポート…どのようにしたらよいでしょうか?

 ちゃんとやった事がないのであれですが、みんなインポートの前か後にデータを整えているんじゃないでしょうか?加工して1側のテーブルに追加クエリ、加工して多側のテーブルに追加クエリみたいな感じで。

13
hiroton 2021/11/11 (木) 11:28:21 e9855@f966d

点呼記録テーブルと日付テーブルの2つのテーブルへインポートするとして、

点呼記録テーブルへのインポートはそのままデータ形式を合わせてインポートすればいいです(不要な行はデータ形式不一致でエラーになって取り込まれないので)

日付テーブルへのインポートはそのままだと注意事項の行に日付がないので注意事項の行に日付をつける作業が必要です
最近似たような話題がありましたAccess2019のアクションカタログを利用して、空白セルに前行の値をコピーしたい

ACCESSの機能でやるなら取り込める形式の仮テーブルを作って取り込んだ後注意事項の行に日付をつけて、注意事項の行だけ抽出して本番テーブル(日付テーブル)へ追加とすればいいです

VBAでやるなら、1行ずつチェックしながら日付があれば日付を変数に確保、注意事項が出てきたら日付テーブルへ追加とすればいいですね
(どうせ全データチェックすることになるので点呼記録テーブルへのインポート作業も組み込んでしまえばいいと思います)

1対多の状態でインポート

リレーションシップで参照整合性をつけているなら日付データがないと点呼記録が入力できないので日付テーブルへのインポートの後、点呼記録テーブルへのインポートという順番でインポートします

VBAで全部やるなら注意事項は各日付の後に出てくるので最後の行からチェックする(先に注意事項の行が見つけられる)ように取り込めばいいです

1対多の状態のデータをそのまま取込ということは普通やりません

14
みづ 2021/11/11 (木) 16:37:11 58219@732d2

ありがとうございます
また説明不足があって恐縮なのですが、EXCELのデータにはすべての行(点呼記録レコード)に注意事項のIDが入力されています(VLOOKUPでマスタから文字列を表示させています)
ACCESSでインポートすることになったならEXCELでは注意事項自体を入力しません(本当はだめだけど書類上出来上がってればいいので、実際に注意事項などを意識していないため)
はじめからACCESSで入力すればいいじゃないか、と思われると思いますが、

数日間の平均値、週間、月間などの総計、前回からの空き時間などの計算やそれに伴う調整が必要で、その計算をACCESSですべてやるのは大変そうでした。(日をまたいだときや空き時間が短いと前日の労働時間として合算しないといけなかったりするので)EXCELだとオートフィルもあるしもろもろ手軽にできます
ですから最終的にACCESSに入れて管理する、という運用にしたいです

点呼記録テーブルと日付テーブルはそれぞれIDでリレーションするのだと思いますが
それぞれにインポートしてIDはどのようにあわせるのでしょうか?

15
hiroton 2021/11/12 (金) 09:07:30 e48a1@f966d

また説明不足があって恐縮なのですが、EXCELのデータにはすべての行(点呼記録レコード)に注意事項のIDが入力されています(VLOOKUPでマスタから文字列を表示させています)

ということは、EXCEL上のデータでいわゆる1対多の状態になっているということですね
ならば単純に「1」側のデータ(「日付」と「注意事項のID」)をインポートしてから「多」側のデータ(「注意事項のID」を除いたそのほかすべて)をインポートすればいいです

点呼記録テーブルと日付テーブルはそれぞれIDでリレーションするのだと思いますが
それぞれにインポートしてIDはどのようにあわせるのでしょうか?

DB設計におけるナチュラルキーとサロゲートキーという考え方の話になるんですがわざわざキーを作らなくても
日付テーブルの「日付」と点呼記録テーブルの「日付」でリレーションを組めばいいですよ

16
みづ 2021/11/12 (金) 18:31:47 58219@732d2

EXCEL上では1対多というか
日付 氏名 開始時間 車両番号 指示事項
のような並びで1行1件で日付や指示事項は重複して入っています
ACCESSにインポートする仕組みができたらEXCEL上では指示事項の入力はせずに
インポートしたときに付与させる方向で考えています

日付でリレーションする場合、日付テーブルと点呼記録テーブル双方に日付というフィールドができるということになりますか?
それですと日付テーブル自体をなくし、点呼記録テーブルのみで
hatena

17

途中送信してしまいました

日付でリレーションする場合、日付テーブルと点呼記録テーブル双方に日付というフィールドができるということになりますか?
それですと日付テーブル自体をなくし、点呼記録テーブルのみで
hatenaさんのコードで運用すると
すべての点呼記録テーブルに指示事項IDがついてしまうけど日付をもたせるのと同じことなので
データベース的には問題ないですか?
レポート表示では重複を非表示、で対応します

18
りんご 2021/11/13 (土) 23:09:22 c564b@0e907 >> 17

すべての点呼記録テーブルに指示事項IDがついてしまうけど日付をもたせるのと同じことなので…11/15,11/15,11/15,…11/16,11/16,11/16…
Aさん,Bさん,Cさん,…Aさん,Bさん,Cさん,…
9:00,9:00,9:00,…9:00,9:00,9:00,…
1234,5678,9123,…1234,5678,9123,…
  指示事項ID1      ,    指示事項ID2
 これが、次のようになるけれど
11/15,11/15,11/15,11/16,11/16,11/16…



1,1,1,2,2,2…
 レポート表示では、日付の重複非表示みたいに指示事項IDの重複非表示で対応するので、データベース的に問題ないと思うが、どうなのかアドバイスが欲しい。

 こういう事でしょうか?

 

21

正規化という考え方が参考になります
データベース的な視点で言えば破綻はしていないので運用自体は可能でしょう
データベースとしてのメリットを得られないというだけですね

レポート表示では重複を非表示、で対応します

これは別な話ですね。特に関係はないです

19
みづ 2021/11/14 (日) 14:55:09 58219@732d2

日付テーブルをつくる目的は重複データをつくらないことでしょうか?
1対多にインポートすると、日付テーブル、点呼記録テーブル、インポートして日付でリレーションするならどちらにも日付が残ることになりますよね?
それだったら日付テーブルをなくして、点呼記録テーブルだけでも問題ないのではないか、と思ってしまいました
(インポートのときにそれぞれのテーブルに振り分ける必要があり、複雑になりそうなので)

もし僕の理解が間違っていたらすみません

20
りんご 2021/11/14 (日) 20:11:50 c564b@0e907

 『日付が決まると何かが決まった』、『Xが決まるとYが決まった』、これを探してテーブルを作りました。重複データ云々だからどうすることはなくなります。
 日付テーブルは作らずに、点呼記録テーブル『日付と従業員が決まると、諸々決まる』とする場合、今日のAさんは法定速度遵守、今日のBさんは車間距離保持、これが可能になります。みんなの注意事項を揃えるには、何か工夫が必要になるでしょう。
 日付テーブルを作らなくても、データベースだからインポート振り分けは避けられないと思います。従業員テーブルに登録して、点呼記録テーブルに登録するように。インポートしたテーブル1つだけでは、データベースになりませんよね。

22
みづ 2021/11/15 (月) 17:13:23 58219@732d2

いずれにしてもIDでの主キーはつくらずに日付でやっても問題ないということになりますか?

23
りんご 2021/11/15 (月) 17:41:26 c564b@0e907

 日付テーブルは作らずに始めてもいいんじゃない。点呼記録テーブルは、日付と従業員の複合主キーを設定する感じでしょう。

24
りんご 2021/11/16 (火) 16:09:46 c564b@0e907

 データベースがやりたいわけじゃない、自動入力がやりたい、レポートを印刷したいという事でしたら、Excelで自動入力する方法、ワードにインポートする方法を検討してみるのはどうでしょうか?
 データベースがやりたいという事でしたら、複合主キーや複数テーブルを頑張るしかないですね。