Access VBA-如何获取父级子窗体的属性,或获取子窗体的用户给定名称(而不是对象引用名称)

Access VBA-如何获取父级子窗体的属性,或获取子窗体的用户给定名称(而不是对象引用名称),vba,ms-access,Vba,Ms Access,在MS Access 2016中,假设我有两种表格:frmMain和frmBaby 我已将frmBaby作为子表单嵌入到frmMain中。我在frmba上嵌入了一个名为tbxInput的控件(假设它是一个文本框,但可以是任何控件) 关于frmMain,由于frmBaby是frmMain的一个“控件”,因此我将该控件的传统名称命名为subthmbaby 现在,在VBA中,子RMBABY上的事件将tbxInput控件ByRef(如Me.tbxInput)传递给一个函数,该函数用于返回ByRef传递的

在MS Access 2016中,假设我有两种表格:frmMain和frmBaby

我已将frmBaby作为子表单嵌入到frmMain中。我在frmba上嵌入了一个名为tbxInput的控件(假设它是一个文本框,但可以是任何控件)

关于frmMain,由于frmBaby是frmMain的一个“控件”,因此我将该控件的传统名称命名为subthmbaby

现在,在VBA中,子RMBABY上的事件将tbxInput控件ByRef(如Me.tbxInput)传递给一个函数,该函数用于返回ByRef传递的控件父级的.Left属性。也就是说,我需要该函数来确定frmMain上subfrmBaby位置的.Left属性。(函数比这个复杂,但是为了保留这个问题,让我们假设函数返回.Left属性值,因为.Left值是我执行函数所需要的。)

假设函数是:
Public function fncLocation(ByRef whtControl作为变量),只要

(我使用Variant以便可以传递空值。)

下面是我希望返回whtControl的父项(即subfrmBaby)的.Left值的代码:
lngLeft=whtControl.parent.Left

但是,这给了我一个错误:“应用程序或对象定义的错误”

当我使用即时窗口查看内容时,我发现whtControl.Parent.Name是“frmBaby”,而不是“subfrmBaby”这使得在frmMain上引用子表单很成问题,因为我无法从传递给函数的对象中获取给定给frmMain上控件的实际名称,因此我也无法按名称引用子表单

问题:

  • 如何获取传递给此函数的控件父级的.Left值

  • 如何获取分配给frmMain上的子窗体控件的实际名称?在本例中,我需要的名称是“subfrmBaby”,而不是“frmBaby”


  • 提前感谢您的建议。

    很有趣。我想你做不到

    如您所见,
    whtControl
    的父级是它的形式,
    frmBaby

    该项的父项是
    frmMain
    。“向上”时,子窗体控件不是对象链的一部分,仅在向下时

    如果您始终使用问题中的命名方案,您可以执行以下操作(air代码):


    可以通过迭代主窗体上的控件来实现这一点,假设whtControl是子窗体的窗体对象(如果是文本框,则为
    whtControl.Parent.Parent
    ,如果c.form是whtControl.Parent,则为


    请注意,迭代控件会带来性能损失,但此代码仍应花费毫秒,而不是秒。此外,由于我们测试了引用相等性,因此即使父窗体上多次出现相同的子窗体,它也可以工作。

    是的,我已经想到了这一点,但不幸的是,由于我继承了大部分代码,因此命名方案不一致。但是,这可能是我必须走的路(并且忍受重命名对象和重新编码新名称的噩梦)。谢谢你的建议,@Andre.谢谢。是的,这是一个选择,但我同意你对绩效的关注;数据库运行在已经相当慢的非常旧的笔记本电脑上,这一事实使情况更加复杂。然而,这也许是最好的选择。我正在考虑重新编码函数以接受另一个参数,然后将子窗体作为单独的(可选,可以为null)参数传递。这似乎比检查整个frmMain(它有很多控件/标签)要快,而且并不总是需要它。尽管如此,我还是很感激@Erik A.可能会尝试一下的建议。@DRC它仍然在毫秒范围内,因此即使在旧的硬件上,也不会明显减慢应用程序的速度。这句话更多地表明,如果能够传递主窗体,速度会快一点。因此,我决定向函数中添加一个参数,并将子窗体作为单独的参数传递。但是,我将此标记为答案,因为如果有人无法将子窗体作为参数传递,则它可能会起作用。谢谢,@Erik A。Andre似乎是正确的:您无法通过引用其父窗体来获取子窗体的名称@Erik A的答案将通过迭代父窗体上的所有控件来完成任务,我已经将其标记为答案,尽管我最终没有使用这种方法。最后,我向函数中添加了一个参数,并将子表单ByRef作为单独的参数传递。
    strSubform = whtControl.Parent.Name
    strSubformCtrl = "sub" & strSubform
    Set ctlSubform = whtControl.Parent.Parent(strSubformCtrl)
    
    Dim mainForm As Form
    Set mainForm = whtControl.Parent
    Dim c As Access.Control
    Dim subformControl As Access.Control
    For Each c In mainForm.Controls
        If TypeOf c Is SubForm Then
            If c.Form Is whtControl Then
                Set subformControl = c
                Exit For
            End If
        End If
    Next
    If Not subformControl Is Nothing Then
        Debug.Print subformControl.Left
    End If