将记录同步到子表单 VBA Access 中的字段值

问题描述 投票:0回答:1

主要问题是同步记录到子表单1 我有 4 个子表单,当我执行下一条记录时,它会按顺序转到下一条记录号 但我想要记录的 3 个子表单具有与子表单 1 相同的值 我没有做组合框所有的文本框有什么帮助吗?

我使用人工智能来解决我的问题但不起作用 不知道怎么解决

vba database forms ms-access subform
1个回答
0
投票

这需要一些编码,但使用此函数很容易实现:

Option Compare Database
Option Explicit

' Automatic synchronizing of multiple subforms.
' 2019-01-05. Gustav Brock, Cactus Data ApS, CPH.
' Version 1.2.0
' License: MIT.

    ' Index for Split to separate the name of the subform control from
    ' the name of the control with the key.
    '   [subControlAny]![ID]
    ' will be split into:
    '   [subControlAny]
    ' and:
    '   [ID]
    Enum ControlName
    SubForm = 0
    Key = 1
    End Enum

Private Function SyncSubforms(ParamArray sControls() As Variant) As Variant

    ' Array sControls() holds the values of the key controls on the subform controls
    ' to be held in sync.

    ' Name of visible textbox on main form bound to this function.
    Const cControl  As String = "txtSyncSubforms"

    ' Static to store the value of the key of the last synced record.
    Static wLastID  As Variant

    Dim rst         As DAO.Recordset
    Dim wSubform    As Form

    ' Array to hold the names of the subform controls and key controls.
    Dim aControls() As String

    Dim bmk         As Variant
    Dim wNew        As Boolean
    Dim wThisID     As Variant
    Dim wIndex      As Integer
    Dim wItem       As Integer
    Dim wCount      As Long
    Dim wFieldName  As String

    ' If any key value is Null, we have moved to a new record.
    ' No syncing shall take place.
    For wIndex = LBound(sControls()) To UBound(sControls())
        wThisID = sControls(wIndex).Value
        If IsNull(wThisID) Then
            If sControls(wItem).Parent.Name = Me.ActiveControl.SourceObject Then
                ' New record. Don't sync.
                wNew = True
                Exit For
            End If
        ElseIf IsNull(wLastID) Or Me.ActiveControl.Form.NewRecord Then
            ' Initial opening of form, or new record has been created.
            ' Set wLastID to the value of the current key of the first subform
            ' or to the key of the new record.
            wLastID = wThisID
            ' Stop further processing.
            wNew = True
            Exit For
        ElseIf IsEmpty(wThisID) Then
            ' Record has been deleted.
            ' Pull the ID from the active subform.
            For wItem = LBound(sControls) To UBound(sControls)
                If sControls(wItem).Parent.Name = Me.ActiveControl.SourceObject Then
                    wThisID = Me.ActiveControl(sControls(wItem).Name).Value
                    ' Store as the current key.
                    wLastID = wThisID
                    Exit For
                End If
            Next
            Exit For
        ElseIf wThisID <> wLastID Then
            ' This key is the new value to sync the other subforms to.
            ' Store the current key.
            wLastID = wThisID
            Exit For
        End If
    Next

    If wNew = True Then
        ' New record or initial opening. Do nothing.
    Else
        ' ControlSource of cControl will read like:
        '   =SyncSubforms([subControlFirst]![ID],[subControlSecond]![ID], .., [subControlLast]![ID])
        '
        ' Build array of the names of the subform controls with the key controls:
        '   [subControlFirst]![ID]
        '   [subControlSecond]![ID]
        '   ...
        '   [subControlAny]![ID]
        '   ...
        '   [subControlLast]![ID]
        ' by extracting arg names between "(" and ")".
        aControls = Split(Replace(Split(Me(cControl).ControlSource, "(")(1), ")", ""), ",")

        ' Get current record count as it will change after an append or delete in one of the subforms.
        For wIndex = LBound(aControls()) To UBound(aControls())
            If Me(Split(aControls(wIndex), "!")(ControlName.SubForm)).Name = Me.ActiveControl.Name Then
                Set wSubform = Me(Split(aControls(wIndex), "!")(ControlName.SubForm)).Form
                wCount = wSubform.RecordsetClone.RecordCount
                Exit For
            End If
        Next

        ' Loop to locate and sync those subforms that haven't changed.
        For wIndex = LBound(aControls()) To UBound(aControls())
            ' Extract name of subform control using Split:
            '   [subControlAny]
            Set wSubform = Me(Split(aControls(wIndex), "!")(ControlName.SubForm)).Form
            If wCount <> wSubform.RecordsetClone.RecordCount Then
                ' A record has been added or deleted in another subform.
                wSubform.Requery
            End If
            If IsNull(sControls(wIndex)) Or sControls(wIndex) <> wThisID Then
                ' This subform is to be synced.
                Set rst = wSubform.RecordsetClone
                ' Find record for current key.
                ' Extract name of control on subform using Split:
                '   [ID]
                ' Then use ControlSource to get the name of the field to search.
                wFieldName = wSubform(Split(aControls(wIndex), "!")(ControlName.Key)).ControlSource
                ' Wrap the fieldname in brackets in case it should contain spaces or special characters.
                If Left(wFieldName, 1) <> "[" Then
                    wFieldName = "[" & wFieldName & "]"
                End If
                rst.FindFirst wFieldName & " = " & wThisID
                If Not rst.NoMatch Then
                    bmk = rst.Bookmark
                    wSubform.Bookmark = bmk
                End If
                rst.Close
            End If
        Next

    End If

    Set rst = Nothing
    Set wSubform = Nothing

    SyncSubforms = wLastID

End Function

内联文档很迟钝。完整的文档太多,无法在此发布,但已发布在这里:

在 Access 中同步多个子表单

© www.soinside.com 2019 - 2024. All rights reserved.