Access JumpStart 2.0 | Blog

A Rapid Development Framework for Microsoft Access

This one is broken because I am not looping through the fields to get the correct object set up and I had hard coded the Dictionary entry with the index “TestText”

Me – yesterday

I am also seeing that my test isn’t actually doing what I want.

The test is using the functions to change the fields, but the functions each save the form by setting Form.Dirty = False after each change. Access is going to run multiple BeforeUpdate Events for the form, one for each Form.Dirty = False. So I will need to change my function. Rather than refactor anything outside my test, I’ll just update the test code directly to make sure I’m doing this and I can refactor later.

Here’s my full test function before the change:

'@TestMethod("Verify Changes")
Private Sub WhenTwoTextFieldsChangeBeforeAndAfterValuesAreReturned()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As New Collection
    Dim TestTextChange As New AuditFieldChange, TestComboChange As New AuditFieldChange
    ChangeTestText "TextBeforeValue"
    ChangeTestCombo "ComboBeforeValue"
    Set testFormAuditor = New FormAuditor
    ChangeTestText "TextAfterValue"
    ChangeTestCombo "ComboAfterValue"
    Set testCollection = testFormAuditor.ListOfChanges
    Set TestTextChange = testCollection.Item(1).FieldChanges("TestText")
    Set TestComboChange = testCollection.Item(1).FieldChanges("TestCombo")
    Assert.IsTrue TestTextChange.OldValue = "TextBeforeValue" And TestTextChange.NewValue = "TextAfterValue" And TestComboChange.OldValue = "ComboBeforeValue" And TestComboChange.NewValue = "ComboAfterValue"
End Sub

I am going to change these lines in the middle:

    ChangeTestText "TextBeforeValue"
    ChangeTestCombo "ComboBeforeValue"
    Set testFormAuditor = New FormAuditor
    ChangeTestText "TextAfterValue"
    ChangeTestCombo "ComboAfterValue"

And now the full test function looks like this:

'@TestMethod("Verify Changes")
Private Sub WhenTwoTextFieldsChangeBeforeAndAfterValuesAreReturned()
    Dim testFormAuditor As FormAuditor
    Dim testCollection As New Collection
    Dim TestTextChange As New AuditFieldChange, TestComboChange As New AuditFieldChange
    With NewForm
        .TestText "TextBeforeValue"
        .TestCombo "ComboBeforeValue"
        .Dirty = False
        Set testFormAuditor = New FormAuditor
        .TestText "TextAfterValue"
        .TestCombo "ComboAfterValue"
        .Dirty = False
    End With
    Set testCollection = testFormAuditor.ListOfChanges
    Set TestTextChange = testCollection.Item(1).FieldChanges("TestText")
    Set TestComboChange = testCollection.Item(1).FieldChanges("TestCombo")
    Assert.IsTrue TestTextChange.OldValue = "TextBeforeValue" And TestTextChange.NewValue = "TextAfterValue" And TestComboChange.OldValue = "ComboBeforeValue" And TestComboChange.NewValue = "ComboAfterValue"
End Sub

I updated the code within the added With block. This ensures the starting values, sets up the auditor to start listening to changes, then changes and saves the fields in one save. This will still fail because there won’t be a TestCombo entry yet due to my FormAuditor object not checking multiple fields. So now I’ll take a look at that function.

Oops, forgot to update the field lines above with an = operator, which I have now done, but the compiler caught me on it.

Now, my code inside the BeforeUpdate event is only checking for one field and adding one item to the collection:

Private Sub FormToAudit_BeforeUpdate(Cancel As Integer)
    If FieldChanged(FormToAudit.TestText) Then pListOfChanges.Add CreateAuditEventDetails
End Sub

But I need to loop through the controls and check multiple controls to see if they’ve changed so let’s add a loop to loop through all the controls:

Private Sub FormToAudit_BeforeUpdate(Cancel As Integer)
    Dim Fld As Variant, ChangeDictionary As Scripting.Dictionary
    For Each Fld In FormToAudit
        If FieldChanged(Fld) Then ChangeDictionary.Add CreateAuditFieldChange(Fld)
    Next Fld
    If ChangeDictionary.Count > 0 Then pListOfChanges.Add
End Sub

Now I have a loop and I updated the Field Changed to use an Access Control type object and am building the dictionary of changes through the loop. I had to modify things a bit because I was calling the CreateAuditEventDetails multiple times in the loop and I only want to call that once per BeforeUpdate Event. Next time I should be able to finish this off by updating the CreateAuditEventDetails to accept a FieldChanges dictionary and return the object.