通过 AuditTrail 保存对多值 ComboBox 的更改
Saving changes to a multivalued ComboBox via AuditTrail
我有一个使用多值字段的 Access 2010 数据库(Access 内置方式在两个 table 之间建立 m:n 关系)。
为了跟踪对数据库的更改,每次更新相应的表单时我都使用 AuditTrail VBA 过程,将所有更改保存到历史记录 table.
现在,当我更改 ComboBox 的值并且循环到达绑定到多值字段的 ComboBox 时,由于数据类型不兼容,该过程会引发错误:
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
如何从组合框中获取实际的 Value
和 OldValue
并将其转换为 VBA 中的字符串?
我尝试了 combobox.focus
然后 combobox.Text
这有效,但对 OldValue
问题没有帮助。
如何正确使用组合框的value
和oldvalue
属性?组合框的官方 VBA 对象参考根本没有帮助。
https://msdn.microsoft.com/en-us/library/office/ff821691.aspx
这不是一个优雅的解决方案,只是一个快速而肮脏的解决方法:
修改您的代码,使其以不同方式检查 ComboBox1 和其他控件。
.Value
和 .OldValue
基本上是一个变体数组。
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
当ctl
引用一个多值组合框且至少选择了一项时,您的测试条件...
Nz(ctl.Value) <> Nz(ctl.OldValue)
...肯定会抛出类型不匹配的错误。在那种情况下,ctl.Value
实际上是一个变体数组,Nz()
无法应对。问题本质上和这个是一样的...
Debug.Print Nz(Array(1,2,3)) '<- type mismatch error
也许您更愿意获取一串串联的组合选择...
Debug.Print Join(ctl.Value, ",")
如果这看起来有用,请注意当 none 项被选中时 ctl.Value
将为空。并且尝试 Join()
Null 也会触发类型不匹配错误。
请注意,这些问题也适用于 ctl.OldValue
。
但可能还有另一个并发症。根据我的测试,我怀疑 OldValue
对于多值组合框是否可靠。如果您也发现是这种情况,请使用表单的当前事件将组合的初始选择存储在表单级变量中,并在您的审计过程中引用该变量(而不是 OldValue
)。
我有一个使用多值字段的 Access 2010 数据库(Access 内置方式在两个 table 之间建立 m:n 关系)。
为了跟踪对数据库的更改,每次更新相应的表单时我都使用 AuditTrail VBA 过程,将所有更改保存到历史记录 table.
现在,当我更改 ComboBox 的值并且循环到达绑定到多值字段的 ComboBox 时,由于数据类型不兼容,该过程会引发错误:
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
如何从组合框中获取实际的 Value
和 OldValue
并将其转换为 VBA 中的字符串?
我尝试了 combobox.focus
然后 combobox.Text
这有效,但对 OldValue
问题没有帮助。
如何正确使用组合框的value
和oldvalue
属性?组合框的官方 VBA 对象参考根本没有帮助。
https://msdn.microsoft.com/en-us/library/office/ff821691.aspx
这不是一个优雅的解决方案,只是一个快速而肮脏的解决方法:
修改您的代码,使其以不同方式检查 ComboBox1 和其他控件。
.Value
和 .OldValue
基本上是一个变体数组。
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
当ctl
引用一个多值组合框且至少选择了一项时,您的测试条件...
Nz(ctl.Value) <> Nz(ctl.OldValue)
...肯定会抛出类型不匹配的错误。在那种情况下,ctl.Value
实际上是一个变体数组,Nz()
无法应对。问题本质上和这个是一样的...
Debug.Print Nz(Array(1,2,3)) '<- type mismatch error
也许您更愿意获取一串串联的组合选择...
Debug.Print Join(ctl.Value, ",")
如果这看起来有用,请注意当 none 项被选中时 ctl.Value
将为空。并且尝试 Join()
Null 也会触发类型不匹配错误。
请注意,这些问题也适用于 ctl.OldValue
。
但可能还有另一个并发症。根据我的测试,我怀疑 OldValue
对于多值组合框是否可靠。如果您也发现是这种情况,请使用表单的当前事件将组合的初始选择存储在表单级变量中,并在您的审计过程中引用该变量(而不是 OldValue
)。