#559 データの変更前後の値をログ出力する方法 フォーム、VBA

フォームでデータが変更されたとき、その変更前と変更後の値をログ用のテーブルに出力する方法です。

  1. ここではまず、例として次のような構造のログ用のテーブルを用意します。テーブル名は「商品変更履歴」、ログの対象は「標準原価」と「表示価格」フィールドの変更前後の値です。
    ログテーブルのデザイン

  2. 次に、「商品」というテーブルをソースとする下図のようなフォームを用意します。
    フォームのデザイン
    フォームの実行画面

  3. このフォームの「BeforeUpdate/更新前処理」イベントプロシージャを次のようにします。

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    'フォームのレコードの更新前処理

      Dim dbs As Database
      Dim rst As Recordset

      '変更前後の値をログ用テーブルに追加
      Set dbs = CurrentDb
      Set rst = dbs.OpenRecordset("商品変更履歴", , dbAppendOnly)
      With rst
        .AddNew
          !商品ID = Me!商品ID
          !標準原価変更前 = Me!標準原価.OldValue
          !表示価格変更前 = Me!表示価格.OldValue
          !標準原価変更後 = Me!標準原価
          !表示価格変更後 = Me!表示価格
        .Update
        .Close
      End With

    End Sub


ここでは、「OldValue」プロパティによって変更前の値を、また「Value」プロパティ(コード上は省略しています)によって変更後の値を取得しています。
「OldValue」には、そのレコードを編集し始める前の値、すなわち前回レコードが保存されたときの値が格納されています。また「Value」には最終的にレコード保存される値が格納されています。したがって、フォームの更新前処理イベントを使っていることもありますが、レコード編集中に何度データを書き換えても、その途中経過まではログに出力されません。あくまでもレコード単位の編集前後の値がログ出力されるだけです。

なお、このような処理は「AfterUpdate/更新後処理」イベントでも良さそうですが、更新後のタイミングでは「OldValue」の値が「Value」の値で置き換えられてしまいます。つまり両者が同じ値になってしまい、もはや変更前の値を取得できません。

また、結果的には変更前と変更後が同じ値であったとしても、一時的に何らかの変更を加えることで更新前処理イベントが発生するため、前後が同じ値としてログに保存されます。そのような場合は保存しないようにするには、事前に「OldValue」と「Value」を比べ、違いがあったときだけログ出力を実行するような分岐処理を加える必要があります。


実行例:
変更前の画面

標準原価を¥1,760→¥1,850に、表示価格を¥2,340→¥2,500に変更
標準原価と表示価格を変更

標準原価を¥980→¥1,000に、表示価格を¥1,300→¥1,350に変更
標準原価と表示価格を変更

実行後のログテーブル
実行後のログテーブル

※ここでは2つのフィールドのみをログの対象としていますが、このプログラムを応用すればいくつでもログ出力させることができます。
※また、Now関数やテーブルの既定値プロパティを使って「変更日時」を保存したり、何らかの方法(ログイン画面を用意したりネットワークユーザー名を取得したりするなど)でユーザー名を取得して「変更者」を保存したりすることもできます。


参考Tips:「#531 レコードの更新ログをとる例」
| Index | Prev | Next |



T'sFactory
Accessで動く生産管理DB
Ureru Express
Webで使う販売顧客管理
Access開発&アドバイス
DB開発やテクニカルアドバイス
Copyright © T'sWare All rights reserved