我在MS Access 2010上遇到了一个令人沮丧的问题,在这个阶段我将其视为错误。在尝试了所有可能的解决方法后,我失去了主意,只能依靠您。
语境
具有25k行VBA和> 50个表格的Ms Access 2010巨大应用程序。它具有客户端服务器体系结构,其中包含编译的前端和网络上的Access后端。它连接到二十个不同的数据库(Oracle/SQL Server/Sybase IQ)。
问题
有时,当我将ADODB记录集分配给子窗体时,其数据未显示在绑定(bind)字段中。我到处都有#Name?
数据在那里。 我可以对其进行debug.print
,可以在Watches浏览器中看到它,可以在使用代码在记录集对象上循环的同时读取或操作它。它只是不出现在子窗体中。
它可以在几个月内完美地工作,突然间,一种表格将开始出现此问题,而没有任何明显的原因(即使在我没有更改的表格上也可能发生)。发生这种情况时,它将对所有用户都有效,因此这在前端accdb/accde中确实是错误的。
该问题与特定的DBMS/驱动程序无关。 Oracle或Sybase数据可能会发生这种情况。
我创建了自己的类,抽象了与ADO连接和查询有关的所有内容,并在各处使用了相同的技术。我有十分之几的表格基于它们,并且大多数都可以完美地工作。
我的应用程序的多个部分都存在这个问题,尤其是在具有许多子表单和代码的高度复杂的表单中。
在此主窗体上,有几个子窗体有此问题,而其他子窗体则没有。它们具有完全相同的参数。
编码
这就是我填充表单的记录集的方式:
Set RST = Nothing
Set RST = New ADODB.Recordset
Set RST = Oracle_CON.QueryRS(SQL)
If Not RST Is Nothing Then
Set RST.ActiveConnection = Nothing
Set Form_the_form_name.Recordset = RST
End If
用
Oracle_CON.QueryRS(SQL)
调用的代码是Public Function QueryRS(ByVal SQL As String, Optional strTitle As String) As ADODB.Recordset
Dim dbQuery As ADODB.Command
Dim Output As ADODB.Recordset
Dim dtTemp As Date
Dim strErrNumber As Long
Dim strErrDesc As String
Dim intSeconds As Long
Dim Param As Variant
If DBcon.state <> adStateOpen Then
Set QueryRS = Nothing
Else
DoCmd.Hourglass True
pLastRows = 0
pLastSQL = SQL
pLastError = ""
pLastSeconds = 0
Set dbQuery = New ADODB.Command
dbQuery.ActiveConnection = DBcon
dbQuery.CommandText = SQL
dbQuery.CommandTimeout = pTimeOut
Set Output = New ADODB.Recordset
LogIt SQL, strTitle
dtTemp = Now
On Error GoTo Query_Error
With Output
.LockType = adLockPessimistic
.CursorType = adUseClient
.CursorLocation = adUseClient
.Open dbQuery
End With
intSeconds = DateDiff("s", dtTemp, Now)
If Output.EOF Then
LogIt "-- " & Format(Now, "hh:nn:ss") & " | Executed in " & intSeconds & " second" & IIf(intSeconds = 1, "", "s") & " | Now rows returned."
Set QueryRS = Nothing
Else
Output.MoveLast
pLastRows = Output.RecordCount
LogIt "-- " & Format(Now, "hh:nn:ss") & " | Executed in " & intSeconds & " second" & IIf(intSeconds = 1, "", "s") & " | " & Output.RecordCount & " row" & IIf(Output.RecordCount = 1, "", "s") & " returned."
Output.MoveFirst
Set QueryRS = Output
End If
End If
Exit_Sub:
pLastSeconds = intSeconds
Set Output = Nothing
Set Parameter = Nothing
Set dbQuery = Nothing
DoCmd.Hourglass False
Exit Function
Query_Error:
intSeconds = DateDiff("s", dtTemp, Now)
strErrNumber = Err.Number
strErrDesc = Err.DESCRIPTION
pLastError = strErrDesc
MsgBox strErrDesc, vbCritical, "Error " & pDSN
LogIt strErrDesc, , "ERROR"
Set QueryRS = Nothing
Resume Exit_Sub
Resume
End Function
到目前为止我尝试过的事情
对于记录集,我尝试了所有可能的变体
.LockType = adLockPessimistic
.CursorType = adUseClient
.CursorLocation = adUseClient
处理记录集的子表单具有所有
Snapshot
记录集类型,如果尝试dynaset
,问题仍然存在。数据输入,添加,删除,编辑均被禁用。它是纯只读的。
我习惯于使用
RST.ActiveConnection = Nothing
断开记录集的连接,以便以后可以对其进行操作,但这也不会影响问题。它可以通过非常简单的查询而发生,仅在
SELECT
子句中只有一个字段,而在子表单上只有一个字段绑定(bind)到该字段。将所有对象重新导入到新的accdb中也无法解决问题。
random_answer_guy提出的解决方案乍一看有效,它可以证实错误假设。不幸的是,在主要形式进行了一些(完全无关)更改之后,我的问题再次出现。我回来了4或5个子窗体,它们不显示数据,并且在全部或部分子窗体上添加/删除Load事件不再有任何区别
如果您想了解有关此问题有多奇怪的更多信息,建议您阅读有关random_answer_guy答案的评论。
总结一下
令人非常沮丧的是,我可以拥有两种具有完全相同的属性和相同的字段,相同的SQL指令,相同的DB,相同的记录集管理代码的两种不同形式:一种显示数据,而另一种不显示数据!
当问题发生时,我别无选择,只能删除所有操作过的对象,并从旧版本重新导入它们,或从头开始重新创建它们。
如果这不是一个bug,我仍在寻找合适的词来限定它。
是否有人遇到过该问题并提出了解释和/或解决方法?
最佳答案
我之前也遇到过同样的问题,只需添加一个空白的Form_Load
事件即可解决该问题。不需要与Form_Load
一起使用任何代码,只需将其存在即可。
关于sql - ADO Recordset数据未显示在窗体上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38614530/