MS Access 表单在表查询完成之前打开
在我的访问数据库中,我有 TABLE1,它是 SQL 2005 服务器表的链接表。我有一个查询 QUERY1,它选择 TABLE1 的子集,操作/格式化其中的一些数据,并将该数据放入临时表 TMP_TABLE1 中(即 SELECT * INTO [TMPTABLE1] FROM [TABLE1])。我还有一个表单 FORM1,它以 TMP_TABLE1 作为其记录源,我可以在其中查看和操作数据。
以下是完成这些任务的代码:
On Error Resume Next
DoCmd.DeleteObject acTable, "TMPTABLE1"
On Error GoTo 0
DoCmd.SetWarnings False
CurrentDb.Execute "QUERY1", dbSeeChanges
DoEvents
DoCmd.SetWarnings True
DoCmd.OpenForm "FORM1", acNormal, , , , acDialog
我遇到的问题是,我的 FORM1 尝试在 QUERY1 完成处理之前打开,并且收到一条错误消息,指出我的表不存在。我一直将 CurrentDb.Execute 作为同步查询进行体验,并且最近才遇到这种行为。如果我在打开表单之前短暂暂停或循环等待创建表,我的程序将正常工作。
不幸的是,这只是我无法解决的根本问题的一个例子。例如,即使我保留临时表并简单地删除所有记录并附加所有新记录,问题仍然存在。当我在屏幕上显示数据之前操作代码中的数据时,例如 INSERT 语句、UPDATE 语句、DAO.Recordset 和 ADODB.Recordset 对象,都会发生这种情况。
我已经在 Windows 7 64 位、Windows Vista 32 位和 Windows XP 32 位上测试了已编译和未编译的客户端,所有反应都相同。该问题是间歇性的,有时查询会很快完成,我的表单会正确打开,但 90% 的情况下无法打开。
有人对我能做什么有什么想法吗?也许更改了设置以以不同的方式运行查询?这可能是我需要更改的 SQL Server 2005 选项/设置吗?
编辑: 下面是我能想到的最详细的代码,尝试等待表准备好,但它仍然失败。有时,我的执行过程会抛出一个错误,指出 TMPTABLE1 已经存在,即使我在函数开始时将其删除:
On Error Resume Next
DoCmd.DeleteObject acTable, "TMPTABLE1"
On Error GoTo 0
Dim wrk As DAO.Workspace
Set wrk = DBEngine.Workspaces(0)
Dim dbs As DAO.Database
Set dbs = CurrentDb
wrk.BeginTrans
On Error GoTo TransErr
dbs.Execute "QUERY1", dbSeeChanges Or dbFailOnError
wrk.CommitTrans
TransResume:
Dim waitLoop As Long
Do While TableDefExists("_working_ReceivedMaterials") = False
waitLoop = GetTickCount
Do While GetTickCount < waitLoop + 100
DoEvents
Loop
Loop
DoCmd.OpenForm "ReceivedMaterials_Entry", acNormal, , , , acDialog
Exit Function
TransErr:
wrk.Rollback
GoTo TransResume
In my access database I have TABLE1 which is a linked table to a SQL 2005 server table. I have a query QUERY1 which selects a subset of TABLE1, manipulates / formats some of its data, and places that data into temporary table TMP_TABLE1 (ie. SELECT * INTO [TMPTABLE1] FROM [TABLE1]
). I also have a form FORM1 that has TMP_TABLE1 as its recordsource where I can view and manipulate the data.
Here is my code that accomplishes these tasks:
On Error Resume Next
DoCmd.DeleteObject acTable, "TMPTABLE1"
On Error GoTo 0
DoCmd.SetWarnings False
CurrentDb.Execute "QUERY1", dbSeeChanges
DoEvents
DoCmd.SetWarnings True
DoCmd.OpenForm "FORM1", acNormal, , , , acDialog
The problem I am having is that my FORM1 tries to open before my QUERY1 finishes processing and I get an error stating my table does not exist. I have always experienced CurrentDb.Execute as a synchronous query and have only recently run into this behaviour. If I place a short pause or a loop waiting for the table to be created before opening the form, my procedure will work correctly.
Unfortunately, this is just one example of the underlying problem which I can't remedy. For example, even if I keep the temporary table and simply delete all records and append all new records, the problem persists. This happens for any instances where I manipulate data in code before displaying it on screen such as INSERT statements, UPDATE statements, DAO.Recordset and ADODB.Recordset objects.
I have tested the compiled and uncompiled client on Windows 7 64-bit, Windows Vista 32-bit and Windows XP 32-bit and the all react the same way. The problem is intermittent and occasionally the query will finish quickly and my form will open correctly but 90% of the time it fails to open.
Does anyone have any ideas on what I can do? Maybe a setting got changed to run queries differently? Could it be a SQL Server 2005 option/setting I need to change?
EDIT:
Below is the most verbose code I could think of to try and wait for the table to be ready and it is still failing. Some times, my execute procedure throws an error saying that TMPTABLE1 already exists even though I delete it at the start of the function.:
On Error Resume Next
DoCmd.DeleteObject acTable, "TMPTABLE1"
On Error GoTo 0
Dim wrk As DAO.Workspace
Set wrk = DBEngine.Workspaces(0)
Dim dbs As DAO.Database
Set dbs = CurrentDb
wrk.BeginTrans
On Error GoTo TransErr
dbs.Execute "QUERY1", dbSeeChanges Or dbFailOnError
wrk.CommitTrans
TransResume:
Dim waitLoop As Long
Do While TableDefExists("_working_ReceivedMaterials") = False
waitLoop = GetTickCount
Do While GetTickCount < waitLoop + 100
DoEvents
Loop
Loop
DoCmd.OpenForm "ReceivedMaterials_Entry", acNormal, , , , acDialog
Exit Function
TransErr:
wrk.Rollback
GoTo TransResume
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有时,在删除表然后重新创建表时,Access 会显示奇怪的行为,因此我认为您的代码不会自行绊倒,我认为最好的解决方案是编辑表单并将记录集更改为空。然后在表单“On_Load”事件中设置记录集,例如:
Private Sub Form_Load()
Me.Recordset = "SELECT * FROM TMPTABLE1"
End Sub
或者,不要删除表,只需运行“DELETE FROM TMPTABLE1”,然后然后使用“INSERT INTO TMPTABLE1 SELECT * FROM TABLE1”代替 make table 查询
Access can display strange behaviour sometimes when deleting tables and then re-creating them, therefore I dont' think your code is tripping over itself, the best solution I think is to edit your form and change the recordset to nothing. Then on your forms "On_Load" event, set the recordset there e.g:
Private Sub Form_Load()
Me.Recordset = "SELECT * FROM TMPTABLE1"
End Sub
Alternatively, do not delete the table, just run "DELETE FROM TMPTABLE1" instead, and then instead of a make table query use "INSERT INTO TMPTABLE1 SELECT * FROM TABLE1"
您是否尝试
过在打开表单之前执行?
Have you tried to execute
Before opening the form?