ACCESS メインフォームの主キー確定を強制させる機能(VBAコード公開)
ACCESSではメインフォーム、サブフォームという形で2つのフォームを組み合わせて1つのフォームを作ることが可能です。
この場合、メインフォームの主キーをサブフォームにも持たせ、両方のフォームを主キーで連動させることが一般的です。
しかし、メインフォームで主キーがない状態でサブフォームに値を入力されてしまうと両方のデータの連携ができません。
今回は、これを防ぐためにサブフォームの値入力前にメインフォームでの主キー確定を強制させる機能をご紹介します。
こんにちは。
はこにわガジェット (@hakoniwagadget) です。
ACCESSを使った売上管理、顧客管理などのデータベース開発を行っています。
ACCESSは使いこなすために少しスキルが必要なものの、うまく活用すればExcelよりも業務の効率化が図れます。
この記事ではACCESSで実際に作成したフォームやレポートを、その作成方法と共にご紹介していきます。
完成形
最初に完成形を示します。
下記は、売上情報を入力するためのフォームで、売上伝票入力メインフォームと、下段の一覧表になっている売上明細サブフォームから成っています。
このフォームでメインフォームの主キーは売上IDです。
売上ID欄に「新規」と表示されている場合は、主キーの取得ができていない状態です。
この状態でサブフォーム側を操作しようとすると以下のエラーメッセージが出て操作ができないようにしてあります。
これにより、メインフォームの主キー確定前にサブフォームに入力されることを防いでいます。
メインフォームとサブフォームの連携
なぜ、サブフォームの入力前にメインフォームの主キーを確定させたいかというと、メインフォームの主キーによってメインフォームとサブフォームを連動させているからです。
今回のフォームを出材ビューで見ると下記のようになっています。
売上明細サブフォームのリンク親フィールドとリンク子フィールドをどちらも売上IDに設定しています。
これは、サブフォームのレコードにメインフォームの売上IDと同じもののみを抽出して表示するということを示しています。
さらに、この設定を行っておくとサブフォームに新規レコードを追加した際に、サブフォームの売上IDに自動的にメインフォームの売上IDが入力されてリレーションができるのでとても便利です。
一方で、メインフォームの売上IDが確定していない状態でサブフォームを入力してしまうとサブフォームに売上IDが入力されず、メインフォームとサブフォームのリンクが崩れてしまいます。
これを防ぐのが今回の目的です。
サブフォーム入力前にメインフォームの主キーを確定させる機能
開発方針
では実際に機能を開発しましょう。
まずは開発方針です。
これを実現するには、どのタイミングでメインフォームの主キーが確定しているかのチェックを行うか、という設計が最初に必要です。
タイミングは以下が考えられます。
1.サブフォームを触ったタイミング
2.サブフォームに最初に何かを入力したタイミング
3.サブフォームの1レコード目が入力完了したタイミング
ではどのタイミングでチェックを行うべきでしょうか。
結論から言うとどのタイミングでも可能です。
ただし、最も簡単で漏れがないのは1.サブフォームを触ったタイミング、です。
2.3.ですとサブフォーム側の入力内容に影響を受けますし、チェックをすり抜けてしまう可能性が高くなります。
そのため、今回はサブフォームを触ったタイミングでチェックするように設定します。
フォームのイベント設定
それでは、チェックを行うためにフォームにイベントを設定します。
イベントの設定はサブフォームではなくメインフォーム側で行います。
メインフォームでサブフォームを選択し、イベントタブの「フォーカス取得時」にイベントプロシージャを設定しましょう。
フォーカス取得時は、フォーム上のそのオブジェクトが選択されたときに発生するイベントです。
今回でいえば売上明細サブフォーム内のどこかがクリックされた時点で発生します。
VBAのプロシージャ
フォーカス取得時のイベントプロシージャに設定したのは以下になります。
このコードでメインフォームの主キー入力を強制します。
Private Sub 売上明細サブフォーム_Enter()
If Me!売上ID = 0 Or IsNull(Me!売上ID) = True Then
MsgBox "顧客名を先に選択してから明細を追加してください。", vbCritical + vbOKOnly, "顧客名未選択"
Me!顧客ID.SetFocus
End If
End Sub
以下、解説します。
最初の
If Me!売上ID = 0 Or IsNull(Me!売上ID) = True Then
は、メインフォームの主キーが入力されているか否かのチェックです。
売上IDは数値型なので0の時と、Nullの時のどちらにも対応できるようにしてあります。
こうしたチェックは想定外のデータが入ることを予期して対応できるパターンを増やしておいた方が無難でしょう。
そして、メインフォームの主キーである売上IDが確定していない場合は、以下の処理を行います。
MsgBox "顧客名を先に選択してから明細を追加してください。", vbCritical + vbOKOnly, "顧客名未選択"
Me!顧客ID.SetFocus
1行目はメッセージの表示です。
ここで売上Dではなく顧客名を選択させるようにしているのは、メインフォームで何らかの値が入力されれば主キーは確定されるからです。
逆に主キーである売上IDはオートナンバー型なので手入力ができず、必須項目である顧客名を選択させるようにしています。
2行目では、フォーカスを顧客IDに移動させています。
この部分が非常に重要です。
このイベント自体がサブフォームのフォーカス取得時イベントですので、現在のフォーカスはサブフォームにあります。
これを、SetFocusを使って強制的に別のコントロールに移動させます。
そうするとサブフォームからフォーカスが外れ、そのままサブフォームに入力を続けることができません。
主キーが確定していない状態で再度サブフォームを操作しようとすると、また同一のチェックが発生することになります。
以上、メインフォームの主キー確定を強制させる機能をご紹介しました。
ACCESSを使いこなせば、業務の効率化や自動化が実現できます。
しかし、自分でACCESSを学ぶには時間がない、難しそうで不安、という方も多いでしょう。
そんな時は、ACCESS開発歴20年以上、過去に100以上のACCESSデータベースを開発してきた私(@hakoniwagadget)にお任せください。
ACCESSの新規開発、既存のACCESSの修正、ACCESSの操作レッスンなど様々なサービスをご提供しています。
ご興味のある方は下記のサービス一覧をご覧ください。
最後までお読みいただき、ありがとうございました。