ACCESS フォームで更新ボタンを押した時にレコード更新する機能(VBAコード公開)
ACCESSのフォームで入力された内容は、基本的にリアルタイムにレコードソースのテーブルに反映されます。
しかし、中には更新ボタンを押した時だけ反映したいというケースもあるでしょう。
今回は、フォームで更新ボタンを押した時にレコード更新する機能をご紹介します。
こんにちは。
はこにわガジェット (@hakoniwagadget) です。
ACCESSを使った売上管理、顧客管理などのデータベース開発を行っています。
ACCESSは使いこなすために少しスキルが必要なものの、うまく活用すればExcelよりも業務の効率化が図れます。
この記事ではACCESSで実際に作成したフォームやレポートを、その作成方法と共にご紹介していきます。
目次
完成形
最初に完成形を示します。
こちらは商品マスターの一覧フォームです。
このフォームで商品IDをダブルクリックすると、詳細を表示するフォームが開きます。
ここで商品名を修正してみます。商品Aから商品A1に変更しました。
その後、登録ボタンを押すことで、確認メッセージの後に更新が反映されます。
「はい」を押すと
一覧フォームで更新内容が反映されたことが分かります。
一方、登録フォームで値の更新後に「閉じる」ボタン押すと、
更新が反映されずに、元の値のままになります。
このように、フォームでの更新内容を自動的に反映するのではなく、ボタン操作によって反映したりしなかったりを選択することが可能です。
作成方針
まずは大まかに、作成の方針をご紹介します。
今回は一覧フォームから詳細フォームに情報を呼び出して表示・更新を行います。
この際、一覧フォームはレコードソースをテーブルにしますが、詳細フォームの方はレコードソースを設定せずに非連結で作成します。
一覧フォームから詳細フォームを呼び出した際に、非連結の詳細フォームにVBAで値を読み込んで表示します。
その後、登録ボタンが押されたら再度VBAで値をテーブルに書き込み、閉じるボタンが押された際は書き込み処理を行わずにフォームを閉じます。
テーブルの準備
では、実際の作成方法に入りましょう。
最初にテーブルを準備します。
今回は下記のレイアウトでtest_登録というテーブルを作成しました。
下記のように、商品情報が登録されているテーブルです。
フォームの準備
次にフォームの準備です。
フォームは2種類作成します。
一覧フォーム
一覧フォームは複数のレコードを一覧表示するフォームです。
デザインビューで見ると下記のようになります。
こちらは、テーブル「test_登録」を元に作成しています。
フォームウィザードを利用すると簡単に作成できるでしょう。
作成時には、既定のビューが「帳票フォーム」になるように注意してください。
帳票フォームを選択することで一覧表示が可能です。
帳票フォームでは、フォームヘッダーセクションに見出しとなるラベルを配置し、詳細セクションに実際のデータを表示するテキストボックスを配置します。
こうすることで、フォームビューで表示した際に詳細セクションがレコード数分繰り返されて表示できます。
詳細フォーム
次に詳細フォームです。
こちらは、1レコードの情報を1画面に表示するフォームです。
今回の機能を実現するにあたり、実際にデータを入力するのがこのフォームです。
デザインビューで見ると下記になります。
こちらは既定のビューを「単票フォーム」にします。
また、今回はフォームでの入力内容をリアルタイムにテーブルに反映しないため、各テキストボックスのレコードソースは非連結にします。
上記のデザインビュー画面でも「非連結」と表示されていることが分かると思います。
この2つのフォームを作成するとフォームの準備は完了です。
VBAプログラミング
では、フォームの動作をVBAで作っていきましょう。
一覧フォームから詳細フォームを開く機能
最初に、一覧フォームから詳細フォームを開く機能です。
ここでは、単純にフォームを開くだけでなく、選択したレコードの内容をフォームに表示する必要があります。
まず一覧フォームをデザインビューで表示します。
商品IDのダブルクリック時にイベントプロシージャを設定します。
設定するイベントプロシージャの内容は以下の通りです。
Private Sub 商品ID_DblClick(Cancel As Integer)
DoCmd.OpenForm "test_登録"
[Forms]![test_登録]![商品ID] = Me!商品ID
[Forms]![test_登録]![商品名] = Me!商品名
[Forms]![test_登録]![仕入先] = Me!仕入先
[Forms]![test_登録]![単価] = Me!単価
[Forms]![test_登録]![登録日] = Me!登録日
End Sub
最初の
DoCmd.OpenForm "test_登録"
で詳細フォームを開きます。
しかし、詳細フォームは非連結でそのままでは何もデータが表示されません。
そこで、その後の処理でtest_登録フォームの各テキストボックスに、一覧フォームに表示されている値を転記しています。
右辺のMe!はこの場合「test_登録一覧」フォームを指しています。
こうして、一覧フォームで選択したレコードの内容を詳細フォームに表示することができます。
詳細フォームでの入力内容をテーブルに反映する機能
次に、詳細フォームでの入力内容をテーブルに反映する機能です。
こちらは、詳細フォームの登録ボタンにイベントプロシージャを設定します。
設定するイベントプロシージャの内容は下記の通りです。
Private Sub 登録_ボタン_Click()
'変数の宣言
Dim cnn As ADODB.Connection
Dim rst1 As ADODB.Recordset
'変数にADOオブジェクトを代入
Set cnn = CurrentProject.Connection
Set rst1 = New ADODB.Recordset
rst1.CursorLocation = adUseClient
'レコードセットを取得
rst1.Open "test_登録", cnn, adOpenKeyset, adLockOptimistic
'確認
If vbYes = MsgBox("登録します。" & vbCrLf & "よろしいですか?", vbQuestion + vbYesNo, "登録確認") Then
rst1.Filter = "商品ID = " & Me!商品ID
If rst1.RecordCount = 0 Then
'同一商品IDが存在しない場合はレコードを追加
rst1.AddNew
rst1!商品名 = Me!商品名
rst1!仕入先 = Me!仕入先
rst1!単価 = Me!単価
rst1!登録日 = Me!登録日
rst1.Update
Else
'同一商品IDが存在する場合はレコードを更新
rst1!商品名 = Me!商品名
rst1!仕入先 = Me!仕入先
rst1!単価 = Me!単価
rst1!登録日 = Me!登録日
rst1.Update
End If
End If
'終了処理
rst1.Close: Set rst1 = Nothing
cnn.Close: Set cnn = Nothing
DoCmd.Close
End Sub
ADOを使ったレコードの追加、更新処理を記述しています。
最初の
'変数の宣言
Dim cnn As ADODB.Connection
Dim rst1 As ADODB.Recordset
'変数にADOオブジェクトを代入
Set cnn = CurrentProject.Connection
Set rst1 = New ADODB.Recordset
rst1.CursorLocation = adUseClient
'レコードセットを取得
rst1.Open "test_登録", cnn, adOpenKeyset, adLockOptimistic
の部分はADOを使うための既定の処理です。
レコードセット:rst1に「test_登録」テーブルをセットしています。
その後、実際のレコード更新処理を下記で行います。
rst1.Filter = "商品ID = " & Me!商品ID
If rst1.RecordCount = 0 Then
'同一商品IDが存在しない場合はレコードを追加
rst1.AddNew
rst1!商品名 = Me!商品名
rst1!仕入先 = Me!仕入先
rst1!単価 = Me!単価
rst1!登録日 = Me!登録日
rst1.Update
Else
'同一商品IDが存在する場合はレコードを更新
rst1!商品名 = Me!商品名
rst1!仕入先 = Me!仕入先
rst1!単価 = Me!単価
rst1!登録日 = Me!登録日
rst1.Update
End If
ここでは最初にrst1.Filterを行って、test_登録テーブルを、test_登録フォームで表示している商品IDでフィルターします。
なお、商品IDは主キーです。
既存のレコードの場合はこの時点でtest_登録フォームに商品IDが表示されているはずですので、フィルターの結果1レコードのみが抽出されます。
一方、新規レコードの場合は商品IDがありませんので、抽出結果は0件となります。
この結果をrst1.RecordCountで判定します。
新規レコードの場合はrst1.RecordCount = 0 となりますので、そこからは新規レコードをtest_登録テーブルに追加する処理を行います。
一方、既存レコードではrst1.RecordCount = 1 となりますので、既存レコードの更新処理を行います。
rst1に対する値の書き込み処理はほぼ新規でも更新でも同一ですが、新規の場合のみrst1.AddNewが必要なことに注意してください。
ADOについて詳しく知りたい方は下記の記事も参照ください。
テーブルの内容を更新せずに詳細フォームを閉じる機能
最後に、テーブルの内容を更新せずに詳細フォームを閉じる機能です。
こちらは、test_登録フォームをデザインビューで開き、閉じるボタンのクリック時イベントにイベントプロシージャを設定します。
設定する内容は以下です。
Private Sub 閉じる_ボタン_Click()
DoCmd.Close
End Sub
DoCmd.Closeでフォームを閉じるだけの単純な処理です。
今回作成したtest_登録フォームは非連結でテーブルとフォームの入力値が連動していませんので、値を更新したくない場合は単純にフォームを閉じる処理だけでよい、となります。
以上、フォームで更新ボタンを押した時にレコード更新する機能をご紹介しました。
ACCESSを使いこなせば、業務の効率化や自動化が実現できます。
しかし、自分でACCESSを学ぶには時間がない、難しそうで不安、という方も多いでしょう。
そんな時は、ACCESS開発歴20年以上、過去に100以上のACCESSデータベースを開発してきた私(@hakoniwagadget)にお任せください。
ACCESSの新規開発、既存のACCESSの修正、ACCESSの操作レッスンなど様々なサービスをご提供しています。
ご興味のある方は下記のサービス一覧をご覧ください。
最後までお読みいただき、ありがとうございました。