Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1529

Changed Class (Keep track of the "dirty" status of your data).

$
0
0
Edit: I made a couple dumb errors in the Demo and fixed them. They weren't important to the point of the Demo so you don't have to download the new ZIP if you don't want to.

cChanged Demo.zip


This is a Changed Class I wrote and use in all my applications that can save data. The reason I wrote it is because I could use the Changed Event in any given control to do whatever but the problem is that if you have multiple ways to get to the same thing (I'll explain that next) then you start triggering a whole lot of changed events and depending on how many different systems you have on one form it can cause a lot of flickering of buttons and such if you want to use Changed to enable/disable controls.

E.g. mnuFileSave is Disabled if nothing is changed.

Multiple ways means maybe you have a Customer form that's a front-end to a database. You have the normal four arrow keys - First, Last, Previous, Next. When you click one of those you reposition the recordset. There's also a ComboBox on the form with a list of customer names. When you reposition, the ComboBox displays the current customer.

But... you can also reposition the recordset by selecting a customer from the ComboBox which triggers the ComboBox again. This is a whole different problem but the way I solved it was in the Reposition Event (after prompting user to save record if applicable), Changed is first checked to see if it's disabled. If it is, the code skips out. If it's not then it Disables it and carries on. There are other ways to prevent unintentional recursive events but that's how I handled it.

I wrote up a demo program that is attached. This is just the cChanged Class code. Ignore the debug stuff. In the sample program I just put in dummy subs to handle that so I don't have to maintain two versions of the code.

Code:


Option Explicit


' Changed Property is Default Member of this Class.



' // Events.


Public Event Changed() ' Raises Event (Changed) when Set. Does not Fire when Changed Object is Disabled.


' // Events.



' // Constants, Enums and Types.


Private Const NAME As String = "cChanged"

Public Enum CHANGED_STATUS ' The Status Changed can have: Changed (Checked), Indeterminate (Grayed) or Unchanged (Unchecked).

  idx_ChangedStatusIsChanged = vbChecked      ' 1
  idx_ChangedStatusIsIndeterminate = vbGrayed ' 2
  idx_ChangedStatusIsUnchanged = vbUnchecked  ' 0

End Enum


' // Constants, Enums and Types.



' // Properties.


Private nChanged As CHANGED_STATUS            ' Manages "Dirty" status of record.
Private fEnabled As Boolean                  ' Sets Changed Status to idx_ChangedIndeterminate when Disabled = True.  Restores previous Changed Status.  Previous Changed Status must be Changed or Unchanged.
Private nPriorChangedStatus As CHANGED_STATUS ' Saves Changed Status immediately before Changed is Disabled.


' // Properties.


Public Property Get Changed() As CHANGED_STATUS


If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Changed(Public Property Get)"

Changed = nChanged

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Public Property Let Changed(ByVal DataChanged As CHANGED_STATUS)

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Changed(Public Property Let)"

If Not fEnabled Then GoTo CleanUp

nChanged = DataChanged

RaiseEvent Changed

CleanUp:

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Public Function DestroyObjects() As Long

' Returns Error Code.

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".DestroyObjects(Public Function)"

' Dummy sub.

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Function
Public Property Get Enabled() As Boolean

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Enabled(Public Property Get)"

Enabled = fEnabled

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Public Property Let Enabled(ByRef EnableChanged As Boolean)

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Enabled(Public Property Let)"

If EnableChanged = False Then ' Save current Changed Status if Changed Object is going to be disabled.

  SavePriorChangedStatus EnableChanged

Else

 RestoreChangedStatus EnableChanged ' Restore Saved Changed Status if Changed Object is being Enabled.

End If

fEnabled = EnableChanged

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Private Property Get PriorChangedStatus() As CHANGED_STATUS

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".PriorChangedStatus(Private Property Get)"

PriorChangedStatus = nPriorChangedStatus

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Private Property Let PriorChangedStatus(ByRef ChangedStatus As CHANGED_STATUS)

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".PriorChangedStatus(Private Property Let)"

nPriorChangedStatus = ChangedStatus

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Property
Private Sub RestoreChangedStatus(ByRef EnableStatusChange As Boolean)

' This Sub should only be called when Disabled is being set to False.  E.g. Changed.Disabled = False
' This Sub is called *Before* the actual Status of Disabled is Changed.
' Restores Changed Status to what it was before Changed was Disabled.

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".RestoreChangedStatus(Private Sub)"

If (fEnabled = True) Or (EnableStatusChange = False) Then GoTo CleanUp

nChanged = PriorChangedStatus

CleanUp:

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Sub
Private Sub SavePriorChangedStatus(ByRef EnableStatusChange As Boolean)

' This Sub should only be called when Disabled is being set to True.  E.g. Changed.Disabled = True
' This Sub is called *Before* the actual Status of Disabled is Changed.
' Current Changed Status is Saved when Changed is Disabled and Restored when Changed is Re-enabled.
' Changed Status is Set to idx_ChangedInderminate.

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".SavePriorChangedStatus(Private Sub)"

If (fEnabled = False) Or (EnableStatusChange = True) Then GoTo CleanUp ' Changed is currently Disabled so this should already be set.
                                                                      ' Or Status is being switched to Enabled.  See RestoreChangedStatus.
                                                             
If nChanged <> idx_ChangedStatusIsIndeterminate Then PriorChangedStatus = nChanged ' Only save idx_ChangedStatusIsChanged or idx_ChangedStatusIsUnchanged, but not idx_ChangedStatusIsIndeterminate

nChanged = idx_ChangedStatusIsIndeterminate ' Changed Status will always be idx_ChangedStatusIsIndeterminate if Changed is Disabled.

CleanUp:

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Sub
Private Sub Class_Initialize()

If DebugMode = idx_Debug_On Then CallStack.Add NAME & ".Class_Initialize(Private Sub)"

fEnabled = True ' On by default.  Otherwise every instance would need to enable its Changed object.
nPriorChangedStatus = idx_ChangedStatusIsIndeterminate

If DebugMode = idx_Debug_On Then CallStack.DeleteProcedureCall

End Sub

Attached Files

Viewing all articles
Browse latest Browse all 1529

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>