Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Access Form Control Arrays and Event Capturing

Introduction

Forms will have several objects of the same type.  For example, there will be several TextBoxes on the Form.  It is not possible to declare separate TextBox Properties in a Class Module to capture Events from each one of them.

The easiest technique is something like the following steps:

  1. Create a Class Module with a single Text Box object property.

  2. Define separate subroutines in the Class Module—such as AfterUpdate, LostFocus, and others—to handle the respective events triggered by Text Box controls on the Form.

  3. In the Form’s module (or in another dedicated Class Module), create an array of these Class Module objects, assigning one class object instance to each Text Box control on the Form.

  4. When a built-in event is raised from a particular Text Box on the Form, it will be captured by the corresponding class object in the array and executed through its event-handling subroutine.

Sample Demo Project

Let us start with a simple example.

  1. Create a new Class Module and change its Name Property Value to clsTxtArray1.

  2. Copy and paste the following VBA Code into the Class Module and save it:

    Option Compare Database
    Option Explicit
    
    Public WithEvents Txt As Access.TextBox
    
    Private Sub Txt_AfterUpdate()
    Dim txtName As String, sngval As Single
    Dim msg As String
    
    txtName = Txt.Name
    sngval = Nz(Txt.Value, 0)
    
    msg = txtName & " _AfterUpdate. :" & sngval
    MsgBox msg, vbInformation, Txt.Name
    
    End Sub
    

    Declared the Text Box Object Txt with Public scope to avoid the Get and Set Property Procedure for the time being, to keep the Code in the Class Module simple.

    The AfterUpdate() Event Procedure will execute when that Event of the Text Box fires on the Form.

  3. Create a new Form, insert a single Text Box on the Form, and save the Form with the name frmTxtArray1.

    An image of the sample form is given below.


  4. Open the Form in Design View and display the form's Code Module.
  5. Copy and Paste the following VBA Code into the Form Module:

    Option Compare Database
    Option Explicit
    
    Private ta() As New ClsTxtArray1
    
    Private Sub Form_Load()
    Dim cnt As Integer
    Dim ctl As Control
    
    For Each ctl In Me.Controls
      If TypeName(ctl) = "TextBox" Then
         cnt = cnt + 1
         ReDim Preserve ta(1 To cnt)
         Set ta(cnt).Txt = ctl
         ta(cnt).Txt.AfterUpdate = "[Event Procedure]"
      End If
    Next
    End Sub

    The VBA Code Line by Line

    In the global declaration area, ClsTxtArray1 Class is instantiated as an empty Array Object.

    The real action is in the Form_Load() Event Procedure.

    Two Variables, Count (cnt) and Control (ctl), are declared.

    The For Each ... Next Loop is set to scan the Form for all Control Types on the Form, and identify the required control type: TextBox.

    If the Control TypeName is TextBox, then the cnt Variable is incremented by one. The ta Array is re-dimensioned for 1 to cnt of items, preserving the earlier elements of data, if any.

    The statement 'Set ta(cnt).Txt = ctl' assigns the current Class Object Array element’s txt Property with the TextBox Control.

    The next line 'ta(cnt).Txt.AfterUpdate = "[Event Procedure]"' enables the TextBox’s AfterUpdate Event, so that it can be captured in the Private Sub txt_AfterUpdate() sub-routine of ta(cnt) instance of ClsTxtArray1 Array element.

  6. If you are through with the above lines of Code, then save and close the Form.

  7. Sample Data Entry

    Open the Form in normal view.

  8. Enter some numeric Value into the Text Box and press the Tab Key. 

    A message box displays the entered value.  A sample test run image is given below.

    Check the MsgBox image with event-related info in there.

    The TexBox Name is shown in the Title area, from where the AfterUpdate Event is captured.  The message line indicates that it is run from the AfterUpdate subroutine, and the value entered into the TextBox is displayed at the end of the line.

    Adding More Controls on Form

  9. Close the Form and Open it in Design View.

  10. Add a few more TextBoxes, anywhere you like on the Form.

  11. Save and Close the Form.

    A sample Image of the changed Form is given below.

  12. Open the Form in Normal View.

  13. Enter some numeric value in any newly added text box and press the Tab Key.

    When you do this, the MsgBox will pop up, displaying messages like the earlier one. It will contain the TextBox Name and the number entered into the Text Box.

  14. Try out other TextBoxes in this way. Add more TextBoxes, if you like, and try out whether the newly added TextBoxes also respond to the AfterUpdate event.

The After Update Event fires only when you enter a value or edit an existing value and leave the Text Box.

Adding the LostFocus Event

But what if a particular Text Box must not be left blank when the cursor moves away from it (on the LostFocus event) without entering any value?

In such a case, when the insertion point leaves that Text Box, the Form should trigger its LostFocus event. This event must then be captured in the Class Module, and a message should be displayed if the Text Box is empty.

To implement this behavior, we need to make corresponding changes in both the Form Module and the Class Module.

In the Form_Load() Event Procedure, checks whether TextBox8 (on my Form, the second TextBox at the left) is the current control, then adds ta(cnt).Txt.OnLostFocus = "[Event Procedure]"  to trigger the LostFocus() Event on TextBox8. 

Add the following lines to the Form_Load() Event Procedure, replacing Text8 with the Text Box name from your Form.

If ctl.Name = "Text8" Then
   ta(cnt).Txt.OnLostFocus = "[Event Procedure]"
End If

The current control's name is Text8 then ta(cnt).Txt.OnLostFocus Event is also set to invoke this Event.  So Text8 will fire both AfterUpdate and LostFocus Events.   

The changed Form_Load() Event Procedure Code is given below:

Private Sub Form_Load()
Dim cnt As Integer
Dim ctl As Control

For Each ctl In Me.Controls
  If TypeName(ctl) = "TextBox" Then
     cnt = cnt + 1
     ReDim Preserve ta(1 To cnt)
     Set ta(cnt).Txt = ctl
     ta(cnt).Txt.AfterUpdate = "[Event Procedure]"
     
     If ctl.Name = "Text8" Then
       ta(cnt).Txt.OnLostFocus = "[Event Procedure]"
     End If
     
  End If
Next
End Sub

A Subroutine for LostFocus Event is required in the ClstxtArray1 Class Module to capture the Event from the Text8 Text Box.

The Subroutine code to handle the LostFocus Event is given below:

Private Sub Txt_LostFocus()
Dim tbx As Variant
tbx = Nz(Txt.Value, "")

If Len(tbx) = 0 Then
  MsgBox Txt.Name & " is Empty.", vbInformation, Txt.Name
End If
End Sub

If some value is entered into the Text8 TextBox, then the MsgBox will not appear for the LostFocus Event.  If the TextBox8 is empty, then the LostFocus Event will fire.  The full Class Module Code is given below:

Option Compare Database
Option Explicit

Public WithEvents Txt As Access.TextBox

Private Sub Txt_AfterUpdate()
Dim txtName As String, sngval As Single
Dim msg As String

txtName = Txt.Name
sngval = Nz(Txt.Value, 0)

msg = txtName & " _AfterUpdate. :" & sngval
MsgBox msg, vbInformation, Txt.Name

End Sub

Private Sub Txt_LostFocus()
Dim tbx As Variant
tbx = Nz(Txt.Value, "")

If Len(tbx) = 0 Then
  MsgBox Txt.Name & " is Empty.", vbInformation, Txt.Name
End If
End Sub

Moving to the Next Stage

Each TextBox on a Form may accept different types of information, each with its own validation criteria. The data entered in every TextBox must be individually validated to ensure it meets the specified requirements, and appropriate action should be taken if any entry fails to comply.

The above code displays a generalized message for all TextBoxes from the subroutine.  That may not be sufficient for real applications.  We need to write a specific Code for each TextBox when the above Event fires from each TextBox.

We will continue this discussion next week for more details on this topic.

Links to WithEvents ...Tutorials.

  1. WithEvents MS-Access Class Module Tutorial
  2. WithEvents and Defining Your Own Events
  3. withevents Button Combo List TextBox Tab
  4. Access Form Control Arrays and Event Capturing
  5. Access Form Control Arrays and Event-2
  6. Access Form Control Arrays and Event-3
  7. WithEvents in Class Module for Sub-Form TextBox Events
  8. WithEvents in Class Module and Data Entry
  9. WithEvents and Access Report Event Sink
  10. WithEvents and Report Lines Hiding
  11. WithEvents and Report Lines Highlighting
  12. Withevents TextBox and Command Button Arrays
  13. Withevents TextBox CommandButton Dictionary
  14. Withevents and all Form Control Types

Share:

No comments:

Post a Comment

Comments subject to moderation before publishing.

PRESENTATION: ACCESS USER GROUPS (EUROPE)

Translate

PageRank

Post Feed


Search

Popular Posts

Blog Archive

Powered by Blogger.

Labels

Forms Functions How Tos MS-Access Security Reports msaccess forms Animations msaccess animation Utilities msaccess controls Access and Internet MS-Access Scurity MS-Access and Internet Class Module External Links Queries Array msaccess reports Accesstips WithEvents msaccess tips Downloads Objects Menus and Toolbars Collection Object MsaccessLinks Process Controls Art Work Property msaccess How Tos Combo Boxes Dictionary Object ListView Control Query VBA msaccessQuery Calculation Event Graph Charts ImageList Control List Boxes TreeView Control Command Buttons Controls Data Emails and Alerts Form Custom Functions Custom Wizards DOS Commands Data Type Key Object Reference ms-access functions msaccess functions msaccess graphs msaccess reporttricks Command Button Report msaccess menus msaccessprocess security advanced Access Security Add Auto-Number Field Type Form Instances ImageList Item Macros Menus Nodes RaiseEvent Recordset Top Values Variables Wrapper Classes msaccess email progressmeter Access2007 Copy Excel Export Expression Fields Join Methods Microsoft Numbering System Records Security Split SubForm Table Tables Time Difference Utility WScript Workgroup database function msaccess wizards tutorial Access Emails and Alerts Access Fields Access How Tos Access Mail Merge Access2003 Accounting Year Action Animation Attachment Binary Numbers Bookmarks Budgeting ChDir Color Palette Common Controls Conditional Formatting Data Filtering Database Records Defining Pages Desktop Shortcuts Diagram Disk Dynamic Lookup Error Handler External Filter Formatting Groups Hexadecimal Numbers Import Labels List Logo Macro Mail Merge Main Form Memo Message Box Monitoring Octal Numbers Operating System Paste Primary-Key Product Rank Reading Remove Rich Text Sequence SetFocus Summary Tab-Page Union Query User Users Water-Mark Word automatically commands hyperlinks iSeries Date iif ms-access msaccess msaccess alerts pdf files reference restore switch text toolbar updating upload vba code