Introduction
Last week, we conducted a trial run to add and retrieve Class Objects from Dictionary Object Items.
One important point we emphasized was that each Class Object added to the Dictionary must be created as a new temporary instance of the Class Object every time it is added.
This practice is not exclusive to the Class or Dictionary objects; it is a general best practice that should be followed whenever adding objects to a Collection, Dictionary, or an Object Array, to prevent accidental overwriting of existing instances in memory. A brief review of the correct procedure is given below:
-
Create a temporary Object instance.
-
Assign values to the temporary object’s Properties.
-
Add the temporary object instance as an Item to the Dictionary, Collection, or as an element in the Object Array.
-
Release the temporary object instance from memory so that it can be reused:
Repeat steps 1 to 4 for each new object you want to add.
If you would like to know why we can’t use only one instance of the Class Object to add several Items to the Dictionary Object, visit the page Add Class Object as Dictionary Object Items?
Class Object Instances as Dictionary Items
Now, let us get ourselves prepared for a trial run to add, edit, update, and delete Class Object Items in the Dictionary Object, through an MS-Access Form. We worked with Form and Dictionary Object about two weeks back, by adding and retrieving simple items in the Dictionary Object.
This time, we are dealing with Objects and Properties in Dictionary Objects, not simple Items, with added data management functions. Besides that, when the Form is closed, the Dictionary Item Values (ClsArea Class Object Property Values) are saved to a Table.
We will use our simple ClsArea Class Object, with only three Property Values to fill in (Description, Length, and Width Values), for our trial run.
Even though the Table is used only at the end of the session, we will design a simple table first with the fields: Description (strDesc), Length (dblLength), and Width (dblWidth), matching the Class Module ClsArea Object Property Names in brackets.
- Create a new Table with the name ClsArea with the Field Names and Field Types shown in the Table Design Image shown below. For Numeric Data Fields, select Double Precision Number Type.
Next, we need a Form with the following design to manage the data of the Dictionary Object.
Design a Form with the following Controls (not bound to the Table):
- Combo Box on the Header:
Name Property Value: cboKey
Row Source Type = Value List
- Four Unbound Text Boxes in the Detail Section of the Form with the following names:
strDesc
dblLength
dblWidth
Area
- Create another TextBox to the right of the last TextBox with the Name:
ItemCount
- Create three Command Buttons below the Text Boxes, on the Detail Section, with the Names:
cmdAdd and Caption: Add
cmdEdit and Caption: Edit
cmdDelete and Caption: Delete
- Create two Command Buttons in the Footer Section of the Form with the Names:
cmdSave and Caption: Save to Table
cmdExit and Caption: Exit
- Combo Box on the Header:
The Form’s Normal View Image, with some sample data, is given below:
As the Form control names indicate, you can enter the Property values of the ClsArea Class Object and add the Class Object as an Item to the Dictionary Object.
The value entered in the strDesc Property will be used as the Key for the Dictionary Item.
⚠️ Important: Ensure that the Description (strDesc) values are unique for each item. If a duplicate key is entered, the Dictionary Object will reject it and trigger an error.
(Extensive validation checks have been intentionally omitted in the code to keep it simple.)
You can also retrieve a specific Class Object’s property values from the Dictionary by selecting its Key from the cboKey Combo Box, then:
-
Edit the values directly on the Form and update them back into the Dictionary, or
-
Delete the unwanted item from the Dictionary Object entirely.
The Form Module Event Procedures.
There are several Event Procedures defined in the Form’s Class Module.
A brief explanation of each procedure is provided below.
Option Compare Database Option Explicit Dim C As ClsArea, xC As ClsArea Dim D As Object, Desc As String Dim editFlag As Boolean, saveFlag As Boolean Dim strV As String
All important Objects and Variables are declared in the Global declaration area.
Private Sub Form_Load()
Private Sub Form_Load()
Set D = CreateObject(“Scripting.Dictionary)
Me.cmdEdit.Enabled = False
Me.cmdDelete.Enabled = False
saveFlag = False
End Sub
At the Form Load Event, the Dictionary Object is instantiated.
Edit and Delete Command Buttons are disabled because the Form will be in data entry mode by default. Data save detection flag saveFlag is set to false. The flag will be set to True when the Dictionary Data is saved to the Table, from one of two possible selections of Command Buttons at the Footer of the Form.
Private Sub Form_Current()
Private Sub Form_Current()
Dim o As String
o = cboKeys.RowSource
If Len(o) = 0 Then
Me.cboKeys.Enabled = False
Else
Me.cboKeys.Enabled = True
End If
End Sub
Checks whether the Combo box's Row Source property has any Value in it (when the Form is open, it will be empty); if not, disable the Combo box Control.
Private Sub strDesc_GotFocus()Private Sub strDesc_GotFocus() If editFlag Then Me.cmdAdd.Enabled = False Me.cmdEdit.Enabled = True Me.cmdDelete.Enabled = True Else Call initFields Me.cmdAdd.Enabled = True Me.cmdEdit.Enabled = False Me.cmdDelete.Enabled = False editFlag = False End If End Sub
Checks whether the form is in Edit mode or not. Edit Mode Flag is set when the user clicks the Edit Command Button. This happens after the user selects an item from the Combobox.
If in edit mode, the data entry fields are not cleared, the Edit and Delete Command Buttons are enabled, Add Command Button is disabled.
If in Add mode, then data fields are emptied in preparation for a new Item, the Add Command Button is enabled, and the Edit and Delete Command Buttons are disabled.
Private Sub dblWidth_LostFocus()
Private Sub dblWidth_LostFocus() 'Area is displayed for info purpose only Me!Area = Nz(Me!dblLength, 0) * Nz(Me!dblWidth, 0) End Sub
On the dblWidth Text Box's LostFocus Event, the product of dblLength * dblwidth is displayed in the Area Text Box.
Private Sub cmdAdd_Click()
Private Sub cmdAdd_Click()
'--------------------------------------------------
'1. Add Class Object as Item to Dictionary Object
'2. Update Combobox RowSource Property
'--------------------------------------------------
Dim tmpstrC As String, tmpLength As Double, tmpWidth As Double
Dim flag As Integer, msg As String
Dim cboVal As String, cbo As ComboBox
editFlag = False
Set cbo = Me.cboKeys
tmpstrC = Nz(Me!strDesc, "")
tmpLength = Nz(Me!dblLength, 0)
tmpWidth = Nz(Me!dblWidth, 0)
flag = 0
If Len(tmpstrC) = 0 Then flag = flag + 1
If tmpLength = 0 Then flag = flag + 1
If tmpWidth = 0 Then flag = flag + 1
If flag > 0 Then
msg = "Invalid Data in one or more fields, correct them and retry."
MsgBox msg, , "cmdAdd()"
Exit Sub
End If
Desc = ""
Set C = New ClsArea 'create a new instance
'add Property Values
C.strDesc = tmpstrC
C.dblLength = tmpLength
C.dblWidth = tmpWidth
'add Class Object instance to Dictionary
D.Add tmpstrC, C 'Description is the Key
Call comboUpdate(tmpstrC) 'update description as combobox item
Me.ItemCount = D.Count 'display dictionary Items count
'Call initFields 'set all fields to blanks
Me.strDesc.SetFocus 'make description field current
'Clear Class Object
Set C = Nothing
End Sub
The TextBox values are transferred into temporary variables and checked to see whether any text box is empty or not.
The ClsArea Class Object Properties are assigned with strDesc, dblLength & dblwidth text box values, from temporary variables.
Adds Class Object to Dictionary Object.
Updates the Combo Box with the Dictionary Object Key from the Class Object's Description (strDesc) Value.
The Dictionary Items Count is displayed on the ItemCount Text Box.
The focus is set in the strDesc field. The text boxes are cleared for entry of new values.
Private Sub cboKeys_AfterUpdate()
Private Sub cboKeys_AfterUpdate() On Error Resume Next strV = Me!cboKeys Set xC = D(strV) If Err > 0 Then MsgBox "Item for Key: " & strV & " Not Found!" Exit Sub End If Me!strDesc = xC.strDesc Me!dblLength = xC.dblLength Me!dblWidth = xC.dblWidth Me!Area = xC.Area Me.cmdAdd.Enabled = False Me.cmdEdit.Enabled = True Me.cmdDelete.Enabled = True Me.strDesc.Enabled = False On Error GoTo 0 End Sub
Retrieving the Dictionary Item
After adding several items to the Dictionary Object, you can retrieve any item by selecting its Key from the Combo Box. The corresponding details will be displayed on the Form. In this mode, the Add command button and the strDesc field will remain disabled. The strDesc field will be unlocked only when you click the Edit button.
If you select an invalid Key (for example, a Key value that was changed during earlier edit operations) from the Combo Box, an error message — ‘Item for Key: XXXX not found’ — will be displayed, indicating that the specified item does not exist in the Dictionary Object.
Private Sub cmdEdit_Click()
Private Sub cmdEdit_Click()
'Edit the displayed item properties
Dim cap As String
Dim mDesc As String
editFlag = True
strV = Me!cboKeys
cap = Me.cmdEdit.Caption
Select Case cap
Case "Edit"
Me.strDesc.Enabled = True
Me.cmdAdd.Enabled = False 'when editing Add button is disabled
Me.cmdEdit.Caption = "Update" 'Edit Button Caption is changed
Case "Update" 'Button clicked when Caption is Update
'directly replace the property value in the Item
xC.strDesc = Me!strDesc
xC.dblLength = Me!dblLength
xC.dblWidth = Me!dblWidth
mDesc = Me!strDesc 'changed Description is copied to mDesc
If mDesc <> strV Then 'checks with key in combobox value if not same then
D.Key(strV) = mDesc 'Change Dictionary Key of Item
'update new desc to Combobox
'old desc also remains in combobox
Call comboUpdate(mDesc)
End If
Call initFields
Me.strDesc.SetFocus
Me.cmdAdd.Enabled = True 'Enable Add button to add new item
Me.cmdEdit.Caption = "Edit" 'change caption from Update to Edit
Me.cmdEdit.Enabled = False 'disable Edit Button
Me.cmdDelete.Enabled = False 'disable Edit Button
End Select
End Sub
Editing Dictionary Item
The item retrieved from the Dictionary and displayed on the Form can be edited by clicking the Edit command button. When you click it, the button’s caption changes to Update.
Make the required changes to the fields (including the Description, if needed), and then click the Update button again to save the changes back into the Dictionary Object.
If the strDesc value (the Dictionary Key) is modified, the corresponding old Key in the Dictionary is replaced with the new Description value. The Combo Box will also be updated to reflect the new Key, though the old Key will remain listed in the Combo Box until it is refreshed.
After the update, the data fields are cleared, the Add button is enabled again, and the Edit and Delete buttons are disabled.
Private Sub cmdDelete_Click()
Private Sub cmdDelete_Click()p Dim txtKey As String, msg As String txtKey = Me!cboKeys msg = "Delete Object with Key: " & txtKey & " ..?" If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbCritical) = vbYes Then D.Remove (txtKey) 'Remove the Item matching the Key MsgBox "Item Deleted." Call initFields Me.strDesc.Enabled = True Me.strDesc.SetFocus 'make description field current Me.ItemCount = D.Count 'display items count Me.cmdAdd.Enabled = True Me.cmdEdit.Enabled = False Me.cmdDelete.Enabled = False End If End Sub
Deleting Dictionary Item
When the Delete Command Button is clicked, the current Item on the Form is deleted from the Dictionary, after the user reconfirms it.
The data entry fields are cleared, and the item count control is updated with the reduced number of items.
Private Sub cmdSave_Click()
Private Sub cmdSave_Click() Dim msg As String msg = "Form will be closed After Saving Data," msg = msg & vbCr & "Proceed...?" If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbInformation, "cmdSave_Click()") = vbNo Then Exit Sub Else Call Save2Table DoCmd.Close End If End Sub
Saving Data from the Dictionary Object.
When you have finished working with the Form and want to save the Dictionary Data Class’s property values from the Dictionary to the temporary Table (clsArea) and to close the Form, click on the 'Save to Table' Command Button.
Private Sub cmdExit_Click()
Private Sub cmdExit_Click()
Dim msg As String
If saveFlag Then
DoCmd.Close
Else
msg = "Dictionary Data Not saved in Table!"
msg = msg & vbCr & vbCr & "Click Cancel to Go back"
msg = msg & vbCr & vbCr & "Click OK to discard Data and close the Form!"
If MsgBox(msg, vbOKCancel + vbDefaultButton2 + vbQuestion, "cmdExit()") = vbOK Then
DoCmd.Close
Else
Call Save2Table
DoCmd.Close
End If
End If
End Sub
If you choose to click the Exit command button instead of the Save to Table button, you will be prompted to confirm whether you want to save the data. If you decide not to save, you can select the appropriate option to close the form without writing the data to the table.
There are also a few common subroutines that are called from multiple event procedures. Their code is included in the full listing provided below:
-
Private Sub initFields()
Clears all text boxes on the form when called from event procedures. -
Private Sub comboUpdate(ByVal stDesc As String)
Called from thecmdAdd_Click()andcmdEdit_Click()event procedures to update the Combo Box items. -
Private Sub Save2Table()
Called from thecmdSave_Click()andcmdExit_Click()event procedures to save the Dictionary Object data to the table.
The Form's Class Module Code.
Highlight, Copy, and Paste the Entire Code given below in the Form's Class Module of your Form. Save the Form with the name frmDictionary.
Option Compare Database
Option Explicit
Dim C As ClsArea, xC As ClsArea
Dim D As Object, Desc As String
Dim editFlag As Boolean, saveFlag As Boolean
Dim strV As String
Private Sub Form_Load()
Set D = CreateObject(“Scripting.Dictionary”)
Me.cmdEdit.Enabled = False
Me.cmdDelete.Enabled = False
saveFlag = False
End Sub
Private Sub Form_Current()
Dim o As String
o = cboKeys.RowSource
If Len(o) = 0 Then
Me.cboKeys.Enabled = False
Else
Me.cboKeys.Enabled = True
End If
End Sub
Private Sub cboKeys_AfterUpdate()
On Error Resume Next
strV = Me!cboKeys
Set xC = D(strV)
If Err > 0 Then
MsgBox "Item for Key: " & strV & " Not Found!"
Exit Sub
End If
Me!strDesc = xC.strDesc
Me!dblLength = xC.dblLength
Me!dblWidth = xC.dblWidth
Me!Area = xC.Area
Me.cmdAdd.Enabled = False
Me.cmdEdit.Enabled = True
Me.cmdDelete.Enabled = True
Me.strDesc.Enabled = False
On Error GoTo 0
End Sub
Private Sub cmdAdd_Click()
'--------------------------------------------------
'1. Add Class Object as Item to Dictionary Object
'2. Update Combobox RowSource Property
'--------------------------------------------------
Dim tmpstrC As String, tmpLength As Double, tmpWidth As Double
Dim flag As Integer, msg As String
Dim cboVal As String, cbo As ComboBox
editFlag = False
Set cbo = Me.cboKeys
tmpstrC = Nz(Me!strDesc, "")
tmpLength = Nz(Me!dblLength, 0)
tmpWidth = Nz(Me!dblWidth, 0)
flag = 0
If Len(tmpstrC) = 0 Then flag = flag + 1
If tmpLength = 0 Then flag = flag + 1
If tmpWidth = 0 Then flag = flag + 1
If flag > 0 Then
msg = "Invalid Data in one or more fields, correct them and retry."
MsgBox msg, , "cmdAdd()"
Exit Sub
End If
Desc = ""
Set C = New ClsArea 'create a new instance
'add Property Values
C.strDesc = tmpstrC
C.dblLength = tmpLength
C.dblWidth = tmpWidth
'add Class Object instance to Dictionary
D.Add tmpstrC, C 'Description is the Key
Call comboUpdate(tmpstrC) 'update description as combobox item
Me.ItemCount = D.Count 'display dictionary Items count
'Call initFields 'set all fields to blanks
Me.strDesc.SetFocus 'make description field current
'Clear Class Object
Set C = Nothing
End Sub
Private Sub cmdDelete_Click()
Dim txtKey As String, msg As String
txtKey = Me!cboKeys
msg = "Delete Object with Key: " & txtKey & " ..?"
If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbCritical) = vbYes Then
D.Remove (txtKey) 'Remove the Item matching the Key
MsgBox "Item Deleted."
Call initFields
Me.strDesc.Enabled = True
Me.strDesc.SetFocus 'select description field current
Me.ItemCount = D.Count 'display items count
Me.cmdAdd.Enabled = True
Me.cmdEdit.Enabled = False
Me.cmdDelete.Enabled = False
End If
End Sub
Private Sub cmdEdit_Click()
'Edit the displayed item properties
Dim cap As String
Dim mDesc As String
editFlag = True
strV = Me!cboKeys
cap = Me.cmdEdit.Caption
Select Case cap
Case "Edit"
Me.strDesc.Enabled = True
Me.cmdAdd.Enabled = False 'when editing Add button is disabled
Me.cmdEdit.Caption = "Update" 'Edit Button Caption is changed
Case "Update" 'Button clicked when Caption is Update
'directly replace the property value in the Item
xC.strDesc = Me!strDesc
xC.dblLength = Me!dblLength
xC.dblWidth = Me!dblWidth
mDesc = Me!strDesc 'changed Description is copied to mDesc
If mDesc <> strV Then 'checks with key in combobox value if not same then
D.Key(strV) = mDesc 'Change Dictionary Key of Item
'update new desc to Combobox
'old desc also remains in combobox
Call comboUpdate(mDesc)
End If
Call initFields
Me.strDesc.SetFocus
Me.cmdAdd.Enabled = True 'Enable Add button to add new item
Me.cmdEdit.Caption = "Edit" 'change caption from Update to Edit
Me.cmdEdit.Enabled = False 'disable Edit Button
Me.cmdDelete.Enabled = False 'disable Edit Button
End Select
End Sub
Private Sub cmdExit_Click()
Dim msg As String
If saveFlag Then
DoCmd.Close
Else
msg = "Dictionary Data Not saved in Table!"
msg = msg & vbCr & vbCr & "Click Cancel to Go back"
msg = msg & vbCr & vbCr & "Click OK to discard Data and close the Form!"
If MsgBox(msg, vbOKCancel + vbDefaultButton2 + vbQuestion, "cmdExit()") = vbOK Then
DoCmd.Close
Else
Call Save2Table
DoCmd.Close
End If
End If
End Sub
Private Sub cmdSave_Click()
Dim msg As String
msg = "Form will be closed After Saving Data,"
msg = msg & vbCr & "Proceed...?"
If MsgBox(msg, vbYesNo + vbDefaultButton2 + vbInformation, "cmdSave_Click()") = vbNo Then
Exit Sub
Else
Call Save2Table
DoCmd.Close
End If
End Sub
Private Sub Save2Table()
Dim db As Database, rst As Recordset
Dim recCount As Long, j As Long, item
On Error GoTo Save2Table_Error
recCount = D.Count
Set db = CurrentDb
Set rst = db.OpenRecordset("ClsArea", dbOpenTable)
For Each item In D.Items
With rst
.AddNew
!strDesc = item.strDesc
!dblLength = item.dblLength
!dblWidth = item.dblWidth
.Update
End With
Next
rst.Close
Set rst = Nothing
Set db = Nothing
saveFlag = True
MsgBox "Data Saved to Table: ClsArea"
Save2Table_Exit:
Exit Sub
Save2Table_Error:
MsgBox Err & ":" & Err.Description, , "Save2Table_Click()"
Resume Save2Table_Exit
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set D = Nothing
End Sub
Private Sub strDesc_GotFocus()
If editFlag Then
Me.cmdAdd.Enabled = False
Me.cmdEdit.Enabled = True
Me.cmdDelete.Enabled = True
Else
Call initFields
Me.cmdAdd.Enabled = True
Me.cmdEdit.Enabled = False
Me.cmdDelete.Enabled = False
editFlag = False
End If
End Sub
Private Sub dblWidth_LostFocus()
'Area is displayed for info purpose only
Me!Area = Nz(Me!dblLength, 0) * Nz(Me!dblWidth, 0)
End Sub
Private Sub initFields()
'Empty all fields
Me!strDesc = Null
Me!dblLength = Null
Me!dblWidth = Null
Me!Area = Null
Me.cmdAdd.Enabled = True
End Sub
Private Sub comboUpdate(ByVal stDesc As String)
Dim cbo As ComboBox, cboVal As String
Set cbo = Me.cboKeys
cboVal = cbo.RowSource
cboVal = cboVal & ";" & stDesc
cbo.RowSource = cboVal
cbo.Requery
If Len(cboVal) > 0 Then
Me.cboKeys.Enabled = True
End If
End Sub
Perform a Demo Run.
Open the frmDictionary form, and try adding a few entries to the Dictionary object.
Select an item from the Combo Box to view the property values of the corresponding class object.
Click the Edit command button and modify the Description, Length, and Width values as needed.
Click the Edit button again (now showing the caption Update) to save the changes back into the Dictionary object. If you open the Combo Box afterward, you will see both the updated item with the new description and the old item with its previous description.
Select the old description from the Combo Box. You will receive an error message indicating that the item no longer exists, as its Dictionary key has been updated with the new description.
To delete an entry, select an item from the Combo Box and click the Delete command button. The selected item will be removed from the Dictionary object.
The event procedure code has been kept simple, without validation checks, error-handling routines, or safeguards against unintended user actions on the form.
You may enhance the code with these features, if needed, and reuse it in your own projects.
Downloads
You may download this demo database from the link given below.
MS-ACCESS CLASS MODULE
- MS-Access Class Module and VBA
- MS-Access VBA Class Object Arrays
- MS-Access Base Class and Derived Objects
- VBA Base Class and Derived Objects-2
- Base Class and Derived Object Variants
- Ms-Access Recordset and Class Module
- Access Class Module and Wrapper Classes
COLLECTION OBJECT
- Ms-Access and Collection Object Basics
- Ms-Access Class Module and Collection Object
- Table Records in Collection Object and Form
DICTIONARY OBJECT
- Dictionary Object Basics
- Dictionary Object Basics-2
- Sorting Dictionary Object Keys and Items
- Display Records from Dictionary to Form
- Add Class Objects as Dictionary Items
- Update Class Object Dictionary Item on Form













"Select an item from the Combo Box and Click on the Delete Command Button to delete the item displayed on the Screen."
ReplyDeleteIt's Remove, not Delete