Access VBA-如何获取父级子窗体的属性,或获取子窗体的用户给定名称(而不是对象引用名称)
在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值是我执行函数所需要的。) 假设函数是: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传递的
Public function fncLocation(ByRef whtControl作为变量),只要
(我使用Variant以便可以传递空值。)
下面是我希望返回whtControl的父项(即subfrmBaby)的.Left值的代码:lngLeft=whtControl.parent.Left
但是,这给了我一个错误:“应用程序或对象定义的错误”
当我使用即时窗口查看内容时,我发现whtControl.Parent.Name是“frmBaby”,而不是“subfrmBaby”这使得在frmMain上引用子表单很成问题,因为我无法从传递给函数的对象中获取给定给frmMain上控件的实际名称,因此我也无法按名称引用子表单
问题:
提前感谢您的建议。很有趣。我想你做不到 如您所见,
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