Accessお手本データベースのホームへ戻る

データシート上の複数のレコードを一括して変更前の状態に復元するお手本

 

4-6-1 作業明細の複数レコードを一括して復元するサンプルデータベース

 

このサンプルデータベースは、データシート上の複数レコードを一括して変更前の状態に復元します。データシート上のシングルレコードを変更前の状態に戻すには、メニューから復元のアイコンをクリックします。ところが、データシート上の複数のレコードを変更前の状態に復元するアイコンは、用意されていません。このサンプルデータベースでは、DBEngineのトランザクション機能を使用することにより、複数のレコードを変更前の状態に復元します。複数のレコードを一括して復元する機能は、受注伝票入力、見積書入力などメイン/サブフォームを使用したアプリに適用すると効果があります。

 

サンプルデータベース(CH4-6.mdb)では、以下のノウハウを習得することができます。

 

◆ トランザクションを一括してコミット/ロールバックする方法

◆ メイン/サブフォームでサブフォームに表示されるレコードをアプリ独自で絞り込む行う方法

 

   データシート上の複数レコードを一括して変更前の状態に復元するフォームを作成するには

 

1 Access を起動して作業フォルダに、新規データベース CH4-6.mdbを作成します。

 

2 ファイルメニューから外部データの取り込みインポートをクリックします。インポートのダイアログが表示されたら、CH4-6.mdbを選択してインポートボタンをクリックします。オブジェクトのインポートダイアログが表示されたら、テーブルタブをクリックしてすべて選択のボタンをクリックします。同様の手順で、クエリ、フォーム、モジュールタブをクリックしたらすべて選択をクリックして、最後にOKボタンをクリックしてインポート処理を完了させます。

 

4-6-2 CH4-6.mdbからテーブル、クエリ、フォーム、モジュールの全てのオブジェクトをインポートする

 

3 データベースウィンドウからクエリをクリックしたら、qryWorkOrderDetailsを選択してデザインボタンをクリックして開きます。フィールドWoIDの抽出条件に[Forms]![frmWorkOrder]![WoID]を設定します。サブフォームのWoIDの抽出条件に、にメインフォームのWoIDを設定することにより、サブフォームにはメインフォームに関連したレコードのみ表示されます。

 

4-6-3 サブフォームのレコードソースに抽出条件を設定してメイン/サブフォームを連動させる

 

4 データベースウィンドウからフォームをクリックしたら、frmWorkOrderをデザインモードで開きます。コンボボックスのスタッフIDの右側に、作業明細を一括復元するコマンドボタンを作成します。コマンドボタンのプロパティを表示させたら、標題に作業明細の一括復元を設定して、コントロールの名前をcmdUnDoWODetailsに書き替えます。

 

次に、フォームフッターにラベルを作成して標題にコマンドボタンの説明を入力します。

 

4-6-1 コマンドボタン/ラベルのプロパティ

コントロールの種類

プロパティ

コマンドボタン

名前

cmdUnDoWODetails

標題

作業明細の一括復元

ラベル

標題

作業明細の出勤/退勤時間を変更してから一括復元のボタンをクリックすると複数のレコードが変更前に復元されます

 

 

4-6-4 一括復元のコマンドボタンをラベルに追加した例

 

5 メニューからコードのアイコンをクリックして、フォームモジュールを開きます。フォームモジュールの全てのコードを削除します。CH4-6.mdbを開いたら、frmWorkOrderのフォームモジュールをコピーして貼り付けます。フォームモジュールのソースコードは、リスト4-6-1を参照してください。メインフォームのコードを置換することにより、サブフォームのトランザクション処理が可能になります。メインフォームを保存して閉じます。

 

6 データベースウィンドウからサブフォームsfrWorkOrderDetailsを選択したら、メニューからコードのアイコンをクリックしてフォームモジュールを表示させます。フォームの全てのコードを削除したら、CH4-6.mdbsfrWorkOrderDetailsのフォームモジュールをコピーして貼り付けます。尚、フォームモジュールのソースコードは、リスト4-6を参照してください。サブフォームを保存して閉じます。

 

7 メインフォームfrmWorkOrderをビューモードで開いたら、明細行の複数レコードを変更します。明細行を変更すると、作業明細の一括復元のコマンドボタンが使用可能状態になりますので、クリックして一括復元します。次に、明細行の複数レコードを選択したら、DELキーを押して削除します。一括復元のコマンドボタンをクリックして、削除したレコードが復元されるか確認します。

 

8 一括復元処理が正常に動作することを確認したらメインフォームを保存して、Access を終了させます。

 

 

Sub Form_Current()イベントの処理

このイベントは、カレントレコードが移動するとき実行されます。このイベントでは、サブフォームのトランザクション処理を可能にするための準備をします。

DBEngine.CreateWorkspaceでは、フォーム固有のWorkspaceを作成します。CreateWorkspaceメソッドには、3個の引数を指定します。

 

Name    新規に作成するWorkspaceオブジェクトの名前を指定します。

User      新規に作成するWorkspaceオブジェクトの所有者を指定します。

  Password 新規に作成するWorkspaceオブジェクトのパスワードを指定します。

 

mws.OpenDatabase(CurrentDb.Name)では、新規に作成したWorkspaceにカレントデータベース(CH1-14.mdb)を開きます。mws(0).QueryDefs("qryWorkOrderDetails")では、クエリコレクションから引数で指定したクエリオブジェクトを取得します。qdf(0) = Me.WoIDでは、qryWorkOrderDetailsWoIDに抽出条件を設定しています。QueryDefOpenRecordsetメソッドで、qryWorkOrderDetailsを開いたら、レコードセットオブジェクトをサブフォームsfrWorkOrderDetailsRecordsetプロパティに設定します。これでサブフォームのデータシートには、メインフォームのWoIDと連動する作業明細が表示されます。WorkspaceBeginTransメソッドで、トランザクション処理の開始を宣言したら、mfInTransTrueをセットします。最後に、一括復元のコマンドボタンのEnabled(使用可能)プロパティをFalse(無効)に設定しておきます。このコマンドボタンは、サブフォームの明細行を更新/削除したときに有効になります。

 

 

Sub cmdUnDoWODetails_Click()イベントの処理

このイベントは、一括復元のコマンドボタンがクリックされたときに実行されます。このイベントでは、トランザクション処理が開始(BeginTransメソッドが実行)されているかどうか調べて、WorkspaceRollbackメソッドで変更されたレコードをBegineTransメソッド発行直前まで戻します。mfInTransFalseを設定したら、Sub Form_Currentを呼んでサブフォームのレコードを再表示します。

 

Sub Form_Unload()イベントの処理

このイベントは、フォームを閉じる処理が開始されたときに実行されます。このイベントでは、BeginTransメソッドが実行されているとき、WorkspaceCommitTransメソッドでレコードを強制的にディスクに書き込んでトランザクションを完了させます。Set mws = Nothingでは、新規に作成したWorkspaceオブジェクトを解放します。

 

 

リスト4-6-1

Option Compare Database

Option Explicit

 

Private mws As DAO.Workspace

Private mfInTrans As Boolean

 

Private Sub cmdUnDoWODetails_Click()

  If mfInTrans Then

    Me.Painting = False

    mws.Rollback

    mfInTrans = False

    Me.cboStaffID.SetFocus

    Call Form_Current

    Me.Painting = True

  End If

End Sub

 

Private Sub Form_Current()

  Dim db As DAO.Database

  Dim qdf As DAO.QueryDef

  Dim rs As DAO.Recordset

   

  If mfInTrans = True Then

    mws.CommitTrans

  End If

   

  Set mws = Nothing

  Set db = Nothing

  Set qdf = Nothing

  Set rs = Nothing

   

  Set mws = DBEngine.CreateWorkspace("mws", "Admin", "")

  Set db = mws.OpenDatabase(CurrentDb.Name)

  Set qdf = mws(0).QueryDefs("qryWorkOrderDetails")

  qdf(0) = Me.WoID

  Set rs = qdf.OpenRecordset

  Set Me.sfrWorkOrderDetails.Form.Recordset = rs

 

  mws.BeginTrans

  mfInTrans = True

  Me.cmdUnDoWODetails.Enabled = False

End Sub

 

Private Sub Form_Unload(Cancel As Integer)

  If mfInTrans = True Then

    mws.CommitTrans

  End If

  Set mws = Nothing

End Sub

 

Private Sub Form_Open(Cancel As Integer)

  Call SetAppTitle_FS("UnDo Multiple Records (C) " _

  & Year(Date) & " by Akio Kasai")

End Sub

 

 

Sub Form_AfterDelConfirm()イベントの処理

このイベントは、サブフォームのレコード削除を承認したときに実行されます。このイベントでは、メインフォームの一括復元コマンドボタンのEnabled(使用可能)プロパティをTrue(有効)に設定します。

 

 

Sub Form_BeforeUpdate()イベントの処理

このイベントは、サブフォームのレコードが更新されたときに実行されます。このイベントでは、サブフォームのWo.IDにメインフォームのWoIDを設定します。WoIDは、メインとサブフォームを関連付けるための主キーです。メインフォームに作成したサブフォームのリンク子フィールド/リンク親フィールドプロパティにWoIDを設定して、メインフォームと同じWorkspaceにサブフォームのレコードセットを開いたときは、Accessが自動的にサブフォームのWoIDを設定してくれます。ところが、サブフォームのレコードセットが、メインフォームと異なるWorkspaceで開かれているときは、サブフォームのWoIDをアプリ独自で設定する必要があります。尚、この処理は、サブフォームに新規レコードを追加するときのみ必要になります。

 

 

Sub Form_Dirty()イベントの処理

このイベントは、サブフォームのレコードが変更されたときに実行されます。このイベントでは、メインフォームの一括復元コマンドボタンのEnabled(使用可能)プロパティをTrue(有効)に設定します。

 

リスト4-6-2

Option Compare Database

Option Explicit

 

Private Sub Form_AfterDelConfirm(Status As Integer)

  Me.Parent.cmdUnDoWODetails.Enabled = True

End Sub

 

Private Sub Form_BeforeUpdate(Cancel As Integer)

  If IsNull(Me!WoID) Then

    Me.WoID = Me.Parent.WoID

  End If

  Call ReCalcHours

End Sub

 

Private Sub Form_Dirty(Cancel As Integer)

  Me.Parent.cmdUnDoWODetails.Enabled = True

End Sub

 

Private Sub 休憩時間_MouseDown( _

  Button As Integer, Shift As Integer, _

  X As Single, Y As Single)

  If Button = acRightButton Then

    Call PopUpTime_FS(Me.休憩時間)

  End If

End Sub

 

Private Sub 出勤時刻_MouseDown( _

  Button As Integer, Shift As Integer, _

  X As Single, Y As Single)

  If Button = acRightButton Then

    Call PopUpTime_FS(Me.出勤時刻)

  End If

End Sub

 

Private Sub 退勤時刻_MouseDown( _

  Button As Integer, Shift As Integer, _

  X As Single, Y As Single)

  If Button = acRightButton Then

    Call PopUpTime_FS(Me.退勤時刻)

  End If

End Sub

 

Private Sub ReCalcHours()

  就労時間 = ElapsedHours_FS( _

    TimeValue(ElapsedTime2_FS(出勤時刻, 退勤時刻)) _

    - 休憩時間, 15)

  残業時間 = IIf(就労時間 > 8, 就労時間 - 8, 0)

End Sub

 

ダウンロード (CH4-6.lzh)
Accessお手本データベースのホームへ戻る