2015-07-10 78 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