Microsoft Access VBA Tutorials for self-paced learning, Class Modules, SQL Techniques, and AI Integration Guides.

Showing posts with label Property. Show all posts
Showing posts with label Property. Show all posts

Access Form Control Arrays and Event-3

Introduction.

This article builds on last week’s topic, focusing on how to capture TextBox AfterUpdate and LostFocus events and validate their Values through a class module array.

In the previous session, we stopped short of discussing how to move all the VBA code from the Form_Load() event procedure into a separate class module, leaving the form module almost free of event procedures. The VBA code in this new structure will define the TextBox control Class Module Array and handle the required built-in events within their respective array elements. This approach will leave only three or four lines of code in the form module, while shifting all the logic into a derived class module object.

Earlier, we had created Derived Class Objects by using a class module as a base class and extending its functionality. We will apply the same concept here as well.

We are using TextBox controls first—rather than other controls on the form—for these array-based examples because they are the most commonly used controls. A TextBox supports several events, including BeforeUpdate, AfterUpdate, LostFocus, Enter, Exit, KeyDown, KeyUp, and OnKey. Depending on the requirements, we can choose to invoke one or more of these events from within the derived class object.

We can define a set of standard event procedures in the TextBox class module to handle commonly used events such as BeforeUpdate, AfterUpdate, Enter, or Exit. However, only the required event handlers need to be activated for each TextBox control. This can be done during the array element initialization by assigning:

obj.txt.EventName = "[Event Procedure]"

This approach enables the selective activation of event procedures for individual TextBox instances.

Since each Form may require different validation rules or processing logic, the code inside these class event procedures often needs customization. An effective way to manage this is to create a TextBox Class Module Template and incorporate the most frequently used event procedures. For a new form, simply copy this template and modify it to suit the specific requirements of the TextBox controls on that form.

Other control types on a form—such as Command Buttons, Combo Boxes, and List Boxes—generally rely on fewer events, most commonly Click or DblClick. We will examine managing these other control types in arrays later.

Eventually, we will also explore whether there are more effective approaches than arrays for managing multiple instances of different types of controls on the same form.

Moving Form's Class Module Code to Derived Class Module

Returning to today’s topic—moving the Form Module code into a separate Class Module—we will create a new Derived Class Module Object based on the existing ClsTxtArray1_2 Class Module as the Base Class. The code currently in the Form_Load() event procedure of the Form Module will be relocated into this new Derived Class.

If you haven’t already downloaded last week’s demo database, please do so using the link provided before proceeding. We will make copies of the relevant Modules and Forms to modify the code, ensuring that both the original and the updated versions of the code and forms are available within the same database. After making these changes, you can immediately run the forms to observe how the new implementation works.


After downloading the database, open it in Microsoft Access. You can then open the Form Module and review its code.

Next, copy the ClsTxtArray1_2 Class Module into a new Class Module named ClsTxtArray1_3, without making any changes to its code. Similarly, make a copy of the existing form and rename it TxtArray1_3Header. Any modifications will be done on these new copies, ensuring that the original Form and Class Module remain intact and unaltered.

We will use last week’s sample Form (shown in the image below) along with its Form Module VBA code, also reproduced below for your reference.


Option Compare Database
Option Explicit

Private Ta() As New ClsTxtArray1_2

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
     
     If ctl.Name = "Text8" Then
       Ta(cnt).Txt.OnLostFocus = "[Event Procedure]"
     Else
       Ta(cnt).Txt.AfterUpdate = "[Event Procedure]"
     End If
     
  End If
Next
End Sub

Make a Copy of the above Form and name it as frmTxtArray1_3Header.

Create a new Class Module with the name ClsTxtArray1_3.  Copy the VBA Code from the ClsTxtArray1_2 Class Module and paste it into the new Module.

Last week’s Class Module ClsTxtArray1_2  Code is reproduced below for reference.

Option Compare Database
Option Explicit

Private WithEvents Txt As Access.TextBox

Public Property Get mTxt() As Access.TextBox
  Set mTxt = Txt
End Property

Public Property Set mTxt(ByRef txtNewValue As Access.TextBox)
  Set Txt = txtNewValue
End Property

Private Sub Txt_AfterUpdate()
Dim txtName As String, varVal As Variant
Dim msg As String

txtName = Txt.Name
msg = ""
Select Case txtName
    Case "Text0"
        'Valid value range 1 to 5 only
        varVal = Nz(Txt.Value, 0)
        If varVal < 1 Or varVal > 5 Then
           msg = "Valid Value Range 1-5 only: " & varVal
        End If
    Case "Text8"
        'validates in LostFocus Event
    Case "Text10"
        'valid value 10 characters or less
        'Removes extra characters, if entered
        varVal = Nz(Txt.Value, "")
        If Len(varVal) > 10 Then
           msg = "Max 10 Characters Only. " & varVal
           Txt.Value = Left(varVal, 10)
        End If
    Case "Text12"
        'Date must be <= today
        'Future date will be replaced with Today's date
        varVal = DateValue(Txt.Value)
        If varVal > Date Then
          msg = "Future Date Invalid. " & varVal & vbCr & "Corrected to Today's Date."
          Txt.Value = Date
        End If
    Case "Text14"
        'A 10 digit number only valid
        varVal = Trim(Str(Nz(Txt.Value, 0)))
        If Len(varVal) <> 10 Then
          msg = "Invalid Mobile Number: " & varVal
        End If
End Select

If Len(msg) > 0 Then
    MsgBox msg, vbInformation, Txt.Name
End If

End Sub

Private Sub Txt_LostFocus()
Dim tbx As Variant, msg As String

tbx = Nz(Txt.Value, "")

msg = ""
If Len(tbx) = 0 Then
  msg = Txt.Name & " cannot be left Empty."
  Txt.Value = "XXXXXXXXXX"
End If

If Len(msg) > 0 Then
   MsgBox msg, vbInformation, Txt.Name
End If

End Sub

The Derived Class: ClsTxtArray1_3Header

The ClsTxtArray1_3 Class Module will be used as the Base Class for our new Derived Class Module. We will name it ClsTxtArray1_3Header, with extended functionality.

Create a new Class Module with the name ClsTxtArray1_3Header. The Derived Class Module, with its Properties and Property Procedures, is given below:

Option Compare Database
Option Explicit

Private Ta() As New ClsTxtArray1_3
Private frm As Access.Form

Public Property Get mFrm() As Access.Form
  Set mFrm = frm
End Property

Public Property Set mFrm(vFrm As Access.Form)
  Set frm = vFrm
  Call Class_Init
End Property

Private Sub Class_Init()
 'Form Module Code goes here
End Sub

Copy and paste the above code into the new Header Class Module you have created.

Check the first two Property declarations.  First Property ClsTxtArray1_3 Class Object is instantiated as an undefined Array: Ta() – Ta stands for TextBox-Array.

The next property, frm, is introduced to give this Class Module access to the Form from which we plan to transfer the existing VBA code. All actions that were previously handled in the Form Module will now be managed here.

We will create Get and Set Property procedures to handle references to the Form. It will be a Set property (not a Let property) because we are passing a Form object, not a simple value, to it.

Immediately after the Form’s reference is received in the Set Property Procedure, we call the Class_Init() (this is not the same as Class_Initialize(), which runs automatically when a Class Object is instantiated) sub-routine to run the same code moved here from the Form’s Module.

Now, we will transfer the following Code from the Form_Load() Event Procedure into the Class_Init() sub-routine and make changes in the Form Module.

Copy and paste the following lines of code from the Form Module into the Class_Init() sub-routine, replacing the Comment line:

Dim cnt As Integer
Dim ctl As Control

For Each ctl In frm.Controls
  If TypeName(ctl) = "TextBox" Then
     cnt = cnt + 1
     ReDim Preserve Ta(1 To cnt)
     Set Ta(cnt).Txt = ctl
     
     Select Case ctl.Name
        Case "Text8"
            'Only LostFocus Event
            Ta(cnt).Txt.OnLostFocus = "[Event Procedure]"
     Case Else
            'All other text Boxes wiil trigger AfterUpdate Event
            'i.e. entering/editing value in textbox
            Ta(cnt).Txt.AfterUpdate = "[Event Procedure]"
     End Select
     
  End If
Next

Form's Class Module Code

Open the Form frmTxtArray1_3Header in the design view. Display the Code Module. Copy and paste the following Code into the Form's Module, overwriting the existing Code:

Option Compare Database
Option Explicit

Private T As New ClsTxtArray1_3Header

Private Sub Form_Load()
  Set T.mFrm = Me
End Sub

We have instantiated the Derived Class ClsTxtArray1_3Header in Object Variable T. With the statement Set T.mFrm = Me, the active form's reference is passed to the T.mFrm() Set Property Procedure.

Immediately after this action, on the Form_Load () Event procedure, the Class_Init() sub-routine runs in the ClsTxtArray1_3Header Class, and the txtArray1_3 Class Object array elements are created by invoking Events for each Text Box on the Form.  Hope you are clear with the Code above.

If you are ready to modify the Form Module, compile the database to ensure that everything is in order.

Save and close the Form, open it in Normal View, and try out each TextBox, and ensure that its Event sub-routines are performing as expected.

Replacing Class Object Array with Collection Object Items

The TextBox Class Object Array method works well for handling multiple TextBoxes. However, creating an array requires a counter variable, resizing the array for each new element while preserving the existing elements, and incrementing the counter for the next TextBox on the form, and so on.

When a form contains multiple controls of other types—such as Command Buttons, ComboBoxes, or ListBoxes—we would need to create separate arrays for each control type, each with its own counter and resizing logic in the class module. We will explore this approach in a future example.

A more efficient way to handle such complex scenarios is to use a Collection object instead of arrays. We will demonstrate this approach here, with TextBoxes, so you can get a practical feel for managing multiple controls using collections.

  1. Create a new Derived Class Module with the name ClsTxtArray1_3Coll.
  2. Copy and Paste the following Code into the Class Module:
Option Compare Database
Option Explicit

Private C As New Collection
Private Ta As ClsTxtArray1_3
Private frm As Access.Form

Public Property Get mFrm() As Access.Form
  Set mFrm = frm
End Property

Public Property Set mFrm(vFrm As Access.Form)
  Set frm = vFrm
  Call Class_Init
End Property

Private Sub Class_Init()
'-----------------------------
'Usage of Collection Object, replacing Arrays
'-----------------------------
Dim ctl As Control

For Each ctl In frm.Controls
  If TypeName(ctl) = "TextBox" Then
     
     Set Ta = New ClsTxtArray1_3  'instantiate TextBox Class
     Set Ta.Txt = ctl 'pass control to Public Class Property
     
     Select Case ctl.Name
        Case "Text8"
            'Only LostFocus Event
            Ta.Txt.OnLostFocus = "[Event Procedure]"
     Case Else
            'All other text Boxes wiil trigger AfterUpdate Event
            'i.e. entering/editing value in textbox
            Ta.Txt.AfterUpdate = "[Event Procedure]"
     End Select
     C.Add Ta 'add to Collection Object
  End If
Next

End Sub

A Collection Object Property is declared and instantiated at the beginning. 

The TextBox Class Module is defined, not instantiated, in the Object Variable Ta.

The TextBox Class Ta Object is instantiated within the Control Type Test condition.  A new Ta Object instance is created for each TextBox on the Form.

After enabling the Events, the Ta Class Object is added to the Collection Object as its Item.

This method is repeated by adding a new instance of the TextBox class Object for each TextBox on the Form, with its required Events enabled, as a new Item to the Collection Object.  The Code is cleaner than the Array method.

Make a copy of the Form frmTxtArray1_3Header with the name frmTxtArray1_3Coll. 

  1. Open it in Design View and display the Form's Code Module.
  2. Copy and paste the Following Code into the Form Module, replacing the existing Code.
Option Compare Database
Option Explicit

Private Ta As New ClsTxtArray1_3Coll

Private Sub Form_Load()
  Set Ta.mFrm = Me
End Sub

The only change here is the name of the derived object, which has been updated to ClstxtArray1_3Coll. After making this change, recompile the database.

Save the Form, open it in Normal View. Test the TextBoxes as before.

It should work as before.

Downloads

You can download the database, which includes all the modules and forms with the suggested changes applied.



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:

Access Form Control Arrays and Event-2

Control Arrays and Events-2.

Last week, we learned how to create a Class Object Array for TextBoxes on the Form. The built-in AfterUpdate and LostFocus events raised from the TextBoxes on the Form are captured by their corresponding elements in the Class Object Array. Each element then executes its own AfterUpdate() or LostFocus() subroutine, instead of running the code within the Form’s Class Module as we normally would.

For example, the AfterUpdate event of the first TextBox is captured by the first element of the Class Object Array, and its AfterUpdate () subroutine is executed there. In the same way, events from other TextBoxes are also handled by their respective Class Object Array elements.

If you are new to this topic, please refer to the earlier pages using the links below to understand the step-by-step transition of code from one stage to the next.

  1. withevents Button Combo List TextBox Tab
  2. Access Form Control Arrays and Event Capturing

The AfterUpdate and LostFocus event handler code we wrote earlier in the Class Module was generic in nature and applied to all TextBox controls on the Form. These were test subroutines created solely to experiment whether the events triggered from each TextBox on the Form were being correctly captured by their respective Class Module array elements.

Data Validation Checks

Now, it’s time to define specific data validation rules for each TextBox on the form and ensure that the user is notified whenever a rule is violated.

To make sure these rules are clear, I’ve placed descriptive labels above each Text Box on the form. These labels indicate how the values entered in the TextBoxes will be validated within the Class Module array through their AfterUpdate and LostFocus events.

An image of the form, showing the TextBoxes along with their corresponding validation rule labels, is provided below.


    Note: This setup is intended purely for demonstration purposes, so the validation rules are not strictly enforced. The second TextBox accepts any type of input—whether text, numbers, or other characters. The Mobile Number field, however, checks only the length of the entered value. Additionally, the Mobile Number TextBox has an Input Mask applied to restrict input to digits only.

  1. The first TextBox accepts only values between 1 and 5. Any value outside this range triggers an error message.

  2. The second TextBox is validated in the LostFocus event to ensure it is not left blank. If it is empty, an error message is displayed, and a sample string is inserted automatically.

  3. The third TextBox accepts text or numbers up to 10 characters long. Any extra characters beyond this limit are removed, and the field is updated accordingly. If left blank, no error is shown.

  4. The fourth TextBox is a date field. Any date later than today is considered invalid.

  5. The last TextBox accepts only a 10-digit number.

The Class Module Changes.

We will write the VBA code for the above simple validation checks in the class module.

The earlier version of the VBA code in the class module  ClstxtArray1 is given below for reference.

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

The Event-based Sub-Routine

Check the Txt_AfterUpdate() event procedure. This single event handler in the class module receives the AfterUpdate event from all the text boxes on the form. The txt.Name property identifies which text box triggered the event, while the txt.Value property provides the value entered in that text box. Using these two properties, you can write specific validation logic for the contents of each text box.

The text box validation sample VBA code of the txt_AfterUpdate() Event Sub-routine is given below.

Private Sub Txt_AfterUpdate()
Dim txtName As String, varVal As Variant
Dim msg As String

txtName = Txt.Name
msg = ""
Select Case txtName
    Case "Text0"
        varVal = Nz(Txt.Value, 0)
        If varVal < 1 Or varVal > 5 Then
           msg = "Valid Value Range 1-5 only: " & varVal
        End If
    Case "Text8"
        ' validation in OnLostFocus Event
    Case "Text10"
        varVal = Nz(Txt.Value, "")
        If Len(varVal) > 10 Then
           msg = "Max 10 Characters Only. " & varVal
           Txt.Value = Left(varVal, 10)
        End If
    Case "Text12"
        varVal = DateValue(Txt.Value)
        If varVal > Date Then
          msg = "Future Date Invalid. " & varVal
        End If
    Case "Text14"
        varVal = Trim(Str(Nz(Txt.Value, 0)))
        If Len(varVal) <> 10 Then
          msg = "Invalid Mobile Number: " & varVal
        End If
End Select

If Len(msg) > 0 Then
    MsgBox msg, vbInformation, Txt.Name
End If

End Sub

The text box name (Txt.Name) received from the AfterUpdate Event is checked in the Select Case. . . End Select structure.  Depending on the text box name and the TextBox value (Txt.Value), the validation check is performed; if Invalid, an appropriate message is displayed.

On the Form_Load() Event Procedure, we have added the OnLostFocus() Event only for TextBox8 on the form.  When the insertion point leaves this text box, the LostFocus Event fires and is captured in the Private Sub txt_LostFocus()  subroutine of the class module.  If the TextBox is empty, the sample text string “XXXXXXXXXX” is inserted into TextBox8, followed by an error message.

The LostFocus subroutine is given below:

Private Sub Txt_LostFocus()
Dim tbx As Variant, msg As String

tbx = Nz(Txt.Value, "")

msg = ""
If Len(tbx) = 0 Then
  msg = Txt.Name & " cannot leave it Empty."
  Txt.Value = "XXXXXXXXXX"
End If

If Len(msg) > 0 Then
   MsgBox msg, vbInformation, Txt.Name
End If

End Sub

Here, we are not testing for TextBox8, as we did in the AfterUpdate() event procedure, because we have not added the LostFocus Event for any other TextBox. 

Did you notice that the statement Txt.value = "XXXXXXXXXX" writes the string back to the same TextBox from which the event was captured? But what if we need to access another control on the form to read or write data there?

To achieve this, we must introduce a Form object property in the class module. We will implement this along with the upcoming code changes, as part of our future plan is to move all actions from the form module to the class module.

The full VBA Code of the Class Module: ClsTxtArray1_2 is given below:

Option Compare Database
Option Explicit

Public WithEvents Txt As Access.TextBox

Private Sub Txt_AfterUpdate()
Dim txtName As String, varVal As Variant
Dim msg As String

txtName = Txt.Name
msg = ""
Select Case txtName
    Case "Text0"
        varVal = Nz(Txt.Value, 0)
        If varVal < 1 Or varVal > 5 Then
           msg = "Valid Value Range 1-5 only: " & varVal
        End If
    Case "Text8"
        ' validation in OnLostFocus Event
    Case "Text10"
        varVal = Nz(Txt.Value, "")
        If Len(varVal) > 10 Then
           msg = "Max 10 Characters Only. " & varVal
           Txt.Value = Left(varVal, 10)
        End If
    Case "Text12"
        varVal = DateValue(Txt.Value)
        If varVal > Date Then
          msg = "Future Date Invalid. " & varVal
        End If
    Case "Text14"
        varVal = Trim(Str(Nz(Txt.Value, 0)))
        If Len(varVal) <> 10 Then
          msg = "Invalid Mobile Number: " & varVal
        End If
End Select

If Len(msg) > 0 Then
    MsgBox msg, vbInformation, Txt.Name
End If

End Sub

Private Sub Txt_LostFocus()
Dim tbx As Variant, msg As String

tbx = Nz(Txt.Value, "")

msg = ""
If Len(tbx) = 0 Then
  msg = Txt.Name & " cannot leave it Empty."
  Txt.Value = "XXXXXXXXXX"
End If

If Len(msg) > 0 Then
   MsgBox msg, vbInformation, Txt.Name
End If

End Sub

The Form Module VBA Code

The form module code remains unchanged from last week’s example, except that the class module name has been updated to ClstxtArray1_2.

I maintain the class module code from earlier articles as separate versioned copies, which is why the class module name has changed here.

Additionally, I made a minor change in the form module code for the TextBox8 control — it now raises only the LostFocus event. In the earlier version, the code triggered both the AfterUpdate and LostFocus events.

Option Compare Database
Option Explicit

Private Ta() As New ClsTxtArray1_2

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
     
     If ctl.Name = "Text8" Then
       Ta(cnt).Txt.OnLostFocus = "[Event Procedure]"
     Else
       Ta(cnt).Txt.AfterUpdate = "[Event Procedure]"
     End If    
  End If
Next
End Sub

Downloads

We have now moved all the event-handling code—normally written in the form’s class module—into a separate class module, keeping all the underlying actions completely hidden from the user.

However, if you look at the current Form_Load() event procedure, you’ll notice that there’s still quite a bit of code left in the form module.

In the coming weeks, we’ll explore techniques to shift almost all this remaining code into the Standalone Class Module, leaving only three or four lines in the Form Module.

In the meantime, you can download the demo database from the links below, try it out, and study the code to understand how it works.



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:

Ms-Access Class Module and Collection Object

Class Object Instances in Collection Object.

Last week, we had a brief introduction to the fundamentals of the Collection object. We learned how to add items to a Collection and retrieve them using various methods. In our earlier examples, we used mixed data types as Collection items, but those were intended purely for demonstration purposes.

In practical use, a Collection typically holds items of a single data type or objects (such as class modules) along with their properties and methods.

We have already become familiar with the following Collection object methods: 

  • Add – Adds an item to the Collection.

  • Count – Returns the total number of items in the Collection.

  • Item – Takes an item’s sequence number (index) as a parameter and returns that specific item.

  • Remove – Takes an item’s sequence number (index) as a parameter and deletes that item from the Collection.

The Add method also has four parameters—Item, Key, Before, and After—whose usage we explored earlier.

Now, let us move on to a real-world example of using the Collection object.

The sample VBA code below demonstrates how to use the ClsArea class (which we created earlier to calculate the area of rectangular rooms or objects) with a Collection object. Previously, we used an array of ClsArea class objects to calculate the area of several rooms. This time, we will use a Collection object instead of an array to create and store details of multiple rooms. We can then retrieve these items as needed and display their details in the Debug window.

Adding a Class Object to the Collection.

  1. Open your database and display the VBA Window (ALT+F11).

  2. Copy and paste the following VBA Code into a Standard Module:

    Public Sub Coll_TestOne()
    Dim Arr As ClsArea
    Dim objColl As Collection, obj As Object
    Dim j As Integer, iMax As Integer
    Dim strName As String
    
    iMax = 5
    
    'instantiate the Collection object in memory
    Set objColl = New Collection
    
    'Create a Collection of five ClsArea Object
    'with it's Property values filled-in
    For j = 1 To iMax
        Set Arr = New ClsArea
        
        strName = "Bed Room" & j
        Arr.strDesc = strName
        Arr.dblLength = 20 + j
        Arr.dblWidth = 15 + j
        
      objColl.Add Arr 'Add current Class Object to Collection
      
        Set Arr = Nothing
    Next
    
    'Printing Section
    Debug.Print "Description", "Length", "Width", "Area"
    For Each obj In objColl
        With obj
            Debug.Print .strDesc, .dblLength, .dblWidth, .Area
        End With
    Next
    
    Set objColl = Nothing
    
    End Sub
The VBA Code Line By Line.

Before running the Code, let us take a look at each line and see what it does.
The first line declares Arr as a ClsArea object. The next line declares it ObjColl as an Collection object and Obj as a generic Object type. The following line declares two integer-type variables, and the line after that declares a String variable.

The iMax variable is initialized with the value 5 to control the For...Next loop. We will create five ClsArea objects, assign their property values, and then add them one by one to the Collection object.
Next, the ObjColl collection object is instantiated in memory.

A For...Next loop is then set up to run from 1 to iMax (or 5). Within the loop, it Arr is instantiated as a new ClsArea class object in memory, ready to receive its first set of property values. The room description will be created by combining the constant text "Bedroom" with the loop control variable j, resulting in room names from "Bedroom1" to "Bedroom5".

Similarly, the dblLength property value of each room will be set to 20 + j (resulting in values from 21 to 25), and the dblWidth property will be set to 15 + j (resulting in values from 16 to 20).
After assigning the property values to Arr, the class object is added to the ObjColl collection using the Add method.

The statement Set Arr = Nothing then releases the current class object from memory.
The For...Next loop continues this process to create and add four more ClsArea objects to the collection.

Next, another For ... Next loop in the printing section uses the Obj object variable to iterate through each item in the collection and print the ClsArea object property values in the Debug Window.

  • Click somewhere in the middle of the Code.
  • Press CTRL+G to display the Debug Window.
  • Click somewhere in the code and press the F5 Key to run the Code.
  • The output listing in the Debug Window will be as shown below:

    Description   Length        Width         Area
    Bed Room1      21            16            336 
    Bed Room2      22            17            374 
    Bed Room3      23            18            414 
    Bed Room4      24            19            456 
    Bed Room5      25            20            500 
    

    We have not provided the second parameter (Key value) in the above example. In the printing section, an object variable is used to retrieve each ClsArea Class object from the Collection in the same order in which they were added, and then print their property values in the Debug Window.

    The following code snippet can be used as a replacement in the above program to retrieve each item from the Collection object. This version uses the item’s sequence number as a parameter to the Item method to fetch each object, preserving the order in which they were added to the collection.

    'Printing Section
    Debug.Print "Description", "Length", "Width", "Area"
    For j = 1 To objColl.Count
        With objColl.item(j)
            Debug.Print .strDesc, .dblLength, .dblWidth, .Area
        End With
    Next
    

    The number of items in the collection is determined by the expression ObjColl.Count in the For... Next loop.

    You may insert a Stop statement above the printing section and run the code. When the program pauses at the Stop statement, open the Locals Window from the View menu.

    Click the plus symbol [+]ObjColl to expand it and display the ClsArea items stored in the Collection.

    Next, click the plus symbol [+] Item 1 to expand the first item and view its ClsArea object properties and their current values.

    Notice that the dblLength property value is shown as 21. We will now attempt to change this value by typing an expression directly in the Immediate (Debug) Window.

    Type the following expression in the Debug Window and press Enter:

    ObjColl.Item(1).dblLength = 50

    Check the Locals Window now — you will see that the value 21 has changed to 50. This demonstrates that you can overwrite the property values of an object already stored in the collection. However, you cannot directly replace the object item itself in the collection.

    If you want to replace an entire object item, you must first remove the existing item from the collection by specifying its sequence number as a parameter (for example: ObjColl.Remove 1). Then, create a new object with the required changes and add it back to the collection.

    To place a new item back in the same position where the old item was removed, you can use the Before or After parameter of the Add method along with the appropriate item number.

    For more details, refer to last week’s article “MS-Access and Collection Object Basics” for a clear explanation of the Before and After parameter usage of the Add method.

    Save to Collection with Key.

    Let us try another example by making a few changes to the previous code. This time, we will add items to the Collection Object using Key values. In the printing section, we will retrieve the ClsArea Class Object items from the Collection by referencing their Key values instead of their index numbers.

    Copy and Paste the following Code into a Standard Module:

    Public Sub Coll_TestTwo()
    
    Dim Arr As ClsArea
    Dim objColl As Collection
    Dim j As Integer, obj As Object
    Dim iMax As Integer
    Dim Desc As String, strKey As String
    
    iMax = 5
    'instantiate Collection Object
    Set objColl = New Collection
    
    For j = 1 To iMax
    'instantiate a temporary ClsArea Object
        Set Arr = New ClsArea
        
        Desc = "Bed Room" & j
     'Assign Property Values
        Arr.strDesc = Desc
        Arr.dblLength = 20 + j
        Arr.dblWidth = 15 + j
        
       On Error Resume Next
    'Validate Collection Key, ClsArea Object with the same Key exists or not
       Set obj = objColl.Item(Desc)
       
       If obj Is Nothing Then ' doesn't exists, Add the ClsArea Instance
          objColl.Add Arr, Desc 'Add Item to Collection with KEY parameter
       Else
          MsgBox "Error: " & Desc & " Already Exists."
       End If
       
       On Error GoTo 0
       Set Arr = Nothing 'release temporary ClsArea Object
    Next
    
    'Print items in reverse order
    Debug.Print
    For j = objColl.Count To 1 Step -1
        strKey = "Bed Room"  & j
        
        Set obj = objColl.Item(strKey) 'access items with KEY value
      
        With obj
             Debug.Print .strDesc, .dblLength, .dblWidth, .Area
        End With
    Next
    
    Set objColl = Nothing
    End Sub 

    We have introduced two additional String variables, including Desc, to store the item description for the ClsArea object’s Arr.strDesc property. This same description will also serve as the Key value in the Add method.

    The strKey variable will be used when retrieving each ClsArea object from the Collection by its key. Although we could reuse the Desc variable for this purpose, we use a separate strKey variable for better clarity.

    The statement objColl.Add Arr, Desc adds the ClsArea object instance Arr to the Collection, using the description (for example, "Bedroom1") stored in the Desc variable as the key for this first item.

    Other Syntax variants of the above statement are given below for reference.

    objColl.Add item:=Arr, key:=Desc 'statement with Parameter Names
      'OR
    objColl.Add key:=Desc, item:=Arr 'values in improper order with Parameter Names
      '
    1. In the printing section, we have arranged the For ... Next loop to run in reverse order, retrieving items from the Collection by their Key values—from "Bed Room5" to "Bed Room1".

      The statement Set ObjColl = Nothing is used to clear the Collection object from memory.

      However, there are a few limitations when using Key values with a Collection object:

      It accepts only the String data type as a Key value.

    2. Once the Key Value is assigned to a Collection item, you cannot retrieve the Key value itself or create a list of the Keys from the Collection Object.

    3. If you already know the Key Value (e.g., Employee Code), you can retrieve the Item belonging to that Key from the Collection.

    4. If you attempt to add an existing Key Item, it will generate an error.

    A better alternative is the Dictionary Object, which provides greater flexibility for storing and retrieving items or values compared to the Collection object.

    We will explore and experiment with the Dictionary Object and its methods next week.

    CLASS MODULES.

    1. MS-Access Class Module and VBA
    2. MS-Access VBA Class Object Arrays
    3. MS-Access Base Class and Derived Objects
    4. VBA Base Class and Derived Objects-2
    5. Base Class and Derived Object Variants
    6. MS-Access Recordset and Class Module
    7. Access Class Module and Wrapper Classes
    8. Wrapper Class Functionality Transformation

    COLLECTION OBJECT.

    1. MS-Access and Collection Object Basics
    2. MS-Access Class Module and Collection Object
    3. Table Records in Collection Object and Form

    DICTIONARY OBJECT.

    1. Dictionary Object Basics
    2. Dictionary Object Basics-2
    3. Sorting Dictionary Object Keys and Items
    4. Display Records from Dictionary to Form
    5. Add Class Objects as Dictionary Items
    6. Update Class Object Dictionary Item on Form
    Share:

    Base Class and Derived Object Variants

    Encapsulation of Objects.

    Last week, we explored an example where a Base Class Object was passed through a Set Property Procedure, allowing it to become part of another object in memory. The passed object essentially became an extension or child object of the main object. In that earlier program, we passed the child object to the target object during the instantiation phase of our test program and then assigned values to the child object’s properties later in the code.

    In the next example, we will take a slightly different approach.

    For those who would like to go through the earlier Articles on the MS-Access Class Module, the links are given below:

    This time, we will open both objects—ClsArea (the base class) and ClsVolume2 (the target class)—separately in our test program. We will assign values to the ClsArea base class properties before passing it to the ClsVolume2 target class object. Remember, the ClsVolume2 class has only one property, p_Height, and its Volume() method requires the Length and Width values from the base class ClsArea to calculate the volume.

    1. Copy and paste the following sample Test Code into a Standard Module.

      The SetNewVol2_2 Procedure.

      Public Sub SetNewVol2_2()
      'Method 2/2
      Dim CA As ClsArea
      Dim Vol As ClsVolume2
      
      Set CA = New ClsArea
      Set Vol = New ClsVolume2
      
      CA.strDesc = "Bed Room"
      CA.dblLength = 90
      CA.dblWidth = 10
      Stop
      
      
      'Here ClsArea class Object CA is passed to the 
      ‘Property procedure Set CArea of ClsVolume2 object Vol
      Set Vol.CArea = CA 'Pass ClsArea obj to ClsVolume2
      
      Vol.dblHeight = 10 'assign height to ClsVolume2
      
      
      Debug.Print "Description", "Length", "Width", "Area", "Height", "Volume"
      With Vol.CArea
        Debug.Print .strDesc, .dblLength, .dblWidth, .Area(), Vol.dblHeight, Vol.Volume()
      End With
      Stop
      
      Set CA = Nothing
      Set Vol = Nothing
      
      End Sub
      

      VBA Code Review.

      In the first Dim statement, CA is declared as a ClsArea object and Vol as a ClsVolume2 object. The next two statements instantiate these objects in memory.

      The following three statements assign values to the properties of the ClsArea object.

      A Stop statement is then used to pause code execution, allowing us to inspect the object property values in the Locals window.

      Next, the statement Set Vol.CArea = CA assigns the ClsArea object (CA) as a child object of the ClsVolume2 object (Vol).

      After that, the value 10 is assigned to the dblHeight property of the ClsVolume2 object.

      The subsequent statements, placed before the next Stop statement, print the property values from memory to the Debug window.

      Finally, the last two Set statements release both objects from memory before the program ends.

      Display the Locals Window.

    2. Inspecting the Locals Window

      1. Open the Locals Window
        From the View menu in the VBA Editor, select Locals Window.

      2. Run the Code

        • Click anywhere in the middle of the code window.

        • Press F5 to run the program until it pauses at the Stop statement.

        • Alternatively, press F8 to run the code step by step, which lets you observe the changes in the Locals Window at each step.

      3. Expand the Objects
        Click the [+] symbol next to the object names in the Locals Window to expand and display their properties and current values.

      4. Observe Object References

        • Check the CArea and p_Area object references under the Vol object.

        • At this point, their values will show as Nothing because we have not yet passed the CA object to the Vol object.

      5. Continue Running the Code

        • After reviewing the Locals Window, run the code until it pauses at the next Stop statement.

        • Now, the CArea Set Property Procedure assigns the p_Area object reference to the ClsArea object, linking it into the ClsVolume2 object.

      Next, we will try another variation of this example using the same two classes — ClsArea and ClsVolume2 — to demonstrate a slightly different approach.

    New Class Module ClsVolume3.

    1.  Insert a new Class Module and change its name Property Value to ClsVolume3.

    2.  Copy and Paste the following VBA Code into the ClsVolume3 Class Module:

    Option Compare Database
    Option Explicit
    'Method three 
    Private p_Height As Double
    Public p_Area As ClsArea
    
    Public Property Get dblHeight() As Double
        dblHeight = p_Height
    End Property
    
    Public Property Let dblHeight(ByVal dblNewValue As Double)
        p_Height = dblNewValue
    End Property
    
    Public Function Volume() As Double
        Volume = p_Area.dblLength * p_Area.dblWidth * Me.dblHeight
    End Function
    
    Private Sub Class_Initialize()
        Set p_Area = New ClsArea
    End Sub
    
    Private Sub Class_Terminate()
        Set p_Area = Nothing
    End Sub

    In the code, p_Height is declared as a Private Property, while p_Area is declared as a public ClsArea object within the ClsVolume3 class. This means p_Area appears as a property of the ClsVolume3 class, with its own accessible properties and methods for direct Get/Let operations in the user program (from a standard module). Although the ClsArea object is exposed as a public property of ClsVolume3, its internal properties and methods remain encapsulated within the ClsArea class itself.

    It is important to ensure that the ClsArea class is fully developed and free of errors before it is encapsulated into other classes.

    The Class_Initialize() and Class_Terminate() routines handle the lifecycle of the embedded object: The ClsArea object is instantiated in Class_Initialize() when a ClsVolume3 object is created, and released from memory in Class_Terminate() When the user program ends.

    The Testing Program.

    The sample Test VBA Code is given below.

    Copy and paste the code into the Standard Module.

    Public Sub SNewVol3()
    'Here ClsArea class is declared as a Public Property of ClsVolume3
    Dim volm As ClsVolume3
    
    Set volm = New ClsVolume3
    
    volm.p_Area.strDesc = "Bed Room"
    volm.p_Area.dblLength = 15 'assign length
    volm.p_Area.dblWidth = 10 'assign width in clsArea
    volm.dblHeight = 10 'assign height to ClsVolume2
    
    Debug.Print "Description", "Length", "Width", "Area", "Height", "Volume"
    With volm.p_Area
       Debug.Print .strDesc, .dblLength, .dblWidth, .Area, volm.dblHeight, volm.Volume
    End With
    Set volm = Nothing
    
    End Sub
    

    Display the Locals Window (View -> Locals Window), if it is not already open.

    Click somewhere in the middle of the code, and press F8 to execute the VBA Code one line at a time and watch the Locals Window to track what happens at each step.

    All the above variants of the ClsVolume Class have been written with less Code, except the ClsVolume Class.  

    Working with the Recordset Object.

    Next week, we will work with a built-in Object 'DAO.Recordset' and build a Class Module to:

    1. Calculate and update a Field,

    2. Sort the Data,

    3. Print the sorted data in the Debug Window,

    4. And create a Clone of the Table with the data sorted.

    That is a lot of action next week.

    List of All the Links on this Topic.

    1. MS-Access Class Module and VBA
    2. MS-Access VBA Class Object Arrays
    3. MS-Access Base Class and Derived Objects
    4. VBA Base Class and Derived Objects-2
    5. Base Class and Derived Object Variants
    6. MS-Access Recordset and Class Module
    7. Access Class Module and Wrapper Classes
    8. Wrapper Class Functionality Transformation
    9. MS-Access and Collection Object Basics
    10. MS-Access Class Module and Collection Object
    11. Table Records in Collection Object and Form
    12. Dictionary Object Basics
    13. Dictionary Object Basics-2
    14. Sorting Dictionary Object Keys and Items
    15. Display Records from Dictionary to Form
    16. Add Class Objects as Dictionary Items
    17. Update Class Object Dictionary Item on Form

    Share:

    VBA Base Class and Derived Object-2

    Object Encapsulation-2.

    Last week, we created a derived Class, 'lsVolume', using ClsArea as the base class. In that approach, we added property procedures in the derived class to expose the base class’s properties and functions to the user programs. This method, however, requires repeating the base class property procedures in the derived class.

    In this section, we will explore how to create the same derived ClsVolume class without duplicating the property procedures of the ClsArea base class.

    So far, we have learned about Get and Let property procedures in classes. There is also a third type: the Set Property Procedure, which is used to directly assign an object to a class object of the same type.

    Before proceeding, you may want to revisit the earlier pages on this topic if you haven’t already. Links are provided below:


    ClsVolume Class, the Makeover.

    We shall create a different variant of the same ClsVolume Class Module we created last week, using ClsArea as Base Class, with a different approach and less Code. 

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

    Copy and Paste the following Code into the Class Module ClsVolume2 and Save the Module:

    Option Compare Database
    Option Explicit
    'Method two-1
    Private p_Height As Double
    Private p_Area As ClsArea
    
    Public Property Get dblHeight() As Double
        dblHeight = p_Height
    End Property
    
    Public Property Let dblHeight(ByVal dblNewValue As Double)
        p_Height = dblNewValue
    End Property
    
    Public Function Volume() As Double
        Volume = p_Area.dblLength * p_Area.dblWidth * p_Height
    End Function
    
    'The new Get and Set Property Procedure for the ClsArea Object.
    
    Public Property Get CArea() As ClsArea
       Set CArea = p_Area
    End Property
    
    Public Property Set CArea(ByRef AreaValue As ClsArea)
      Set p_Area = AreaValue
    End Property
    
    

    From the Debug menu, select Compile [Project Name] to compile all the VBA code in your database and ensure it is error-free. If any errors are found in other VBA programs, locate and correct them, then recompile the project.

    While unresolved errors will not prevent you from assigning or retrieving values from object properties, the VBA IntelliSense—which displays a list of an object’s properties and functions—will not work properly until the project compiles successfully.

    Seeing the property list appear in IntelliSense is an invaluable aid during coding, especially while learning and experimenting with class objects.

    Get / Set instead of the Get / Let Property Procedure.

    In this version of the ClsVolume class, we have omitted all the property procedures  ClsArea that were present in the previous version. Instead, we use Get and Set property procedures rather than the traditional Get/Let pair.

    Take a look at the declaration: the private member p_Area is declared as a ClsArea class object. Normally, when an object is declared this way, we would create an instance of it in the Class_Initialize() procedure.

    However, in this approach, we have not instantiated it within the class. The plan is to create and populate the ClsArea object in the user program, set its properties with appropriate values, and then pass it to the ClsVolume2 class. The class will then use these values during the final calculation phase.

    Take note of the Set CArea() procedure. Its ByRef parameter, AreaValue, is declared as a ClsArea object. When an ClsArea instance is passed to this property procedure, the object variable AreaValue receives it and assigns it to the private p_Area property of the ClsVolume2 object.

    This mechanism allows the ClsVolume2 class to use an externally created and populated ClsArea object without having to instantiate it internally, maintaining flexibility and reusability.

    The Get CArea() Property procedure returns the Object to the calling program.

    In our earlier programs, we wrote property procedures for individual elements of an object, such as Length, Width, and Height—to assign or retrieve values. In this version, the difference is that we are passing an entire object as a parameter to a Set property procedure.

    To access a property of this passed object—for example, dblLength—we use the syntax CArea.dblLength. Here, the Get/Set property procedure name CArea essentially becomes a child object of the main object when declared in the main program. Its individual properties can then be accessed directly using the object address, such as:

    Vol.CArea.dblLength

    This approach allows the main object to interact with the entire child object and its properties as a single unit, simplifying property management and enhancing reusability.

    A Test Program in Standard Module.

    We will now create a small test program in a Standard Module to verify the functionality of our newly derived class object. ClsVolume2.

    1. Insert a new Standard Module into your project.

    2. Copy and paste the following code into the module.

    3. Save the module before running the program.

    Public Sub SetNewVol2_1()
    'Method 1/2
    Dim Vol As New ClsVolume2
    
    'ClsArea Object instantiated and passed to the
    'Property Procedure Set CArea in ClsVolume2.
    
    Set Vol.CArea = New ClsArea 'declare and instantiate the object in one statement
    
    Stop
    
    Vol.CArea.strDesc = "Bed Room"
    Vol.CArea.dblLength = 90
    Vol.CArea.dblWidth = 10
    
    Vol.dblHeight = 10 'assign height to ClsVolume2
    
    Stop
    
    Debug.Print "Description", "Length", "Width", "Area", "Height", "Volume"
    Debug.Print Vol.CArea.strDesc, Vol.CArea.dblLength, Vol.CArea.dblWidth, Vol.CArea.Area, Vol.dblHeight, Vol.Volume
    
    Set Vol.CArea = Nothing
    Set Vol = Nothing
    
    End Sub
    
    

    Code Review Line by Line.

    Let’s quickly review the VBA code above.

    1. The first line instantiates the ClsVolume2 class with the object name Vol.

    2. After the comment lines, the Set Vol.CArea statement calls the property procedure and passes the newly instantiated ClsArea object as its parameter.

    I included a Stop statement on the next line to pause the program so you can observe how the object is assigned to the CArea property. We’ll explore how to inspect this in memory shortly.

    1. The following four lines assign values to the ClsArea object properties (strDesc, dblLength, dblWidth) and to the dblHeight property of the ClsVolume2 object.

    2. The next Stop statement pauses the program again, allowing you to inspect how these values are stored in memory.

    3. The subsequent line prints the headings in the Debug Window for clarity.

    4. Finally, the last line prints the values of the object properties retrieved from memory, displaying them in the Debug Window.

    Run the Code to the Next Stop Statement

    1. Let’s run the code and inspect the memory to see what happens at each stage where the Stop statements are placed.

      1. Click anywhere in the code and press F5 to run the program. The execution will pause at the first Stop statement.

      2. From the View menu, select Locals Window. This opens a window below the code editor that displays the ClsArea and ClsVolume2 objects, along with their properties and member procedures, as they are stored in memory.

      3. Observe the structure of the objects and how the property values are held. A sample image of the Locals Window is shown below for reference.

      The Locals Window View.


      To give more space for the Locals Window, drag the sizing handles of other windows upward to reduce their height. Alternatively, you can close the Debug Window and press Ctrl+G to bring it back when needed.

      The Locals Window provides a graphical view of all objects and their properties in memory:

      1. The first item with a plus [+] symbol shows the name of the Standard Module the program is running.

      2. The next plus [+] symbol represents the Vol object, which is the instantiated ClsVolume2 object in memory.

      Click the plus [+] symbols to expand each item and display detailed information about the object’s properties and member procedures.

      You will find the next level of Objects and Properties.

      The [+]CArea indicates that this Object has the next level of Properties and their Values.

      The dblHeight Get property Procedure comes directly under the Vol Object.

      The [+]p_Area is the Private Property declared in the ClsArea Class in the ClsVolume2 Class.

      The p_Height is also declared as a private property in the ClsVolume2.

      Click the plus [+] symbols to expand the objects to show their Properties and Values.

      Expanding the [+] CArea node displays the ClsArea object that was passed to the Set CArea() property procedure.

      The expansion of the [+] p_Area view of the ClsArea Property declared as Private.

      Note that the p_Area Private Property of the ClsVolume2 Class Object, and all its elements, are accessible only through the CArea Object Property Get/Set Procedures to the outside world.

      The second column in the Locals Window displays the values assigned to the object’s properties. At this stage, no values have been assigned, so the fields are currently empty.

      The Third Column shows the Data Type or Object Class Module Names.

      Press F5 to run the program till it pauses at the next Stop statement, after assigning some values to the Object Properties.  The program pauses at the Stop statement.  Check the Locals Window for changes in Values.

      In the CArea object, the first two values (90 and 10) and the final `strDesc` variable with the value `"Bedroom"` are assigned via their respective `Get Property` procedures. Likewise, `p_Desc`, `p_Length`, and `p_Width` are assigned through the corresponding `Set Property` procedures to the `p_Area` property of the `ClsVolume2` class object. 

      The p_Area Object of the ClsArea Class is declared as the Private Property of ClsVolume2 and is seen with its Get/Set Property Procedures and assigned values.

      Check the Type Column of [-]CArea and [-]p_Area; both Objects are derived from the ClsArea Base Class.

      Usage of ClsArea and ClsVolume2 Class Objects Differently.

      Next week, we will explore another approach using the same two objects.

      If you’d like to experiment on your own beforehand, here’s a clue to get you started:

      1. Instantiate the ClsVolume2 and ClsArea classes as two different Objects in the Standard Module Program.

      2. Assign values to both Object Properties.

      3. Assign the ClsArea Class Object instantiated in the CArea Object in the ClsVolume2 Class Object, before printing the Values to the Debug Window.

      In this example, we can achieve the same result as in the previous example without having to repeat the Get/Let property procedures in the ClsVolume class module.

      The Links of All the Pages in this Topic.

      1. MS-Access Class Module and VBA
      2. MS-Access VBA Class Object Arrays
      3. MS-Access Base Class and Derived Objects
      4. VBA Base Class and Derived Objects-2
      5. Base Class and Derived Object Variants
      6. Ms-Access Recordset and Class Module
      7. Access Class Module and Wrapper Classes
      8. Wrapper Class Functionality Transformation
      9. Ms-Access and Collection Object Basics
      10. Ms-Access Class Module and Collection Object
      11. Table Records in Collection Object and Form
      12. Dictionary Object Basics
      13. Dictionary Object Basics-2
      14. Sorting Dictionary Object Keys and Items
      15. Display Records from Dictionary to Form
      16. Add Class Objects as Dictionary Items
      17. Add Class Objects as Dictionary Items
      18. Update Class Object Dictionary Item on Form

    Share:

    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 External Links Queries Array Class Module msaccess reports Accesstips msaccess tips WithEvents Downloads Objects Menus and Toolbars MsaccessLinks Process Controls Art Work Collection Object Property msaccess How Tos Combo Boxes ListView Control Query VBA msaccessQuery Calculation Dictionary Object 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 Recordset Top Values Variables msaccess email progressmeter Access2007 Copy Excel Expression Fields Join Methods Microsoft Numbering System RaiseEvent Records Security Split SubForm Table Tables Time Difference Utility WScript Workgroup Wrapper Classes 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 Export 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