3

我正在对 Microsoft Access 2010 中的链接表应用程序进行一些维护工作,并遇到了这个小问题。该应用程序链接到 SQL Server 2008 数据库。该应用程序有一个主表单,允许用户选择公园代码和资源的组合,并弹出一个编辑表单以获取该特定组合的详细信息。如果数据库中不存在该组合,则应用程序会插入一条新记录,但问题是插入了 2 条记录。

这是问题代码的位置,当我需要在详细信息弹出表单中插入新记录时会调用它:

Private Sub New_Rec(unit_code As String, resource As String, sql As String)

   DoCmd.RunSQL ("INSERT INTO PARK_RESOURCES (unit_code, resource, sensitivity) VALUES " _
    & "('" & unit_code & "','" & resource & "','public')")

   'Force an explicit save
   'http://www.pcreview.co.uk/forums/update-cancelupdate-without-addnew-edit-t1150554.html
   If Me.Dirty Then
      Me.Dirty = False
   End If

   Me.RecordSource = sql
End Sub

创建“新”记录会导致 2 条记录插入到 Recordset 中。在设置 RecordSource 之前或之后移动显式保存代码似乎并不重要。以任一顺序(并在任一顺序后停止)都会在数据库中插入 2 条新记录(通过在 SSMS 中查询来验证)。

当我设置 RecordSource 属性并逐步执行代码时,事件链看起来像:Me.RecordSource = sql --> Form_BeforeUpdate() --> Form_AfterUpdate() --> Form_After_Insert() --> Form_Current()。在更新前结束时不存在副本,但是当我到达更新后时,副本已经被插入。BeforeUpdate 和 AfterUpdate 之间会发生什么导致这种情况发生?

根据MSDN,顺序是:BeforeInsert → BeforeUpdate → AfterUpdate → AfterInsert。他们还声明通过 Visual Basic 设置控件的值不会触发这些事件。但是当我在代码中更新 RecordSource 时,最后 3 个事件肯定会触发;BeforeInsert 是唯一一个不会停止单步执行的方法。

根据 Daniel Cook 的要求,这里是调用代码。

Private Sub Form_Load()
   On Error GoTo Err_Form_Load

   Me.KeyPreview = True
   If Not IsNull(Me.OpenArgs) Then
      ProcessOpenArgs (Me.OpenArgs)
      Me.lblHeader.Caption = Me.unit_code & ": Resource - " & Me.resource
   Else
      Me.lblHeader.Caption = "Information Needs"
   End If
   ... (error trapping)
End Sub

和 ProcessOpenArgs 子(OpenArgs 设置为“公园;资源”):

Private Sub ProcessOpenArgs(open_args As String)
   On Error GoTo Err_ProcessOpenArgs

   Dim Args() As String
   Args = Split(open_args, ";")

   Me.unit_code = Args(0)
   Me.resource = Args(1)

   'Check to see if there are records in the database for current unit/resource combo'
   Dim rs As DAO.Recordset
   Dim sql As String
   sql = "SELECT * FROM PARK_RESOURCES " & _
    "WHERE resource='" & Me.resource & "' AND unit_code='" & Me.unit_code & "'"
   Set rs = CurrentDb.OpenRecordset(sql, dbOpenDynaset, dbSeeChanges)

   'if there aren''t, create a new record'
   If (rs.RecordCount = 0) Then
      New_Rec Me.unit_code, Me.resource, sql
   Else 'go to the current listing'
      Me.RecordSource = sql
   End If

Exit_ProcessOpenArgs:
   Exit Sub
Err_ProcessOpenArgs:
   MsgBox Err.Number & Err.description
   Resume Exit_ProcessOpenArgs
End Sub

我将继续梳理事件文档,作为最后的手段,我可​​能会完全发疯,只是将所有可能的事件粘贴到我的 VBA 代码中并逐步执行它们,但有谁知道可能发生什么导致重复?

4

2 回答 2

1

在您的ProcessOpenArgs, 该If (rs.RecordCount = 0) Then行可能是一个问题,除非您第一次使用rs.MoveLast- 请参阅此处

于 2012-12-15T23:42:53.167 回答
1

当我在这里设置Me.unit_codeMe.unit

Private Sub ProcessOpenArgs(open_args As String)
   On Error GoTo Err_ProcessOpenArgs

   Dim Args() As String
   Args = Split(open_args, ";")

   Me.unit_code = Args(0)
   Me.resource = Args(1)

该代码正在创建 1 条记录,然后New_Rec在数据库中插入第二条记录。当 Form 自动 Requeries afterMe.RecordSource = sql时,它会将第一条记录(由 Me.xxx = yyyy 语句创建的ProcessOpenArgs也插入数据库,然后将两者都拉回 Form Recordset。这就是双插入的来源。

为了更正它,我将Me.unit_code和更改Me.resource为局部子程序变量l_unit_codel_resource并在ProcessOpenArgs. 这解决了这个问题以及我遇到的第二个问题,即记录从一种资源类型渗入其他资源类型。

谢谢大家的协助!

于 2012-12-18T01:10:17.133 回答