Microsoft Access 掲示板

登録画面の構成に関して

15 コメント
views
5 フォロー

こちらのコミュニティには初めてお世話になります。現在、Accessを勉強中の者です。
身近にシステムに詳しい方がおらず、ご経験者様のお力添えをいただけたらと思いこの度ご相談させていただきました。

現在、会社の売掛金管理システムを作成中なのですが、
顧客との契約が成立した際に、契約情報を登録するためのフォームの構成を考え中です。
「こんな風だったら便利かな」という理想のフォームをまずはパワポで作ってみたのですが、
Accessの特徴をすべて理解しきれていないため、もっと良いやり方があるのではないかと悩んでおります。
抽象的な質問で申し訳ないのですが、もっと効率の良いデータの入力方法、
もしくはシステムとして悪い点がありましたら、ご教授いただけますと大変有難いです。


画像



テーブル
T_契約マスタ(画像の桃色フィールドの情報が書き込まれるテーブル)
T_月額マスタ(画像の青色フィールドの情報が書き込まれるテーブル)
T_顧客マスタ(契約マスタの1対多のテーブル)

クエリ
Q_登録追加クエリ

フォーム
F_登録画面フォーム
(この他に、月額料金が入金されていることをチェックするフォームや、
年度にわたって売掛金データを表示するフォーム、請求書のレポートを作成予定です)


【考えているフォームの運用について】

  1. 上部の非連結コントロールにユーザーがデータを入力する
  2. 「全てに入力」ボタンを押すと、下部の非連結コントロールに、「期間」の月数分データが入力される
    ※このコントロールのデータは「Q_登録追加クエリ」に紐づけられている
  3. 月によっては内容が若干変わることがあるので、その場合はこの段階で手動で編集する
  4. データをすべて入力し終わったら、右下の「登録」ボタンを押すと
    フォームに紐づけられた「Q_登録追加クエリ」が「T_契約マスタ」「T_月額マスタ」テーブルに追加される

【問題点】
契約によっては5年以上のものがあるため非連結コントロールが5年分以上必要となり、開発工数がかなり掛かる

【考えた改善策】
フォーム上での入力を諦めて、Excelに入力したデータをインポートするようにする

もし分かりづらい部分やつじつまが合わない点がございましたら、大変申し訳ありません…
お手数をお掛けしますが、教えていただけますと非常に助かります。
最後までご覧いただきありがとうございました。どうぞよろしくお願いいたします。

だいふくもち
作成: 2021/04/26 (月) 15:18:30
最終更新: 2021/04/26 (月) 16:03:23
通報 ...
1

非連結ではなく、メイン/サブフォーム形式の連結フォームでいいと思いますが、だめでしょうか。

Accessのフォームのメイン/サブフォームとは | できるネット

サブフォームを含むフォーム (一対多のフォーム) を作成する - Access

2
だいふくもち 2021/04/26 (月) 17:14:14

>hatena様
ご回答いただきありがとうございます!また、URLも教えていただきありがとうございます。
確かにクエリを間に挟まずに、直接テーブルに繋げた方が無駄がなさそうです…

色々と調べてみたのですが、連結フォームを用いた登録方法は
下記の画像のようなフォームで、一件ずつレコードを登録していくやり方が主流のようでした。
hatena様が想定されているのは以下のようなフォームで合っておりますでしょうか…?

画像

ご回答いただいた内容を上手く汲み取れず申し訳ありません…

3

回答の前に

画像は下記のアップロードボタンでアップロードするとページ内に表示できますので、それを利用してください。
詳細は下記を参照してください。
Microsoft Access 掲示板 の使い方 Microsoft Access 掲示板 - zawazawa

下記のように表示できます。

画像1

回答

最初の画像のようにするなら、
メインフォームは非連結にする。
T_顧客マスタから連結フォームを作成。
T_月額マスタとT_契約マスタを結合させてクエリから連結フォームを作成。
この2つのフォームをサブフォームとして埋め込むという設計にするといいと思います。
メインフォームの「すべて入力」ボタンで指定した期間のデータをVBAで追加するとようにします。

VBAは必要になりますが、すべて非連結でするより、設計もシンプルだしコード量もはるかに少なくなります。
ただ、Accessのフォームに扱いに慣れている必要があります。
Accessの初心者なら、まずは入門書か入門サイトで基本のフォーム設計を習得しておくといいでしょう。

4

T_顧客マスタ の方はサブフォームではなくてリストボックスにしてもいいでしょう。
ユーザーはリストボックスで顧客を選択することができます。

5
だいふくもち 2021/04/30 (金) 15:02:59 修正

>hatena様
お礼をお伝えするのがすっかり遅くなってしまって申し訳ありません…
再びご回答いただきありがとうございます!

また、画像のアップロードに関しても教えていただき感謝いたします!
(投稿が見づらくて申し訳ありませんでした…)

1対多の情報でしかサブフォームを利用できないと思い込んでいたので、
連結クエリのサブフォームを用いるという方法が思いつけませんでした…
Accessに関しては、数冊テキストを読み、記載してあった演習を2周した程度なのですが、
実践に活かすとなると難しいです…(サブフォームに関して何度も触れたはずなのに)

ただ、hatna様のおかげで今後の方向性が固まりました!
道のりは遠そうですが、頑張ってみます!
教えていただいた方法でパワポを作り直してみたのですが、もしhatena様の意図と
相違がありましたら、お手数をお掛けしますがご指摘いしていただけますと幸いです。

Excel VBAなどで困ったことがある場合はネットでよく調べ物をするのですが、
実は、度々hatena様をお見掛けしたことがありましたので、今回お話できて光栄でした。

6
だいふくもち 2021/04/30 (金) 15:08:07

申し訳ありません。画像が反映されませんでしたので連投失礼いたします。画像1

7

画像は私のイメージしていた通りのものです。

メインフォームのコマンドボタンでサブフォームにレコード追加するときのサンプルコードを例示しておきます。
コントロール名等は適当ですので参考程度にして作成してみてください。

Private Sub cmdAddNew_Click()
    Dim 開始年月 As Date
    開始年月 = DateSerial(Me.開始年,Me.開始月,1)
    Dim 月数 As Long
    月数 = Datediff("m", 開始年月, DateSerial(Me.終了年,Me.終了月,1)) 

    Dim i As Long
	With Me.サブフォームコントロール名.Form.Recordset
	    For i = 0 to 月数
	        .AddNew
	        !契約番号 = Me.契約番号
	        !請求先 = Me.請求先
	        !契約名 = Me.契約名
	        !月額 = Me.月額
	        !請求月 = DateAdd("m",i,開始年月)
	        '・・・・
	        .UpDate
	    Next
    End With
End Sub

ここまで書いてちょっと思ったのは、メインフォームは非連結にせずに、T_契約マスターと連結させた方がいいかも知れませんね。
とりあえず作成してみて、行き詰ったらまた質問してください。

8
だいふくもち 2021/05/06 (木) 08:49:40

>hatena様
御礼の返答が遅くなって申し訳ありません…
Excel VBAではFor文を使用したことがあったのですが、Accessでは未だ使用したことがありませんでしたので、
hatena様のコード、とても参考になりました!何から何までお気遣いいただき本当にありがとうございます!

作成の過程で、行き詰まった際はまたご助言いただけますと非常に有難いです。
この度は貴重なお時間をいただき、本当にありがとうございました!😊

9
だいふくもち 2021/05/12 (水) 16:11:30 修正

>hatena様
前回は色々とご教授いただきありがとうございました。
hatena様のお力添えのおかげで、途中まで順調に進むことができました。

しかし、どうしても一点つまづいてしまった部分があり、
ご助言をいただきたく、またご相談させていただきました。

画像1

hatena様のご助言通り、メインフォームの「基本情報」はT_契約マスターと連結させました。
教えていただいたVBAのコードは、「ごとに請求」ボタンに埋め込んでおります。
また、月額、税率、税の処理などのコントロールは、非連結で作成しております。

今回困っている箇所ですが、ボタンを押すと問題なくレコードがサブフォームに追加されるのですが、
サブフォームを触ろうとするとサブフォームがクリアされてしまいます。
(サブフォーム以外の場所をクリックしてもクリアされてしまいます)
サブフォームはT_月額マスタに連結しているのですが、T_月額マスタにはきちんと保存されておりました。

また、「ごとに請求」ボタンを2回連続で押すと、今度はサブフォームはクリアされず、
サブフォームに追加されている1回目のレコードの下に2回目のレコードが追加されます。
2回目以上だと、不思議なことにサブフォームを触ってもクリアされず編集可能です。

稀にですが、月額が異なっていたり、ひと月だけ税率の違う月が存在するため、
ユーザーがサブフォームのレコードを自由に編集できるようにしておきたいです。
ボタンを押した後、データをそのままサブフォームに保持しておける手段がありましたら
どうか教えていただけませんでしょうか?

直接テーブルとつながってるサブフォームなので、もしかしたらただレコードを表示するための
ユーザーは触れないサブフォームにした方が理想的なのかもしれません…
もし、データベース構造的にふさわしくない等のご意見がありましたら、
お手数をお掛けしますが、併せて教えていただけますと大変ありがたいです。
よろしくお願いいたします🙇‍♂️

10

下記の情報を提示してもらえますか。

「ごとに請求」ボタンのクリック時イベントのVBAコード。
サブフォームコントロールの「リンク親フィールド」「リンク子フィールド」の設定。
サブフォームで手入力で入力したときは問題なく入力できるかどうか。

11
だいふくもち 2021/05/13 (木) 17:25:30

情報が足りずに申し訳ありません…

  • 「ごとに請求」ボタンに埋め込んでいるマクロのコード
    '請求月数の分だけ、サブフォームにレコードを追加する
    Dim i As Long
    With Me.T_月額マスタのサブフォーム1.Form.Recordset
      For i = 0 To 月数
          .AddNew
          Me.T_月額マスタのサブフォーム1.Form![契約番号サブ] = Me.txt契約番号
          Me.T_月額マスタのサブフォーム1.Form![月額サブ] = Me.月額
          Me.T_月額マスタのサブフォーム1.Form![入金月サブ] = DateAdd("m", i, 開始年月)
          Me.T_月額マスタのサブフォーム1.Form![税率サブ] = Me.税率
          Me.T_月額マスタのサブフォーム1.Form![税の処理サブ] = Me.税の処理
          '「ごとに請求」のコンボボックスで、以下の値が選択されている場合
          If Me.入金月頻度 = "2ヶ月" Then
              i = i + 1
          ElseIf Me.入金月頻度 = "半年" Then
              i = i + 5
          ElseIf Me.入金月頻度 = "1年" Then
              i = i + 11
          End If
      Next
    End With
    
  • サブフォームのリンク
    親フィールド:「T_契約マスタ」の「契約番号」
    子フィールド:「T_月額マスタ」の「契約番号」
    (リレーションシップで結ばれている関係をリンクフィールドと解釈しているのですか、相違ありませんでしょうか…?)
    画像1

  • サブフォーム上で手入力した場合は問題なく入力できました。

以上、どうぞよろしくお願いいたします。

12
だいふくもち 2021/05/14 (金) 10:44:14

リンク親フィールド/子フィールドが設定されている箇所が分かりましたので、念のため追記いたします。
画像1

13
hatena 2021/05/14 (金) 13:07:43 修正

まず、Forループ内でカウンター変数を変更するのはご法度です。Step を使いましょう。

データ追加は、サブフォームのレコードセットに対してAddNewで追加するようにします。
Withでサブフォームのレコードセットを参照するようしてますのて、
Me.T_月額マスタのサブフォーム1.Formは不要です。

![契約番号サブ] 等の[]内はコントロール名ではなく、フィールド名にしてください。

テーブルのフィールド名が「契約番号サブ」ならいいですが、「契約番号」なら、
![契約番号]
です。

あと、最後に .Update が必要です。

'請求月数の分だけ、サブフォームにレコードを追加する
Dim i As Long, s As Long
With Me.T_月額マスタのサブフォーム1.Form.Recordset
  '「ごとに請求」のコンボボックスで、以下の値が選択されている場合
  If Me.入金月頻度 = "2ヶ月" Then
      s = 2
  ElseIf Me.入金月頻度 = "半年" Then
      s = 6
  ElseIf Me.入金月頻度 = "1年" Then
      s = 12
  End If

  For i = 0 To 月数 Step s
      .AddNew
      ![契約番号] = Me.txt契約番号
      ![月額] = Me.月額
      ![入金月] = DateAdd("m", i, 開始年月)
      ![税率] = Me.税率
      ![税の処理] = Me.税の処理
      .Update
  Next
End With

リンクフィールドの設定は問題ないと思います。

14
だいふくもち 2021/05/17 (月) 11:19:51

>hatena様
ご回答とご指摘いただきありがとうございます!とても参考になりました!
Forループ内でカウンター変数を使用しない方が良いというのは知りませんでした…
例文をいくつか調べてみましたが、確かにカウンター変数を途中で変更されている方はおりませんでした。
ご法度というのは、For文にカウンター変数を変更する分岐を入れてしまうと、
煩雑になり可読性が落ちるからでしょうか?

また、コントロール名ではなく、フィールド名を指定するということですが、
こちらの理由をお伺いしてもよろしいでしょうか…?
個人的には、コードを見返した際に分かりやすく管理しやすいかな…
と思ってコントロール名を分かりやすい名前に変更し、指定していたのですが、
テーブルにデータを追加する場合などは、テーブルのフィールド名を指定しておかないと
後で問題になったりするのでしょうか?(見かける例文はコントロール名での指定が多い気がしたので…)

教えていただいたコードに変更しましたが、同じ症状が出てしまいます…
サブフォームをもう一度作り直してみましたが、結果は同じでした。
同じような症例がないか、もっと調べてみたいと思います。
(せっかくたくさんアドバイスいただいたのに解決できず申し訳ありません…)

15
だいふくもち 2021/05/17 (月) 13:58:32 修正

追記です。
メインフォームを新しく作り直したところ、消える現象はなくなりました!
プロパティの設定を新旧フォームで見比べてみたのですが、特に差異もなく…
原因を突き止めることができましたら、またご報告させていただきたいと思います。