首页 > 解决方案 > 子窗体不显示 VBA 记录更改

问题描述

我有一个带有 3 个子表单的未绑定表单。每个子表单都具有相同的记录源,但在名为 CrntPhaseNmbr 的字段上进行过滤,该字段带有一个简单的数值 1、2 或 3,以显示来自同一查询的 3 组不同的数据。我使用 VBA 来实际更新该字段,因为使用的查询是不可更新的查询。我在子窗体 1 和 2 上有一个命令按钮,单击该按钮时,所选记录的值增加 1,将其提升到下一组。在子窗体 2 和 3 上,命令按钮将值减小 1,将所选记录降级到前一组。

我尝试将所有 3 个子表单的记录源设置为查询,然后将表单过滤器设置为每个表单所需的特定值。我也尝试过不使用过滤器并将记录源设置为带有 where 语句的 SQL 字符串来过滤记录集。无论哪种方式,结果都没有区别。

问题是 CrntPhaseNmbr 值更新没有问题,但子窗体不显示更新的记录集。

ResidentPhaseMove 存储在一个模块中,所有 3 种形式都可以正常工作。

这是子表单 2 的代码,它同时具有降级和提升命令按钮(子表单 1 和 3 的代码是相同的,只是它们每个只有一个按钮,分别是提升和降级):

Private Sub cmdDemote_Click()

    Dim intNewPhase As Integer
    Dim lngResidentID As Long
    Dim rstList As Object
    Dim strRcrdSrc As String
    Dim strRcrdSrc2 As String

    lngResidentID = txtResidentID
    intNewPhase = txtCrntPhaseNmbr - 1
    
    Application.Echo False

    strRcrdSrc = Me.RecordSource
    Me.RecordSource = ""
    strRcrdSrc2 = Forms!frmHouseAssignedPhases!ResidentsPhase1.Form.RecordSource
    Forms!frmHouseAssignedPhases!ResidentsPhase1.Form.RecordSource = ""
    
    Call ResidentPhaseMove(lngResidentID, intNewPhase)
    
    Call Me.Parent.ChkUpdateStatus
    
    Me!txtFocus.SetFocus
    Me.RecordSource = strRcrdSrc

    Me.Requery
    
    Forms!frmHouseAssignedPhases!ResidentsPhase1.Form!txtFocus.SetFocus
    Forms!frmHouseAssignedPhases!ResidentsPhase1.Form.RecordSource = strRcrdSrc2

    Forms!frmHouseAssignedPhases!ResidentsPhase1.Form.Requery
    Application.Echo True

End Sub

Private Sub cmdPromote_Click()

    Dim intNewPhase As Integer
    Dim lngResidentID As Long
    Dim rstList As Object
    Dim strRcrdSrc As String
    Dim strRcrdSrc2 As String

    lngResidentID = txtResidentID
    intNewPhase = txtCrntPhaseNmbr + 1
    
    Call ResidentPhaseMove(lngResidentID, intNewPhase)

    Application.Echo False

    strRcrdSrc = Me.RecordSource
    Me.RecordSource = ""
    strRcrdSrc2 = Forms!frmHouseAssignedPhases!ResidentsPhase3.Form.RecordSource
    Forms!frmHouseAssignedPhases!ResidentsPhase3.Form.RecordSource = ""
   
    Call ResidentPhaseMove(lngResidentID, intNewPhase)
    
    Call Me.Parent.ChkUpdateStatus

    Me!txtFocus.SetFocus
    Me.RecordSource = strRcrdSrc

    Me.Requery
    
    Forms!frmHouseAssignedPhases!ResidentsPhase3.Form!txtFocus.SetFocus
    Forms!frmHouseAssignedPhases!ResidentsPhase3.Form.RecordSource = strRcrdSrc2

    Forms!frmHouseAssignedPhases!ResidentsPhase3.Form.Requery
    Application.Echo True

End Sub

Sub ChkUpdateStatus()

    Dim varState

ChkAgain:
    varState = SysCmd(acSysCmdGetObjectState, acStoredProcedure, "ResidentPhaseMove")

    If varState = 0 Then
        WaitSeconds 2
    Else
        GoTo ChkAgain
    End If

    Me.Requery

End Sub

Sub ResidentPhaseMove(lngResidentID As Long, intPhase As Integer)

    Dim sqlMove As String
    Dim cnnMain As ADODB.Connection
    Dim cmdMove As ADODB.Command
    Dim rstMove As ADODB.Recordset
    
    Set cnnMain = New ADODB.Connection
    cnnMain.ConnectionString = cnstCnctMain
    cnnMain.Open

    sqlMove = "UPDATE Residents SET Residents.CrntPhaseNmbr = " & intPhase _
                    & " WHERE (((Residents.ResidentID)=" & lngResidentID & "));"

    Set cmdMove = New ADODB.Command
    cmdMove.ActiveConnection = cnnMain
    cmdMove.CommandText = sqlMove
    cmdMove.Execute

    Set cmdMove = Nothing
    cnnMain.Close
    Set cnnMain = Nothing

End Sub

我确定问题是子表单在更改之前显示,但我还没有弄清楚如何在更改后让子表单重新查询。

感谢您提供的任何帮助。

标签: vbams-access

解决方案


我还没有找到任何方法导致数据在更新后显示,而 RecordSource 是一个不可更新的查询,其中实际编辑是使用 VBA 完成的,而不是直接在表单上。因此,我创建了一个代码例程来创建一个由不可更新查询中的字段组成的临时表。我将其用作子表单的 RecordSource。

有了这个 RecordSource,Gustav 给出的答案就可以正常工作。一个小小的调整。对于每个子表单,重新查询应包含其自身。即,对于子表单 1 中的代码,应出现以下重新查询语句:

Me.Requery
Me.Parent!NameOfOtherSubformControl2.Form.Requery
Me.Parent!NameOfOtherSubformControl3.Form.Requery

推荐阅读