Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Filter Function Output In Listbox-2

Introduction

Last week we saw the usage of the Filter() Function with a simple example and I hope you understood how it works. We have assigned constant values of the Source Array elements directly, to keep the VBA Code as simple as possible.

We can filter data on Forms by setting Criteria on the Filter Property of Forms. Similarly, we can use conditions in Queries to filter information from Tables as well.

But, the Filter() Function gives a unique way of filtering data from an Array of information loaded from Tables or Queries and creates output quickly based on matching or non-matching options.

Let us try out the Filter() Function in an Address Book Application to quickly find persons or places that match the specified search text and display them in a List Box. We will use Names and Addresses from the Employees Table of Northwind.mdb sample database for our experiment.

Following is the User Interface design that we planned to create and explains how the user will interact with it to display information quickly on the Form.

We will design a Form with a List Box, a Text Box Control, a Check-Box Control, and a Command Button for our experiment. An image of such a Form in Design View is given below:

When the Form is open in normal view the List Box and Text Box Controls will be empty. The User can enter the word ALL in the Text Box Control and click the Command Button to display the Name and Addresses of all Employees in the List Box.

Or

The User can enter a word or phrase, like part of a Name or Address, that can match anywhere within the Name and Address text, and click on the Command Button to filter out the matching items and to display them in the List Box.

If the Matching Cases Check-Box is in the selected state, then the Filter action will select records that match with the search text given in the Text Box Control otherwise it will select all records that do not match with the search text.

To provide the User with the above facility, we need two Subroutines on the Form's Code Module and a User Defined Function in the Standard Module of the Database to use the Filter() Function.

When the User opens the above Form the first Sub-Routine is run from the Form_Load() Event Procedure to read the data (First Name, Last Name & Address) from the Employees Table, join all the three field values in a single row of text, and load them into a Singly Dimensioned Array Variable in Memory. This data will remain in memory till the User closes the Form.

The second Sub-Routine is run when the user clicks on the Command Button to extract information from the Source Array with the help of the Filter() function, based on the search text entered into the Text Box Control.

The Filter() Function will extract the entries that match with the search text in the Text Box Control, from the Source Array Variable and save the output into the target variable xTarget. All we have to do is to take these values, format them, and insert them as Row Source Property Value to display them in the List Box.


The Address Book Project.

Let us prepare for the Address Book's Quick Find Project.

The Design Task

  1. Import Employees Table from C:\Program Files\Microsoft Office\Office11\Samples\Northwind.mdb sample database.
  2. Open a new Form in Design View.
  3. Select the List Box Control from the ToolBox and draw a List Box as shown on the design above.
  4. While the List Box is in the selected state display the Property Sheet (View - - > Properties) and changes the following Property Values as given below:
    • Name = AddBook
    • Row Source Type = Value List
    • Width = 4.5"
    • Height = 1.75"
    • Font Name = Courier New
    • Font Size = 10
  5. Position the Child Label attached to the List Box above and change the Caption value to Address Book.
  6. Draw a Text Box below the List Box. Change the Name Property value of the TextBox to xFind. Position the Child Label above the Text Box and change the Caption value to Search Text/ALL.
  7. Create a Check-Box Control to the right of the Text Box. Change the Name Property of the Check-Box to MatchFlag. Change the Default Value Property to True. Change the Caption value of the child label of Matching Cases.
  8. Create a Command Button to the right of the Check-Box control. Change the Name Property Value of the Command Button to cmdFilter and the Caption Property Value to Filter.

    NB: Ensure that the Name Property Values of the above controls are given exactly as I have mentioned above. This is important because we are referencing these names in Programs.

  9. Display the Code Module of the Form (View - - >Code).
  10. Copy and paste the following Code into the Form Module:

    The VBA Code

    Option Compare Database
    Option Explicit
    Dim xSource() As Variant
    
    Private Sub Form_Load()
    Dim db As Database, rst As Recordset, J As Integer
    Dim FName As String * 12, LName As String * 12, Add As String * 20
    
    'Take the count of records
    J = DCount("*", "Employees")
    
    'redimension the array for number of records
    ReDim xSource(J) As Variant
    
    Set db = CurrentDb
    Set rst = db.OpenRecordset("Employees", dbOpenDynaset)
    'load the name and addresses into the array
    J = 0
    Do Until rst.EOF
       FName = rst![FirstName]
       LName = rst![LastName]
       Add = rst![Address]
      xSource(J) = FName & LName & Add
    rst.MoveNext
    J = J + 1
    Loop
    rst.Close
    Set rst = Nothing
    Set db = Nothing
    End Sub
    
    Private Sub cmdFilter_Click()
    Dim x_Find As String, xlist As String, xTarget As Variant
    Dim x_MatchFlag As Boolean, J As Integer
    
    Me.Refresh
    x_Find = Nz(Me![xFind], "")
    x_MatchFlag = Nz(Me![MatchFlag], 0)
    
    'if no search criteria then exit
    If Len(x_Find) = 0 Then
      Exit Sub
    End If
        'initialize list box
        xlist = ""
        Me.AddBook.RowSource = xlist
        Me.AddBook.Requery
    
    If UCase(x_Find) = "ALL" Then
        'Take all values from the Source Array
        'Format it as listbox items
        For J = 0 To UBound(xSource())
          xlist = xlist & xSource(J) & ";"
        Next
    Else    'Call the Filter Function
        xTarget = GetFiltered(xSource(), x_Find, x_MatchFlag)
        'format the returned values as list box items
        If Len(xTarget(0)) > 0 Then
            For J = 0 To UBound(xTarget)
                xlist = xlist & xTarget(J) & ";"
            Next
        End If
    End If
        'remove the semicolon from
        'the end of the list box Value List
        If Len(xlist) > 0 Then
            xlist = Left(xlist, Len(xlist) - 1)
        End If
        'insert the list item string
        'and refresh the list box
        Me.AddBook.RowSource = xlist
        Me.AddBook.Requery
    
    End Sub
  11. Save the Form with the name Filter Form.
  12. Copy and paste the following Function into a Standard Module and save the Module:
    Public Function GetFiltered(ByRef SourceArray() As Variant, ByVal xFilterText As Variant, ByVal FilterType As Boolean) As Variant
        GetFiltered = Filter(SourceArray, xFilterText, FilterType)
    End Function
    

    Filter() Function and Filter Property of the Form.

    We cannot use the Filter() Function in the Form Module because the function name clashes with the Form Property Filter.

    We have inserted the Filter() Function in the Standard Module enveloped in User Defined Function GetFiltered() with the necessary Parameters so that we can call it from the Form Module. The first parameter to the Function is passed By Reference so that it can use the Source Array values directly.

    The Demo Runs

  13. Open the Filter Form in normal View.
  14. Enter the word ALL (in this case the Matching Cases flag has no effect) in the Text Box control and Click on the Filter Command Button.

    This action will display the Name and Addresses of all Employees from the xSource() Array loaded from the Employees Table.

  15. Enter the text Ave in the Text Box and see that the Matching Cases check box is in the selected state.
  16. Click on the Command Button.

    This time you will find that only two Employee (Nancy & Laura) names and addresses are filtered and the word Ave is appearing in their Address Lines.

  17. Remove the check-mark from the Matching Cases check box and click on the Filter Command Button again.

Now, all items except the lines with the word Ave are listed in the List Box.

If you go through the Programs that we have copied into the Form Module you can see that we have declared the xSource() Array Variable in the Global area of the Module so that we can use the data in both Sub-Routines in the Form Module.

In the Form_Load() Event Procedure, we have declared three Variables as fixed-length String Type (see the declaration line given below).

Dim FName As String * 12, LName As String * 12, Add As String * 20

When we read employee Name and Addresses into these Variables the values will be left-justified inside the Variable and the balance area of the declared size will be space filled to the right. This method will space out items at a fixed distance from each other and properly align them when displayed.

It is important that we use a Fixed Width Font, like Courier New, for the List Box display and we set this in Step-4 above.

If you click the Filter Command Button when the TextBox is empty, then the program terminates, otherwise, it calls the GetFiltered() Function and passes the parameter values.

The output Values are returned in the xTarget Array and the next steps format the Value List and display them in the List Box.

Share:

2 comments:

  1. Unfortunately it did not work for me. There was something wrong with the xTarget events on click. I tried fixing it but it did not work. Also, some of the code, I had to edit to get working. For example, the OnLoad() event. Nothing showed up because there was no command that told the listbox to add an item. (Listbox1.AddItem strName)

    ReplyDelete
  2. If you can copy some sample data and the Form with the modified code into a new database and forward it to me (in .zip format) to my email address aprpillai@gmail.com, I can take a look at it. I shall correct the code and sent it back to you.

    Regards,
    a.p.r. pillai

    ReplyDelete

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