提问人: 提问时间:12/29/2008 最后编辑:10 revs, 3 users 70%Andrew G. Johnson 更新时间:5/27/2015 访问量:1971
字符串在 MSAccess 的 VBA 代码的 For Each 循环中异常行为
String acting abnormally in a For Each loop in VBA code in MSAccess
问:
好的,所以我从一个问题开始,并根据这个网站和其他网站的建议对代码进行了大量更改,所以我想我应该创建一个新问题。
尽管我的代码更短、更高效,但同样的问题仍然存在;我正在使用一个名为 strSQL 的字符串,其中包含我想要执行的 INSERT 语句。我有一个 FOR EACH 循环,它遍历我的 MSAcess 窗体上的每个控件(确保它们是文本框、下拉列表或复选框)并确定字段是否已更改。如果有,它会生成一个查询字符串来记录更改,并将其存储在 strSQL 中。
问题在于,同一个查询被一次又一次地执行。我添加了一个 DEBUG。执行查询字符串的行之前和之后的 PRINT 语句,调试器显示字符串已更改!是的,你没看错,这似乎是不可能的,但我已经截屏了。
首先是我的代码:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim C As Control
For Each C In Controls
Select Case C.ControlType
Case acTextBox, acComboBox, acCheckBox
Dim strOriginalValue, strCurrentValue, strSQL As String
strOriginalValue = IIf(IsNull(C.OldValue), "", IIf(C.OldValue = vbTrue Or C.OldValue = vbFalse, IIf(C.OldValue = vbTrue, "Yes", "No"), C.OldValue))
strCurrentValue = IIf(IsNull(C.Value), "", IIf(C.Value = vbTrue Or C.Value = vbFalse, IIf(C.Value = vbTrue, "Yes", "No"), C.Value))
If strOriginalValue <> strCurrentValue Then
strSQL = "INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'" & ThisUserName() & "','Edit'," & [id] & ",0,'" & C.ControlSource & "','Administrator','" & Replace(strOriginalValue, "'", "") & "','" & Replace(strCurrentValue, "'", "") & "')"
Debug.Print "Before: " & strSQL
CurrentDb.Execute strSQL, dbFailOnError
Debug.Print "After: " & strSQL
End If
End Select
Next
End Sub
下面是调试器的结果:
Before: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'indoor_performers_tab','Administrator','No','Yes')
After: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'indoor_performers_tab','Administrator','No','Yes')
Before: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'volunteers_tab','Administrator','No','Yes')
After: INSERT INTO fringefestival_changes (change_time,change_admin,action_taken,user_affected,year_affected,field_affected,type_affected,old_value,new_value) VALUES (NOW(),'ajohnson','Edit',3,0,'volunteers_tab','Administrator','No','Yes')
其次,我的截图...首先是调试器:1 和 2,其次是结果:这里 -- 请注意,调试器太宽了,所以我截取了两张屏幕截图,结果有一行被涂掉了,因为它与这个问题无关。
请注意,在我给出的示例中,唯一应该不同的列应该是“field_affected”列。
我完全不知所措,我不知道为什么它会将正确的字符串输出到调试器并执行其他操作。
编辑:在使用CurrentDb.Execute之前,我使用的是DoCmd.RunSQL,但这需要我禁用然后重新启用警告。由于两者的结果相同(相同的错误),因此我使用了单行解决方案而不是三行解决方案。
更新:感谢 shahkalpesh 帮助我意识到数据确实被正确插入,我可以在 SQL Server 的 management studio 中看到它,但 MS Access 仍然错误地显示它......问题是为什么?
最终编辑:通过向表中添加标识/自动递增整数列来修复,我怀疑缺少不同的字段值使 MSAccess 感到困惑(尽管它确实没有理由)——这里的士气是 M$ 是愚蠢的
答:
有问题的表单是否绑定到数据源?这是使用 Access 的最常见方式,如果是这样,您可能不需要通过 SQL 进行更新。
Form_BeforeUpdate() 通常在表单绑定到数据源时使用。通常不会使用此事件来确定控件的值是否已更改,是否需要写回数据库...
评论
您对 currentdb(我假设是 access-db)运行这些查询,但实际上使用的是您希望发生更改的 SQL Server 数据库?
sql Server 中的这些表是否链接到 access-db 中的表,或者您使用的是什么方法?
评论
您是否检查过表中是否有损坏的触发器?这是一个很长的镜头,但一些非常非常奇怪的问题是由之前坏/损坏的触发器引起的,在你注意到触发器之前,它们很难理解......
评论
如果可以转到特定的SQL Server表(使用查询分析器或Enterprise Mgr),并查看它是否按预期工作。我怀疑VBA中的链接表可能会向您显示不正确的图片。
编辑:如果您有 SQL 事件探查器,请查看那里正在执行的内容,以确认您对执行同一查询的怀疑。
评论
啊,你也在使用 SQL Server。我很幸运地使用触发器来审核 Access 背后的数据更改。有几个怪癖,但是使用受信任的身份验证通过 ODBC 链接表非常容易。
好的,所以你不能或不想使用触发器。使用 Access 前端 SQL 时,我通常在 VBA 代码中使用 ADO 对象来执行此类操作。带有 ODBC 的链接表非常适合绑定表单,但没有什么比 ADO 更适合直接转到 SQL Server。
您是否希望了解有关使用受信任的身份验证链接表的详细信息,或者有关使用 ADO 执行 SQL Server 工作的帮助?
通过向更改表添加自动递增的整数主键列来修复。
傻傻的存取...
评论
我不得不说,围绕这个问题的讨论让我发疯。使用 ODBC 链接表时,可以从绑定表单开始。根本没有理由使用池连接。如果您对如何执行这些操作的 Access 实现怀有敌意,请停止使用 ACCESS。
评论