我正在尝试设置一个表单,以使用断开连接的ADODB.Recordset作为其来源 我遇到的问题是,在关闭表单并向提示回复“是”时,更改不保存到原始Access表中。我错过了什么?
注意:请不要告诉我这个方法没用,它只是一个带有本地表的POC,我打算稍后尝试使用更“遥远”的记录集。
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Private Sub Form_Load()
Set conn = New ADODB.Connection
conn.Open CurrentProject.Connection
Set rs = New ADODB.Recordset
With rs
rs.CursorLocation = adUseClient
rs.Open "select * from amsPor", conn, adOpenStatic, adLockBatchOptimistic
Set rs.ActiveConnection = Nothing
End With
Set Me.Recordset = rs
conn.Close
End Sub
Private Sub Form_Unload(Cancel As Integer)
Select Case MsgBox("Save changes ?", vbQuestion + vbYesNoCancel)
Case vbNo
'do nothing
Case vbYes
conn.Open CurrentProject.Connection
rs.ActiveConnection = conn
rs.UpdateBatch
rs.Close
conn.Close
Set conn = Nothing
Case vbCancel
Cancel = True
End Select
End Sub
重现步骤:
select
子句中的表名。 Record Source
属性。 编辑:我想知道问题是否可能出现在CurrentProject.Connection
?
在调试窗口中,我输入? CurrentProject.Connection
并获得以下内容:
Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=\\xxxxxx\yyyy$\Documents\AMS.accdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database=C:\Users\G828992\AppData\Roaming\Microsoft\Access\System.mdw;Jet OLEDB:Registry Path=Software\Microsoft\Office\14.0\Access\Access Connectivity Engine;Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=6;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=True;Jet OLEDB:Bypass UserInfo Validation=False
答案 0 :(得分:1)
我来到这里寻找与你相同的答案,经过大量的谷歌搜索和反复试验,我终于能够完成你正在尝试做的事情。我知道这是一个老帖子,但我没有看到任何答案,实际上提供了一个答案,允许你试图做的工作。我将使用您的示例并尝试应用我必须更改的内容并添加以使其正常工作。
Dim rs As ADODB.Recordset
Dim conn As ADODB.Connection
Private Sub Form_Load()
If CurrentProject.Connection.State = adStateOpen Then CurrentProject.Connection.Close
Set conn = New ADODB.Connection
conn.Open CurrentProject.Connection.ConnectionString
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open "select * from amsPor", conn, adOpenForwardOnly, adLockBatchOptimistic
If Not rs Is Nothing Then
If Not rs.ActiveConnection Is Nothing Then Set rs.ActiveConnection = Nothing
If Not (rs.eof And rs.BOF) Then
Set Me.Recordset = rs
End If
If conn.State = adStateOpen Then
conn.Close
End If
End If
Call AddNewRecord(Me.Recordset)
End Sub
Private Sub AddNewRecord(ByRef rs As ADODB.Recordset)
On Error Resume Next
If Not rs Is Nothing Then
If rs.Supports(adAddNew) Then
rs.AddNew
rs.Fields("FirstName").Value = "John"
rs.Fields("LastName").Value = "Doe"
If rs.Supports(adUpdate) Then rs.Update
End If
End If
If Err.Number <> 0 Then
Debug.Print "AddNewRecord Err Msg: " & Err.Description
Err.Clear
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
Select Case MsgBox("Save changes ?", vbQuestion + vbYesNoCancel)
Case vbYes
Call UpdateDbWithRS(Me.Recordset)
Case vbCancel
Cancel = True
Case Else
' Nothing.
End Select
End Sub
Private Sub UpdateDbWithRS(ByRef rs As ADODB.Recordset)
If Not rs Is Nothing Then
If CurrentProject.Connection.State = adStateOpen Then CurrentProject.Connection.Close
Set conn = New ADODB.Connection
conn.Open CurrentProject.Connection.ConnectionString
rs.ActiveConnection = conn
If rs.Supports(adUpdateBatch) Then
rs.UpdateBatch
If Not conn Is Nothing Then
If conn.State = adStateOpen Then conn.Close
Set conn = Nothing
End If
If Not rs Is Nothing Then
If rs.State = adStateOpen Then rs.Close
Set rs = Nothing
End If
End If
End If
End Sub
通过上面的代码,我能够添加 记录到我的记录集,并验证它没有显示在我的数据库表中。然后,当我执行 UpdateDbWithRS 时,我已添加到 Recordset 的记录,之前已被推送到我的数据库表。
我对代码所做的最大改变是将conn.Open CurrentProject.Connection
更改为conn.Open CurrentProject.Connection.ConnectionString
,添加代码If CurrentProject.Connection.State = adStateOpen Then CurrentProject.Connection.Close
以修复我收到的有关已经打开的连接的错误。然后我做的最后一个最大的改变是将adOpenStatic
的 CursorType 替换为adOpenForwardOnly
。我不确定最后一次更改是否真的需要,但我根据我在此Microsoft Support Site上找到的断开连接的RecordSet示例使用它。
答案 1 :(得分:0)
使用断开连接的记录集时,您无法获得自动更新表更改的好处。您需要实际运行SQL Update和插入语句来保存数据。
答案 2 :(得分:0)
首先,您的代码看起来很完美,也应该有效,但是......
解决方案1
根据我的经验,我建议忘记这些功能。几年前,我一直在努力解决同样的问题。我没有找到任何解决方案,但我几乎可以肯定多用户环境中使用的访问数据库无法更新,因为当其他用户同时进行更改时,Jet / ACE引擎不允许更新静态记录集(变更被拒绝)。
我使用&#34;临时表&#34;解决了这个问题。与形式结合:
DELETE * FROM ~TableName;
INSERT INTO ~TableName SELECT * FROM TableName;
用户可以编辑记录,直到打开表格。在 Form_Unload 事件中,我运行如下查询:
UPDATE t1 SET Field1 = t2.Field1,
Field1 = t2.Field2 ... and so on
FROM TableName As t1 INNER JOIN ~TableName AS t2 ON t1.Key = t2.Key
请注意,记录的插入和删除(如果允许)应单独处理。
<强>溶液2 强>
使用动态游标并且不会将记录集与数据库断开连接;) 使用Form.Dirty property抓住更改。
答案 3 :(得分:-4)
您的所有代码均与DISCONNECTED RECORDSETS无关。您的记录集已连接。断开连接的记录集可以作为xml或二进制文件保存到文件中。没有底层数据库。
注意我们制作断开连接的记录集。
Sub Randomise
Randomize
Set rs = CreateObject("ADODB.Recordset")
With rs
.Fields.Append "RandomNumber", 4
.Fields.Append "Txt", 201, 5000
.Open
Do Until Inp.AtEndOfStream
.AddNew
.Fields("RandomNumber").value = Rnd() * 10000
.Fields("Txt").value = Inp.readline
.UpDate
Loop
.Sort = "RandomNumber"
Do While not .EOF
Outp.writeline .Fields("Txt").Value
.MoveNext
Loop
End With
End Sub
以下是州
ConnectionState
ConnectionState枚举用于标识连接器空间对象的状态。 CSEntry.ConnectionState属性包含此枚举的值之一。
已连接
连接器空间对象连接到metaverse对象。
明确连接
连接器空间对象由MIISAdmins或MIISOperators组的成员由帐户连接器显式连接到元节对象。
断开连接
连接器空间对象未连接到元节对象,但可能是将来连接到元节对象的候选对象。
DisconnectedByFilter
连接器空间对象已被连接器过滤器规则断开。
明确断开连接 连接器空间对象未连接到元节对象,并且将来不会成为连接到元节对象的候选对象。 占位符连接器空间对象隐式存在于连接目录中,但尚未导入。