Microsoft Access 掲示板

テキストボックス内データ変更時の処理

4 コメント
views
4 フォロー

お世話になっております。

ACCESS入力フォーム(分割フォーム)に、いくつか配置された入力・更新用TXTBOXがあります。
テキストボックス内データが変更されていれば『常に』、そのテキストボックスの枠を赤太線に。変更されていないものは黒細線にする。(変更が解除されたり、変更が保存されたら黒線に戻す。)という動きを望んでいます。
TXTBOXはすべて部品マスタと連結されてます。

ただいま、下記のようなプログラムを使用しています。

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Dim CtlObj As Control

  For Each CtlObj In Me.Controls
    If CtlObj.ControlType = acTextBox Then
    'フォーム内Objのうち、TXTBOXのみを抽出'
      If CStr(Nz(CtlObj.Value, "")) = "" Then
      Else  'Nullや空白は、保存時に自動で「-」に変更できるから無視'

        If CStr(Nz(CtlObj.Value, "")) = CtlObj.OldValue Then
          CtlObj.BorderColor = RGB(89, 89, 89)'普段は'
          CtlObj.BorderWidth = 1              '黒細線'
        Else
          CtlObj.BorderColor = RGB(255, 0, 0) 'データ変更時は'
          CtlObj.BorderWidth = 2              '赤太線'
        End If
      End If
    End If
  Next
End Sub

これを動かした場合、枠線の色は変わるっちゃ変わるんですが、
データ変更したTXTBOXからフォーカスを外して、分割フォームのテーブル側にマウスを動かして、そのあとにもう一回、データを変更したTXTBOXをクリックしないと、線が変わってくれませんでした。

また、同フォーム内に、変更を確定するボタン(基本常にTrueなForm_BeforeUpdate(Cancel As Integer)を一瞬falseにしてacCmdSaveRecordする)や、変更を取り消すボタン(Me.DirtyだったらMe.Undoする)があるのですが、これらを押して、Dirtyを消したつもりでも、線の色が変わってくれません(上記のように、マウスを動かして、またクリックしてとしないとダメ)。

イベントのタイミングが悪いのかな、とも思いましたが、常にDirtyの是非を問い続けるのはやり方もわかりません。また、できたとしても処理も重そうなので、何かいいアイデアがないかと思っております。

ゲッキョク駐車場
作成: 2020/05/28 (木) 14:09:16
通報 ...
1
hiroton 2020/05/28 (木) 14:39:17 f56bb@f966d

よくわからないんですが、その入力・更新用テキストボックスの更新後処理や、変更の確定ボタン、取り消しボタンのクリック時に実行するんじゃダメなんですか?

2
ゲッキョク駐車場 2020/05/28 (木) 14:56:20 cb55f@f6500 >> 1

hiroton さん
ありがとうございます。
変更の確定・取消ボタンおよび、レコード移動ボタンや、フォームを閉じるボタン等のクリック時イベントに、MsgBoxでデータが変更されている旨を表示するようにはしていますが、ドコソコのデータが変更されてるヨ。とは表示していません(僕のスキル的にまだできていません)。
入力フォームといっても、閲覧だけするユーザーも開く「閲覧入力兼用フォーム」であるので、閲覧ユーザーが誤ってデータを書き換えてしまったとき用に、どこのデータが書き換わっちゃってるのか、を明示したかったのです。
(データ変更されてるとき、レコード移動やフォームを閉じようとした際、確定または取消を押下しないとレコード移動等ができないようにしています)

レコード移動時などにMSGBOXで「●●TXTBOXが書き換わってます」とメッセージを出すより、視覚的にどこのデータが変更されてるか、わかりやすい方が良いと判断しまして、今回の質問に至りました。(フォームを使う人の中にはACCESSに明るくなかったり、年配の方も多いので)

3

下記のような感じでどうでしょうか。

変更の確定コマンドボタン
名前 cmdSave

取消コマンドボタン
名前 cmdUndo

フォームモジュール

Private Sub cmdSave_Click()
    Me.BeforeUpdate = ""
    DoCmd.RunCommand acCmdSaveRecord
    Me.BeforeUpdate = "[イベント プロシージャ]"
End Sub

Private Sub cmdUndo_Click()
    If Me.Dirty Then
        Me.Undo
    End If
End Sub

Private Sub Form_AfterUpdate()
    Call InitTextbox
End Sub

Private Sub Form_BeforeUpdate(Cancel As Integer)
    Cancel = True
End Sub

Private Sub Form_Undo(Cancel As Integer)
    Call InitTextbox
End Sub

Public Sub InitTextbox()
    'テキストボックス初期化
    Dim CtlObj As Control
    For Each CtlObj In Me.Controls
        If CtlObj.ControlType = acTextBox Then
            CtlObj.BorderColor = RGB(89, 89, 89) '普段は'
            CtlObj.BorderWidth = 1              '黒細線'
        End If
    Next
End Sub

'テキストボックスの更新後処理に設定する関数
Private Function Textbox_Update()
    With Me.ActiveControl
        If Nz(.Value) = Nz(.OldValue) Then
            .BorderColor = RGB(89, 89, 89) '普段は'
            .BorderWidth = 1              '黒細線'
        Else
            .BorderColor = RGB(255, 0, 0) 'データ変更時は'
            .BorderWidth = 2              '赤太線'
        End If
    End With
End Function

フォームのデザインビューで、入力用のテキストボックスをすべて選択して、
「更新後処理」プロパティに =Textbox_Update() と設定。

4
ゲッキョク駐車場 2020/05/28 (木) 17:11:57 cb55f@f6500 >> 3

ありがとうございます!希望通りの動きになりました!
Form_BeforeUpdate(Cancel As Integer) で Cancel = True としているので
更新後処理も使えないものだと思っていました。

TXTBOXの数も多く、1つ1つ設定するのもアレでしたし、
今回の物では標準モジュールも使わなくて済み、わかりやすいプログラムで助かりました!
ありがとうございます。😃