我正在尝试创建一个允许我使用各种命令按钮而不必每次都重新创建代码的函数。
为此,我必须通过函数
传递表单名称功能:
public Function NewRecord(controlForm, focusForm)
focusForm.SetFocus
DoCmd.GoToRecord , , acNewRecord
controlForm.SetFocus
controlForm - 这是类似于Me函数的主要形式
focusForm - 这不仅适用于主窗体,而且当我创建子窗体时,我必须关注子窗体以使命令有效。
要调用该函数,我执行了以下操作:
public sub Command19_Click()
Dim controlForm
Dim focusForm
Set controlForm = Forms![frm_Sales_CustomerProfile]
Set focusForm = Forms![frm_Sales_CustomerProfile]
Call NewRecord(controlForm, focusForm)
End Sub
我收到状态:编译错误:无效使用属性的错误。
答案 0 :(得分:1)
您使用已在此上下文(表单)中使用标识符并且未使用强名称(NameOfLibrary.NameOfFunction)来捕获。NewRecord
是表单属性,因此Invalid Use Of Property
有意义。如果你使用MyModulName.NewRecord(frm1,frm2)
一切都很好。如果你在ModuleòrClass中使用NewRecord
它也可以,因为没有相同名称的属性(我假设; - ))。
老实说,我也不使用强名称(除了数据库或记录集对象,因为我也被困在那里,假设DAO,使用ADODB),但专业人士建议,现在我们知道为什么!
你的函数应该只有一个参数,因为如果你需要那个形式NewRecord(frm as Access.Form)
就足以只传递子表格引用(注意强名称!)。您可以使用Set mfrm = frm.Parent
您的代码;
Public Function FrmNewRecord(frm As Access.Form)
frm.Recordset.AddNew
End Function
Public Sub Command19_Click()
FrmNewRecord(Forms![frm_Sales_CustomerProfile]) ' mainform
FrmNewRecord(Forms![frm_Sales_CustomerProfile]!sfrmControl.Form) ' subform
End Sub
您在代码中传递了两次相同的表单,无论如何?如果Forms[frm_Sales_CustomerProfile]
包含Command19,请使用Me
。
我放弃.SetFocus
部分作为没有必要或任何理由设置焦点?为什么NewRecord是一个功能?不归还任何东西。
顺便说一句:我正在开发一个SubForms(frm)
函数,它返回所有子表单的集合。
代码:
'SubForms(frm As Access.Form) returns a collection of all subform references in frm
Public Function SubForms(frm As Access.Form) As VBA.Collection
Dim ctr As Access.Control
Dim sfrm As Access.Form
Dim col As New VBA.Collection
For Each ctr In frm.Controls
If ctr.ControlType = acSubform Then
On Error Resume Next
Set sfrm = ctr.Form
If Err.Number = 0 Then
col.Add sfrm, sfrm.Name
End If
On Error GoTo 0
End If
Next ctr
Set SubForms = col
End Function
答案 1 :(得分:0)
作为构建自定义菜单栏或色带的一般规则,您可以编写“形式”中性的代码,如下所示:
Public Function MyDelete(strPrompt As String,strTable As String)
Dim strSql As String
Dim f As Form
Set f = Screen.ActiveForm
If MsgBox("Delete this " & strPrompt & " record?", _
vbQuestion + vbYesNoCancel, "Delete?") = vbYes Then
请注意我们根本不需要传递表单名称 - 上面的代码只是将活动屏幕选为变量“f”。
此时,您可以执行任何操作,就像代码在表单中一样。
所以
Me.Refresh (code inside the form)
变为
f.Refresh
因此,这里的关键概念是您不需要传递当前活动表单,因为screenActive表单将使您能够获取当前表单对象。
但是,对于子表单和“常见”类型的代码,上面的内容会分崩离析,因为screen.ActiveForm将返回主窗体,而不是子窗体实例。
因此,作为第二种推荐方法,只需将当前上下文形式对象“me”传递给它:
Call MySub(me)
你定义你的子像:
Sub MySub(f as form)
现在在这段代码中,我们可以参考"任何事情"通过使用" f"代替" me"
f.Refresh
如果您使用子表单,那么只需传递“我”。鉴于上述信息,您的代码将变为:
public sub Command19_Click()
Call NewRecord(me)
End Sub
NewReocrd成为:
Sub NewRecord(f as form)
现在在你的newreocrd代码中,你可以使用对象中的“任何东西”,例如:
f.Name ' get name of the form.
或
City = f.City ' get value of city control
所以传递“整体”形式背景。
你可以说做一个例程来显示任何形式的City值:
致电ShowCity(我," City")
然后
Sub ShowCity(f为表单,strControlToShow为字符串)
Msgbox "City value = " & f(strControlToShow)
因此,OFTEN将通过简单地选取当前活动表单来编写适用于任何表单的代码:
Dim f As Form
Set f = Screen.ActiveForm
并注意上面的代码如何立即获取活动表单 - 这是一个好主意,因为如果焦点发生变化,“f”引用将保持完整,因为后面的代码会被调用的“常规”例程+用于多种形式。
但是由于子表单问题,通常最好总是将“整个”表单实例/对象传递给:
Call MyNewRecord(me)
然后将sub定义为:
Sub MyNewReocord(f as form)
DoCmd.GoToRecord acDataForm, f.Name, acNewRec
End Sub
你可以通过
选择添加“焦点”到上面f.SetFocus
因此,对于很多菜单或功能区代码,您不会传递表单对象,只需使用screen.ActiveForm,您也可以使用Screen.ActiveControl(再次强大的菜单栏或功能区代码来抓取什么控制有焦点)。然而,由于子形式的限制,经常通过" me"如果在某些情况下不是更好,那么例行程序将取得类似的结果。