class - 在 MS Access 中引用可重复使用的表单(2 深)

标签 class vba ms-access

我有多个成员(member),每个成员(member)都有一条记录,其中包含几个备注字段:

Member ID    Entry A       Entry B
   1        [memo text]   [memo text]
   2        [memo text]   [memo text]
   3        [memo text]   [memo text]

在 Access 2007 中,我正在创建一个等效于 Shift-F2 的备忘录条目表单 -- 一个用于查看和编辑内容的专用窗口。与 Shift-F2 不同,这必须是可重用的。

我必须提一下,显示成员(member)详细信息的表单也是可重复使用的。按照上面的计划(缩写),我最多可以同时打开三个成员(member)表格和六个备忘录条目表格。

下面的解决方案运行良好,除了关键事件 UpdateComment() 仅在每个成员表单触发一次,而不是每个备忘录表单触发一次。因此,如果我为同一成员打开 AB 并进行编辑,则只会将一个编辑传递给调用表单。

不知何故,我无法为调用表单 Member Detail 提供一种将 Memo 表单视为唯一的方法。我该如何解决?

成员详细信息表单——这是生成

Dim strFieldName As String, varValue
Private WithEvents frmZoom As Form_frmMemberInputZoom

Private Sub btnView_A_Click()
    strFieldName = "boxQuality_A"
    varValue = Me(strFieldName)
    Call OpenMemberInput(Me!boxID, strFieldName, varValue, True)
End Sub

Private Sub btnView_B_Click()
    strFieldName = "boxQuality_B"
    varValue = Me(strFieldName)
    Call OpenMemberInput(Me!boxID, strFieldName, varValue, True)
End Sub

Private Sub frmZoom_UpdateComment(lngID As Long, _ 
                    strAssessStage As String, varReturn)

    Dim intCount As Integer
    For intCount = 1 To collectnZooms.Count
        If collectnZooms(intCount)![boxID] = lngID _
           And collectnZooms(intCount)![boxAssessStage] = strAssessStage _ 
              Then

                Me(strAssessStage) = varReturn
                Me.Dirty = False

                Exit Sub
        End If
    Next

End Sub

Private Sub Form_Close()
    Dim obj As Object

    For Each obj In collectnMembers
        If obj.Hwnd = Me.Hwnd Then
            collectnMembers.Remove CStr(Me.Hwnd)
        End If
    Next
End Sub

Sub OpenMemberInput(lngID As Long, strStage As String, _
                    varComment, booEdit As Boolean)

    Set frmZoom = New Form_frmMemberInputZoom

    frmZoom.Caption = CStr(frmZoom.Hwnd)

    frmZoom.ID = lngID 
    frmZoom.Stage = strStage
    frmZoom.ProviderName = "Dr " & CStr(lngID)
    frmZoom.Comment = varComment

    frmZoom.Visible = True

    collectnZooms.Add Item:=frmZoom, Key:=CStr(frmZoom.Hwnd)

End Sub

备忘录输入表单——生成此表单

Public Event UpdateComment(lngID As Long, strAssessStage As String, _ 
                           varReturn)

Private lngAssess_ID As Long
Private strAssessStage As String
Private strProviderName As String
Private varComment

Public Property Let ID(ByVal MyAssessID As Long)
    lngAssess_ID = MyAssessID
    Me.boxID = lngAssess_ID
End Property

Public Property Let Stage(ByVal MyAssessStage As String)
    strAssessStage = MyAssessStage
    Me.boxAssessStage = strAssessStage
End Property

Public Property Let ProviderName(ByVal MyProviderName As String)
    strProviderName = MyProviderName
    Me.boxProviderName = strProviderName
End Property

Public Property Let Comment(ByVal varExisting)
    varComment = varExisting
    Me.boxComment = varComment
End Property

Public Property Get Comment()
    Comment = varComment
End Property

Private Sub boxComment_AfterUpdate()
    varComment = Me.boxComment
    Comment = varComment
End Sub

Private Sub Form_Close()

    '#################################################################
    ' Line below will be called for only ONE of the multiple instances
    '#################################################################

    RaiseEvent UpdateComment(lngAssess_ID, strAssessStage, varComment)

    Dim obj As Object
    For Each obj In collectnZooms
        If obj.Hwnd = Me.Hwnd Then
            collectnZooms.Remove CStr(Me.Hwnd)
        End If
    Next

End Sub 

最佳答案

按照 this post 中的建议:

  • 拆除RaiseEvent 函数。
  • 使用 .Visible 来避免关闭 Memo Entry 表单(这会导致错误)。

成员详细信息表单——这是生成

Dim strFieldName As String, varValue
'Private WithEvents ... NAH, WE WON'T GO THERE  

Private Sub btnView_A_Click()
    strFieldName = "boxQuality_A"
    varValue = Me(strFieldName)
    Call OpenMemberInput(Me!boxID, strFieldName, varValue, True)
End Sub

Private Sub btnView_B_Click()
    strFieldName = "boxQuality_B"
    varValue = Me(strFieldName)
    Call OpenMemberInput(Me!boxID, strFieldName, varValue, True)
End Sub

'Private Sub frmZoom_UpdateComment(lngID As Long, strAssessStage As String, varReturn)
'    ... NAH, we won't be using this...
'End Sub

Private Sub Form_Close()

    Dim obj As ObjecT
    For Each obj In collectnMembers
        If obj.Hwnd = Me.Hwnd Then
            collectnMembers.Remove CStr(Me.Hwnd)
        End If
    Next

End Sub

Sub OpenMemberInput(lngID As Long, strStage As String, _
                    varComment, booEdit As Boolean)

    Dim FoundMe As Boolean
    FoundMe = v_MemberComment.FetchForm(lngID, strStage)
    If FoundMe Then Exit Sub

    Dim frmZoom As New Form_frmMemberInputZoom

    Set frmZoom = New Form_frmMemberInputZoom


    frmZoom.ID = lngID 
    frmZoom.Stage = strStage
    frmZoom.Comment = varComment

    frmZoom.Visible = True

    collectnZooms.Add Item:=frmZoom, Key:=CStr(frmZoom.Hwnd)

End Sub

备忘录输入表单——生成此表单

'' NAH, no use of the Public Event
'Public Event UpdateComment(lngID As Long, strAssessStage As String, varReturn)

Private lngAssess_ID As Long
Private strAssessStage As String
Private varComment

Public Property Let ID(ByVal MyAssessID As Long)
    lngAssess_ID = MyAssessID
    Me.boxID = lngAssess_ID
End Property

Public Property Let Stage(ByVal MyAssessStage As String)
    strAssessStage = MyAssessStage
    Me.boxAssessStage = strAssessStage
End Property

Public Property Let Comment(ByVal varExisting)
    varComment = varExisting
    Me.boxComment = varComment
End Property

Public Property Get Comment()
    Comment = varComment
End Property

Private Sub boxComment_AfterUpdate()
    varComment = Me.boxComment
    Comment = varComment
End Sub

Private Sub CmdCancel_Click()
    ''TODO revert to before-update text if Cancel is selected
    Me.Tag = "Cancel"
    Me.Visible = False
End Sub

Private Sub CmdOK_Click()

    Dim intCount As Integer, frm As Form, lngHwnd As Long
    For intCount = 1 To collectnMembers.Count

        Set frm = collectnMembers(intCount)
        If frm![boxID] = lngAssess_ID Then
                frm(strAssessStage) = varComment
                frm.Requery
        End If
    Next

    Me.Visible = False

End Sub

Private Sub Form_Close()

    'RaiseEvent .... NAH, DON'T BOTHER

    Dim obj As Object
    For Each obj In collectnZooms
        If obj.Hwnd = Me.Hwnd Then
            collectnZooms.Remove CStr(Me.Hwnd)
        End If
    Next
End Sub

支持上述形式的VBA标准模块

Public collectnZooms As New Collection

Public Function FetchForm(lngID As Long, strStage As String) As Boolean

    Dim intCount As Integer
    For intCount = 1 To collectnZooms.Count

        If collectnZooms(intCount)![boxID] = lngID _
           And collectnZooms(intCount)![boxAssessStage] = strStage Then
                FetchForm = True
                collectnZooms(intCount).Tag = ""

                collectnZooms(intCount).Visible = True

                Exit Function
        End If

    Next
End Function

关于class - 在 MS Access 中引用可重复使用的表单(2 深),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22108012/

相关文章:

ms-access - 有没有办法让 ms-access 显示外部文件中的图像

java - 单类依赖

c# - 如何使用类本身作为方法参数?

vba - Outlook VBA 宏不修改电子邮件

vba - 任务计划程序不运行 Excel VBA 代码以将 PDF 作为电子邮件附件发送

sql - 使用 Excel VBA 更新 Access 数据库时确定记录是否存在

vba - .将图片添加到Word文档: Invalid Property Assignment

c# - 如何将 List<T> 对象项目正确存储到 List<T> 的另一个实例而不影响其单个项目值 - C#

Python 元类 : how do I generalize this helper class?

excel - 使用标准突出显示