Saving changes to a multivalued ComboBox via AuditTrail

送分小仙女□ 提交于 2019-12-24 14:30:38

问题


I have a Access 2010 Database using a multivalued field (the Access inbuilt way to have m:n-relation between two tables).
To keep track of changes to the database I use an AuditTrail VBA procedure every time the corresponding form is updated, saving all the changes to history table.

Now, when I change the value of the ComboBox and the loop reaches the ComboBox bound to the multivalued field, the procedure throws an error because of incompatible Data types:

    For Each ctl In Screen.ActiveForm.Controls
    If ctl.Tag = "History" Then
        If Nz(ctl.Value) <> Nz(ctl.OldValue) Then
            With rst
                .AddNew
                ![timestamp] = datTimeCheck
                ![UserName] = strUserID
                ![FormName] = Screen.ActiveForm.Name
                ![recordid] = Screen.ActiveForm.Controls(IDField).Value
                ![FieldName] = ctl.ControlSource
                ![beforeValue] = ctl.OldValue
                ![afterValue] = ctl.Value
                .Update
            End With
        End If
    End If
Next ctl

How do I get the actual Value and the OldValue from a combobox converted to string in VBA?

I tried combobox.focus and then combobox.Text This works, but doesnt help with the OldValue problem.

How to properly use the value and oldvalue property of comboboxes? The official VBA object reference for comboboxes doesn't help at all. https://msdn.microsoft.com/en-us/library/office/ff821691.aspx


回答1:


It is not an elegant solution, only a quick & dirty workaround:

Modify your code so that it checks differently ComboBox1 and the other controls. The .Value and .OldValue are basically an array of variants.

Dim afterValue as variant
Dim beforeValue as Variant

For Each ctl In Screen.ActiveForm.Controls
    If ctl.Tag = "History" Then
        If Ctl.name = "ComboBox1" then
           err.clear
           on error resume next
           I=0
           afterValue = ""
           beforeValue = ""
           while err=0
               '
               ' Throws an error if 'out of range', i.e. after the last value
               '
               afterValue = afterValue + Nz(Cstr(ComboBox1.Value(I))) + ";"
               beforeValue = beforeValue + Nz(Cstr(ComboBox1.OldValue(I))) + ";"

           wend
        else
           afterValue = ctl.Value
           beforeValue = Nz(ctl.OldValue)
        endif
        If Nz(ctl.Value) <> a$ Then
           With rst
              .AddNew
              ![timestamp] = datTimeCheck
              ![UserName] = strUserID
              ![FormName] = Screen.ActiveForm.Name
              ![recordid] = Screen.ActiveForm.Controls(IDField).Value
              ![FieldName] = ctl.ControlSource
              ![beforeValue] = beforeValue
              ![afterValue] = afterValue
              .Update
           End With
        End If
    End If
Next ctl



回答2:


When ctl references a multi-valued combo box with at least one item selected, your test condition ...

Nz(ctl.Value) <> Nz(ctl.OldValue)

... will certainly throw a type mismatch error. In that situation, ctl.Value is actually a variant array, and Nz() can't cope with it. The problem is essentially the same as this ...

Debug.Print Nz(Array(1,2,3)) '<- type mismatch error

Perhaps you would prefer to grab a string of the concatenated combo selections ...

Debug.Print Join(ctl.Value, ",")

If that seems useful, beware that ctl.Value will be Null when none of its items is selected. And attempting to Join() Null will also trigger type mismatch error.

Note those issues also apply to ctl.OldValue.

But there may be yet another complication. Based on my testing I'm skeptical whether OldValue is reliable for a multi-valued combo box. If you also find that to be the case, use the form's current event to store the combo's initial selections in a form level variable and reference that variable (instead of OldValue) in your audit procedure.



来源:https://stackoverflow.com/questions/35224669/saving-changes-to-a-multivalued-combobox-via-audittrail

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!