2015-07-10 70 views
0

使用的MS Access 2013:麻烦追加记录到MS Access ADO记录集 - 记录消失

我创建一个分离的ADO记录,以作为我正在写一个应用程序的内存中写入缓冲区。通常我会使用表/查询,但多人同时使用数据库。如果我将这些记录写入表格,则用户有可能会覆盖彼此的数据。

ADODB.recordset被定义为一个全局变量,并用函数初始化。现在,这是棘手的部分。我可以很好地定义记录集,但是当我添加第一个记录时,记录在添加后“消失”。

我使用While-Wend循环来添加记录。当我进入该循环的中间时,我可以移动到不同的记录,并调试任何我喜欢的值。但是当我退出这个循环时,我失去了所有的记录。无论我移动到何处,任何debug.print命令都会产生“无当前记录”。当我在其他函数中调用全局变量时,我得到一个空记录集。

下面的代码:

Option Compare Database 
'Establish a global recordset variable to be a write buffer 
Public gbl_rstADO_WriteBuffer As ADODB.Recordset 
Option Explicit 

Private Function InitWriteBuffer() 
Dim strSQL As String 
Dim dbs As DAO.Database 
Dim rst As DAO.Recordset 
Dim i As Integer 
Dim j As Integer 

'These records will form the structure and initial entries of the write buffer 
strSQL = "SELECT [#DEFAULT MASTER QUERY].* FROM [#DEFAULT MASTER QUERY] INNER JOIN " & _ 
"tblBatchCircuitUploadTable ON [#DEFAULT MASTER QUERY].[Install ID] = " & _ 
"tblBatchCircuitUploadTable.[Install ID] WHERE (((tblBatchCircuitUploadTable.[Install ID]) Is Not Null));" 

Set dbs = CurrentDb 
Set rst = dbs.OpenRecordset(strSQL) 


Set gbl_rstADO_WriteBuffer = New ADODB.Recordset 

'Create detatched recordset using fields from SQL query 
For i = 0 To rst.Fields.Count - 1 
    gbl_rstADO_WriteBuffer.Fields.Append rst.Fields(i).Name, adVariant, , adFldMayBeNull 
Next 

With gbl_rstADO_WriteBuffer 
    .CursorType = adOpenKeyset 
    .CursorLocation = adUseClient 
    .LockType = adLockPessimistic 
    .Open 
End With 


rst.MoveFirst 

'Copy values from DAO recordset, one-by-one, into the detatched ADO recordset 
While Not rst.EOF 
    gbl_rstADO_WriteBuffer.AddNew 

    'Move through values of current source record, and copy one by one to ADO destination 
    For j = 0 To gbl_rstADO_WriteBuffer.Fields.Count - 1 
     gbl_rstADO_WriteBuffer.Fields(j).Value = rst.Fields(j) 
    Next 

    gbl_rstADO_WriteBuffer.Update 
    rst.MoveNext 
Wend 

    'With the following command I receive a "No Current Record" error 
    'Moving to first, last, etc in the immediate window all still produce "no current record" 
    Debug.Print gbl_rstADO_WriteBuffer.Fields(0).Value 



'Cleanup 
Set rst = Nothing 
Set dbs = Nothing 

End Function 

有谁看到什么我失踪?

+0

根据[Append Method(ADO)](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681564(v = vs.85).aspx),*“以下数据类型不被ADO支持,并且在将新字段附加到记录集对象(ADO)时不应使用:adIDispatch,adIUnknown,** adVariant **。“* – HansUp

+0

我认为这是一个过程而不是编程问题。为什么不使用临时表来快照数据集而无需用户交互?为什么不让应用程序在运行时调用ADO或ODBC记录集,而不是在后端数据库中保存内存?最后,考虑保存[记录集外部](https://msdn.microsoft.com/en-us/library/aa260348(v = vs.60).aspx)。 – Parfait

+1

*“通常我会使用表/查询,但多人同时使用数据库,如果我将这些记录写入表中,则有可能会覆盖对方的数据。”* - 不是您已经正确设置了多用户Access应用程序。每个用户必须拥有自己的前端(用户界面)本地副本,因此如果应用程序写入前端.accdb/.accde文件中的本地表,则用户将永远无法覆盖彼此的数据。 –

回答

1

非常感谢您的反馈!所有的要点都非常好。

就技术答案而言,HansUp认为:事实证明,您不能将adVariant数据类型附加到ADO记录集中。它不受支持。瘸。因此,如果您倾向于将记录从DAO记录集复制到ADO记录集中以便将其分离,则有助于将数据类型从一个映射到另一个的漂亮方式,重新创建ADO记录集。

这就是我想出了:

... 
For i = 0 To rst.Fields.Count - 1 
    intDataType = IDS_MapToTypeADO(rst.Fields(i).Type) 
    If intDataType = adVarWChar Then 
     gbl_rstADO_WriteBuffer.Fields.Append rst.Fields(i).Name, intDataType, 50, adFldMayBeNull 
    Else 
     gbl_rstADO_WriteBuffer.Fields.Append rst.Fields(i).Name, intDataType, , adFldMayBeNull 
    End If 
Next 

With gbl_rstADO_WriteBuffer 
    .CursorType = adOpenKeyset 
    .CursorLocation = adUseClient 
    .LockType = adLockPessimistic 
    .Open 
End With 
... 

Private Function IDS_MapToTypeADO(iTypeDB As Integer) As Long 

Select Case iTypeDB 

    'Fixed width adWChar does not exist 
    Case dbText: IDS_MapToTypeADO = adVarWChar 
    Case dbMemo: IDS_MapToTypeADO = adLongVarWChar 
    Case dbByte: IDS_MapToTypeADO = adUnsignedTinyInt 
    Case dbInteger: IDS_MapToTypeADO = adSmallInt 
    Case dbLong: IDS_MapToTypeADO = adInteger 
    Case dbSingle: IDS_MapToTypeADO = adSingle 
    Case dbDouble: IDS_MapToTypeADO = adDouble 
    Case dbGUID: IDS_MapToTypeADO = adGUID 
    Case dbDecimal: IDS_MapToTypeADO = adNumeric 
    Case dbDate: IDS_MapToTypeADO = adDate 
    Case dbCurrency: IDS_MapToTypeADO = adCurrency 
    Case dbBoolean: IDS_MapToTypeADO = adBoolean 
    Case dbLongBinary: IDS_MapToTypeADO = adLongVarBinary 
    Case dbBinary: IDS_MapToTypeADO = adVarBinary 
    Case Else: IDS_MapToTypeADO = adVarWChar 

End Select 

End Function 

这从另一个StackOverflow的解决方案在这里借用: Converting DAO Recordset to Disconnected ADO Recordset dbDecimal Issue

再次谢谢。我很感激!

+0

我很高兴你解决了你的问题。但我会怠慢,不要恳求你在这里转换你的数据处理过程。 Access等数据库不应该向应用程序发出数据请求,反之亦然。数据库必须存在并且与任何客户端离婚。抽象FrontEnd和后端进程非常重要。尽管整洁的方面可能会调用外部记录集内存中的内存可能是CPU资源的低效率使用。考虑在运行时将您的应用程序直接连接到实时临时表数据源。祝你好运! – Parfait