VBA Access类的新功能

时间:2015-03-26 11:09:18

标签: vba access-vba

我一直在研究一个项目并且有多个标记框(25)和多个标签,形式为名称SC1,SC2 ... SCN和Lbl1,Lbl2 ... LblN,具体取决于记录集。当我点击复选框时,我希望它旁边的标签显示一些信息,见下面 -

Private Sub SC1_Click()
   If (Me!SC1) = True Then
    Form.Controls("Lbl1").Caption = ("Completed by " & (Environ$("Username")))
    Form.Controls("Lbl1").ForeColor = vbGreen
Else
    Form.Controls("Lbl1").Caption = ("Please tick if Complete")
    Form.Controls("Lbl1").ForeColor = vbBlack
End If

End Sub

我的问题是我无法更改子名称中的数字,因此我必须创建多个子程序。我想如果我为勾选框创建了一个类,这会改变,但我不确定如何设置该类。我已经尝试了下面的类模板,但我不确定在哪里可以更改属性值以达到我的目标。我不确定为什么你会在一个类中同时获取和设置属性。非常感谢任何帮助。

Option Compare Database
Option Explicit


Private pName As String
Private pCaption As String
Private pVisiblity As Boolean
Private pValue As Boolean


Public Property Get Name() As String
    Name = pName
End Property
Public Property Let Name(Value As String)
    pName = Value
End Property

Public Property Get Caption() As String
    Caption = pCaption
End Property
Public Property Let Caption(Value As String)
    pCaption = "Please Tick Box if complete"
End Property

Public Property Get Visibility() As Boolean
    Visibility = pVisibility
End Property
Public Property Let Visibility(Value As Boolean)
    pVisibility = True
End Property

Public Property Get Value() As Boolean
    Value = pValue
End Property
Public Property Let Value(Value As Boolean)
    pValue = True
End Property

2 个答案:

答案 0 :(得分:1)

创建表单控件并将表单控件链接到自定义支持对象(类)有两个部分。在你的情况下

课程模块:clsMyCheckbox

Option Explicit
Option Compare Database
Public WithEvents chkBox As CheckBox
Public chkLabel As Label

Private currentUser As String

Private Sub chkBox_Click()
    If chkBox.Value = True Then
        chkLabel.Caption = "Completed by " & currentUser
        chkLabel.ForeColor = vbGreen
    Else
        chkLabel.Caption = "Please tick if Complete"
        chkLabel.ForeColor = vbBlack
    End If
End Sub

Private Sub Class_Initialize()
    currentUser = Environ$("Username")
End Sub

在您的表单模块中:

Option Explicit
Option Compare Database

Private localCheckboxes As New Collection

Private Sub Form_Load()
    '--- find all the checkboxes on the form and create a
    '    handler object for each one
    Dim ctl As Control
    Dim chknum As String
    Dim cbObj As clsMyCheckbox
    Dim chkLbl As Label
    For Each ctl In Me.Controls
        If ctl.ControlType = acCheckBox Then
            '--- you can filter by name if needed
            If ctl.Name Like "SC*" Then
                chknum = Right(ctl.Name, Len(ctl.Name) - 2)
                Set chkLbl = Me.Controls.Item("Lbl" & chknum)
                chkLbl.Caption = "initialized" 'optional during form load
                Set cbObj = New clsMyCheckbox  'class object for this checkbox
                Set cbObj.chkBox = ctl         'link the control to the object
                Set cbObj.chkLabel = chkLbl    'link the label too
                '--- add it to a local store so the object persists
                '    as long as the form is open
                localCheckboxes.Add cbObj
            End If
        End If
    Next ctl
End Sub

Private Sub Form_Unload(Cancel As Integer)
    '--- guarantee the objects are destroyed with the form
    Set localCheckboxes = Nothing
End Sub

答案 1 :(得分:0)

我认为你走错了路。在Access中,您无法真正派生自己的GUI控件类并在表单上使用它们。对于您的问题,您基本上有三个选项:

  1. 使用默认事件处理程序并从每个调用一个自定义函数。这会稍微改善你的情况。
  2. 为所有复选框使用一个自定义事件处理程序,而不是默认的事件处理程序。
  3. 使用类并将实例附加到您使用的每个复选框。然后,该类可以从复选框中接收任何事件。这很强大,但你仍然需要在每个控件上注册你的类,并在某处保存你所有的实例。
  4. 对于您的问题,我选择解决方案2:

    首先,在Form-module中编写一个这样的自定义事件处理程序:

    Private Function chkClick(sName As String)
        Debug.Print "Clicked: " & sName
        Me.Controls(sName).Controls(0).Caption = "x"
    End Function
    

    接下来,进入表单的设计模式并转到所有复选框。在Checkbox" SC1"中,您转到" OnClick"事件并输入=chkClick("SC1")作为事件处理程序而不是[Eventprocedure]。确保使用正确的控件名称作为函数的参数。

    恭喜!从现在开始,所有复选框都将调用相同的事件处理程序并传递其名称。由于复选框的标签是其关联控件,因此您可以通过.Controls(0)从复选框中获取该标签,这意味着复选框的第一个" sub" - 控件。这样,您根本不需要知道相关标签的名称!