Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Saturday, April 18, 2009

Filter by Character and Sort

Introduction

Search, find, filter, and sort operations are essential for organizing data into a manageable form, making it easier to locate specific information. We have already explored some of these operations in the following earlier posts titled:

Now, let’s look at a simpler and more user-friendly method for filtering data, by typing one or more characters directly into a text box and seeing instant results, rather than entering search text in various controls and clicking multiple buttons or toolbar options.

When the first character is entered into the text box (for example, the letter F), all records with names starting with that letter are instantly displayed. If the filtered list is still large or includes unwanted items, entering additional characters narrows the list. This process can be repeated as needed.

If the Backspace key is used to delete one or more characters, the filtered list will expand accordingly, gradually reversing the process. Since the filtering occurs instantly, the user can see results as soon as a key is pressed.

If you need to transfer values from one of these filtered records to another open form, you can do so by writing a routine for the Double-Click event at the form level. Double-clicking the record selector (the left border of a record) can trigger this action and transfer the required values to another open form. We’ll look at the sample code for this action at the end of this article.

Sample Image of Form

The limitation of this method is that it is designed for use with tabular-type forms, where multiple records can be viewed simultaneously. The earlier methods (referenced in the previous articles) were intended for single-record forms.

Typically, a search or filter operation of this kind is implemented for a single field, such as Employee Code, Company Code, or Company Name—fields that are most relevant when searching for information.

However, in this example, we’ll take it a step further by offering greater flexibility. We’ll provide a combo box listing all the field names from the form’s source object (table or query). This allows the user to select which field to filter the data on, making the search feature far more versatile.

To follow along with this example, you’ll need the Customers table from the Northwind.mdb sample database. If you’re unsure where to find this file, refer to last week’s post—specifically, the third item in the list of three links provided there.

Sample Data Table, Query & Form.

  1. Import the Customers Table from the Northwind database.

  2. Create a SELECT Query with the following SQL String and save the Query with the name CustomersQ.

    SELECT Customers.[First Name], Customers.[Last Name], Customers.[Job Title]
    FROM Customers;
    
  3. Design a Tabular Form as shown in the Image given above. I have selected only three fields from the Table in this example. If you like to use some other Fields in the Query, you may do so.

  4. Expand the Form Footer Section, if it is not visible (View ->Form Header/Footer).

  5. If the Toolbox is not visible, display it by selecting Toolbox from the View Menu.

  6. De-select the Control Wizards Button (the top right one); if it is already in the selected state on the ToolBox, so that the Wizard will not start when the Combo Box Tool is selected.

  7. Select the Combo Box Tool from the Toolbox and draw a Combo Box on the Footer Section of the Form, as shown in the design above.

  8. Change the Caption value of the Child Label on the Combo Box to Filter/Sort Field:.

  9. Click on the Combo Box to select it and display its Property Sheet (View -> Properties).

  10. Change the following Property Values as given below:

    • Name = cboFields
    • Row Source Type = Field List.
    • Row Source = CustomersQ.
    • Column Width = 1.5"
  11. Create a Text Box below the Combo Box.

  12. Change the Caption Value of the Child Label to FilterText:.

  13. Change the Name Property Value of the Text Box to FilterText.

  14. Create an Option Group Control, with two buttons with Label Captions ASC and DESC for the Sorting option, Ascending or Descending order.

  15. Create a Command Button to the right of the Options Group control and change the following Property values:

    • Name = cmdClose
    • Caption = Close

    The VBA Code

  16. Display the VBA Code Module of the Form (View -> Code or Alt+F11).

  17. Copy and paste the following Code into the Module and save the Form with the name Customers or any other name you prefer.

    'Global declaration
    Dim x, rst As Recordset
    
    Private Sub cmdClose_Click()
        DoCmd.Close
    End Sub
    
    Private Sub FilterText_KeyUp(KeyCode As Integer, Shift As Integer)
    Dim i As Integer, tmp, j As Integer, srt As String
    
    On Error GoTo FilterText_KeyUp_Err
    i = KeyCode
    
    Select Case i
        Case 8 'backspace key
            Me.Refresh
            If Len(x) = 1 Or Len(x) = 0 Then
                x = ""
            Else
                x = Left(x, Len(x) - 1) 'delete the last character
            End If
            GoSub setfilter
        Case 37, 39 'left and right arrow keys
            SendKeys "{END}" 'ignore action
        Case 32, 48 To 57, 65 To 90, 97 To 122 'space, 0 to 9, A to Z, a to z keys
            x = x & Chr$(i)
            Me![FilterText] = x
            GoSub setfilter
    End Select
    
    FilterText_KeyUp_Exit:
    Exit Sub
    
    setfilter:
      Me.Refresh
      tmp = Nz(Me!cboFields, "") 'save the value in Combo Box
      If Len(Nz(x, "")) = 0 Then
            Me.FilterOn = False ' remove filter
      Else 'set filter and enable
            Me.Filter = "[" & Me![cboFields] & "]" & " like '" & x & "*'"
            Me.FilterOn = True
      End If
      ' Set sort order
      j = Me!Frame10
      srt = IIf(j = 1, "ASC", "DESC")
      Me.OrderBy = "[" & Me!cboFields & "] " & srt
      Me.OrderByOn = True
      Me![cboFields] = tmp
      Me.FilterText.SetFocus
      SendKeys "{END}"
    Return
    
    FilterText_KeyUp_Err:
    MsgBox Err.Description, , "FilterText_KeyUp()"
    Resume FilterText_KeyUp_Exit
    End Sub
    
    Private Sub Form_Close()
    Application.SetOption "Behavior Entering Field", 0
    Me.FilterOn = False
    Me.OrderByOn = False
    End Sub
    
    Private Sub Form_Load()
        Application.SetOption "Behavior Entering Field", 2
        Set rst = Me.RecordsetClone
        Me!cboFields = rst.Fields(0).Name
        Me.Refresh
        rst.Close
    End Sub
    

    Test Run the Demo Form

  18. Open the Form in Normal View.

  19. The First Name field will appear as the default value in the Combo Box control.

  20. Click on the Text Box below the Combo Box to set the focus on it.

  21. Type the Character F and you will see that all records with CustomerID values starting with the letter F are filtered.

    If you look at the filtered Field values of records, you may find that the second character of the filter field values is different, and three items have the same letter in the second character position. Besides, the field values are correctly sorted in selected (Ascending/Descending) Alphabetical Order.

  22. Type the second common character next to the earlier character in the FilterText control, and the list of items narrows down. You can further filter and narrow down the list progressively.

  23. Press the Backspace Key to delete the last character typed and to leave the rest of the characters in the Text Box. The list will expand, and all items starting with the letters in the control are back on the List.

  24. Press the Backspace Key again to delete other characters one by one from the TextBox. This time, the Filter action is removed, and all the records are back in the Form.

NB: The Filter Criteria Text Values are limited to the Characters 0 to 9, A to Z, and a to z only.

If you want to try the Filter action on one of the other two fields, select that Field's name from the Combo Box above before trying the filter action explained from Step 19 onwards.

Try it on the third Field Job Title for different results.

Download Demo Database



Saturday, April 11, 2009

Animating Label on Search Success

Introduction

We have seen how to find or filter records using values entered into a text box. We have used three different methods to find or filter data after entering text or numeric search values into a text box. But we have not used any visual indicator to announce whether the search operation was successful or not. If the search operation was successful, then the record that matches the criteria will become current or filtered; that was the only indication that the search was successful.

Visual Indicator Design Task

Here, we will see how to animate a Label a few times with an indicative message, announcing whether the search operation was successful or not.

  1. To try an example with the sample VBA Code given below, import the Customers Table and Customers Form from the Northwind.mdb sample database. If you don't know where to look for this database, check the location C:\Program Files\Microsoft Office\Office11\Samples Folder (in Office 2003).

  2. Open the Customers form in the design view.

  3. Expand the Form Footer Section to create a few controls for the Quick Search operation and for our magic label animation. Check the sample image of the Form given below with controls added at the Footer of the Form:

  4. Draw a Label on the Form Footer Section and change its Caption to Customer ID to Find:.

  5. Draw a Text Box to the right of the Label and change its Name Property (View -> Properties or Alt+Enter) Value to xFind.

  6. Create a Command Button to the right of the Text Box and change its Name Property Value to cmdFind. Change the Caption of the Command Button to << Find.

  7. Create a Label below the Text Box and change the following Property Values shown against each Property:

    • Name = lblMsg
    • Caption = x
    • Visible = False
  8. Display the Code Module of the Form (View -> Code or Alt+F11)

    Animation Running VBA Code

  9. Copy and Paste the following Code into the Form Module and save the Form:

    'Global Declarations
    Dim backcolor As Long, forecolor As Long
    Dim L As Integer
    
    Private Sub cmdFind_Click()
    '---------------------------------------------------------------
    'Author : a.p.r. pillai
    'Date    : April-2009
    'URL     : www.msaccesstips.com
    'All Rights Reserved by www.msaccesstips.com
    '---------------------------------------------------------------
    Dim m_Find, rst As Recordset
    
    On Error GoTo cmdFind_Click_Err
    
    backcolor = -2147483633
    
    m_Find = Me![xFind]
    If IsNull(m_Find) Then
        Exit Sub
    End If
    Set rst = Me.RecordsetClone
    rst.FindFirst "CustomerID = '" & [m_Find] & "'"
    If Not rst.NoMatch Then
        Me.Bookmark = rst.Bookmark
        Me.lblMsg.Caption = "** Successful ***"
        forecolor = 16711680
        Me.lblMsg.forecolor = forecolor
    Else
        Me.lblMsg.Caption = "Sorry, Not found...!"
        forecolor = 255
        Me.lblMsg.forecolor = forecolor
    End If
    L = 0
    Me.lblMsg.Visible = True
    Me.TimerInterval = 250
    
    cmdFind_Click_Exit:
    Exit Sub
    
    cmdFind_Click_Err:
    MsgBox Err.Description, , "cmdFind_Click()"
    Resume cmdFind_Click_Exit
    End Sub
    
    Private Sub Form_Timer()
    L = L + 1
    Select Case L
        Case 1, 3, 5, 7, 9, 11, 13, 15, 17
            Me.lblMsg.Visible = True
        Case 2, 4, 6, 8, 10, 12, 14, 16, 18
            Me.lblMsg.Visible = False
        Case 19
           Me.lblMsg.forecolor = forecolor
           Me.lblMsg.Visible = True
           Me.TimerInterval = 0
    End Select
    End Sub
    
    Private Sub xFind_GotFocus()
         Me.lblMsg.Visible = False
    End Sub

    The first two lines of code should go at the Global level of the Form Module.

  10. Open the Customers form in Normal View to try out our creation. When you open the form, the Label that we have created below the Text Box will not be visible.

  11. Type record number 55 in the Record Navigation control below.

  12. Highlight the CustomerID code and press Ctrl+C to copy the Customer Code into the Clipboard.

  13. Type 1 in the record navigation control to make the first record current.

  14. Click on the Text Search Control on the Form Footer to select it and press Ctrl+V to paste the Customer Code from the Clipboard.

  15. Click on the Command Button to find the first record that matches the Customer Code.

    If the search operation is successful, the first record that matches the CustomerID will become the current record. A Label positioned below the TextBox will then become visible, flashing the message “Successful” nine times before remaining visible on the screen.

  16. Make the first record current again, and replace a non-existent CustomerID in the search Text Box so that the search operation fails with the modified Value.

  17. Click the Command Button to search for the CustomerID.

This time, we will get the "Sorry, Not Found...!" message. The message flashes nine times and stays on the screen.

How does it work?

In this example, we have made the label visible and hidden intermittently within an interval time of 250 Milliseconds. This method is ideal for all types of Forms with different backgrounds, like the one we used with a Background picture.

A Better Approach.

We can make the Label flash by changing the text Color (rather than hiding and displaying the label as we did in the above example) with the same timing mechanism if the Form background has a particular Color.

  1. Create a copy of the Customers Form and rename it to Customers2.

  2. Open the Form in Design View and display the Form's Property Sheet.

  3. Find the Picture Property and delete the WMF image file pathname. This action will display a message asking to reconfirm the delete action and respond to remove the entry.

  4. Remove the After Update property value. A Macro is attached here to run in the after-update event of the form.

  5. Without closing the Property Sheet, click on the Footer of the Form and change the Back Color Property value to -2147483633. This is the normal Form background color when you open a new form in Design View.

  6. Click on the label below the Text Box and change the following Property Values:

    • Back Style = Transparent
    • Special Effect = Flat
    • Border Style = Transparent
  7. Replace the following Select Case ... End Select code segment with the Code given below, in the Sub Form_Timer() Event Procedure:

    Select Case L
        Case 1, 3, 5, 7, 9, 11, 13, 15, 17
            Me.lblMsg.forecolor = forecolor
        Case 2, 4, 6, 8, 10, 12, 14, 16, 18
            Me.lblMsg.forecolor = backcolor
        Case 19
           Me.lblMsg.forecolor = forecolor
           Me.lblMsg.Visible = True
           Me.TimerInterval = 0
    End Select
    

    We have changed the lines under the first two Case... Statements in the above code segment to change the Color of the Font.

    The first statement changes the Font color to Blue if the search operation was successful, otherwise red.

    The line under the second Case... Statement replaces the Font Color with the Form's Background, making the text in the Label invisible.

    When the value in the control variable L is an Odd Number, the line under the first Case statement executes; when it is an Even Number, the line under the second Case statement executes. This happens alternatively every 250 milliseconds, and the label animates nine times. When the value in the Control Variable L = 19, the Interval Timer is turned off and the Label's Font Color is changed according to the search result (Blue or Red), and keeps the Label visible on the Form till the User clicks on the Text Box again to enter a new search criterion.

  8. Save the Form and open it in a normal view.

  9. Repeat the procedure explained under Steps 10 to 17 above.

This time, the Label will flash blue when the search result is successful and red when the search fails. In both situations, the colors are exchanged with the background color intermittently with the Form Background Color Value -2147483633.

If you want to slow down the action, then increase the interval time value from 250 Milliseconds to a higher value or reduce it to flash the Label faster.

Download Demo Database.

  1. Textbox and Label Inner Margins
  2. Animating Label on Search Success
  3. Label Animation Style-1
  4. Label Animation Style-2
  5. Label Animation Variant
  6. Label Animation Zoom-in Style
  7. Label Animation in Colors
  8. Label Animation Zoom-out Fade

Saturday, April 4, 2009

Form Background with Gradient Color

Introduction

The Form background pictures are not only used for giving the Form a different look, but also for other useful purposes.

Assume that the user is entering data from a pre-printed document, such as a telephone bill or an electricity bill.  In such situations, it can be very effective to scan an image of the source document and use it as the background picture of the data entry form. The Data Fields can be positioned in appropriate locations on the image, matching the physical Document so that it will be easier for the user to find information on the Document and key in exactly the same locations on the Form.

Microsoft Access Form Wizard offers several images that can be used as background pictures, but I couldn’t find the one I wanted — a simple gradient background. So, I decided to create one myself and use it instead.


Creating a Sample Image

The steps are given below to create the image for the Form Background picture.

  1. Opened a new Microsoft Word Document and went through the following steps to create a Gradient bitmap image:

  2. Selected Format - - >Background - - > Fill Effects.

  3. Under Colors, options selected One Color.

  4. Clicked on the Color 1 drop-down control and selected a light color.

  5. Used the Darker/Lighter slider control to adjust the color tone.

  6. Selected the Horizontal Radio Button under Shading Styles.

  7. Clicked on one of the Style Variants.

  8. Clicked OK to apply the selected shade as the Background of the Word Document.

  9. Maximized the Word Document Window.

  10. Select the Prt Scrn key (at the top row, right side). The full-screen image is now captured and copied to the Clipboard.

  11. Opened the MS Paint Program. You can find this in Start -> Programs -> Accessories.

  12. Displayed the Toolbox (View -> Toolbox or press Ctrl+T).

  13. Selected the Select Tool (the one at the top right with a rectangle picture).

  14. Drawn a rectangle from the left top corner of the gradient image area to the right bottom corner to select the image large enough for my Form's width and height. If you find the width is not enough to cover your form, then change the Page Orientation of the Word Document into Landscape mode before capturing it in MS Paint.

  15. Use Ctrl+C to copy the selected area into the Clipboard.

  16. Clicked outside the selected area to deselect the earlier selection.

  17. Select Clear Image from the Image Menu (Ctrl+Shift+N) to clear the Canvas. Inspected the right Scroll Bar to check whether it is positioned at the top or not. It was positioned slightly down, so I dragged it up to the top. Similarly, adjusted the Scroll bar at the bottom to the position at the left end.

  18. Pressed Ctrl+V to paste the copied image from the Clipboard.

  19. Clicked outside the pasted image to deselect it.

  20. Dragged the Sizing control at the bottom of the Canvas up and stopped at the edge of the pasted image to eliminate the white area of the canvas.

  21. Similarly, adjust the right side of the image.

  22. Select Save from the File Menu to save the image with a name in a convenient location.

If you’ve been following along so far, we’re now ready to move on to the next stage — implementing the gradient image as a background picture. However, there are a few limitations when using images like this as a form background, but with a little trick, we can easily overcome them.

If you’re thinking about the increase in database size, you’re absolutely right to consider it. And if you’re already thinking about saving the image in JPEG or GIF format, then you’re one step ahead of me! Saving the image type as GIF in MS Paint won’t produce good-quality results. If you have access to software like Adobe Photoshop, you can create high-quality GIF images with much better control.

We’ll use the BMP image format with a few smart modifications to preserve excellent image quality without increasing the database size.

But first, let’s see how to apply the gradient image as the form’s background picture.

Inserting the Image on the Form Background

Before opening your database, you can check the current file size in Windows Explorer. It’s a good idea to compact the database first to get an accurate baseline size. After adding the background picture to a Form, inspect the database size again to see how much it has changed.

  1. Open your Database and open a Form in Design View or create a new one.

  2. Display the Property Sheet of the Form (View -> Properties).

  3. Find the Picture Property and click on it.

  4. Click on the build button (...) at the right side of the Property Sheet and click on it to browse to the location of the image you have saved and select the image.

  5. The next four Properties are used for formatting and displaying the Background Picture.

  • Picture Type
  • Picture Size Mode
  • Picture Alignment
  • Picture Tiling

Linked or Embedded Image Methods

The Picture Type property has two options, Embedded and Linkedwith Embedded as the default. The Embedded option allows opening the default image editor directly from within MS Access by double-clicking the image and editing the picture if needed. However, to support this functionality, Access stores not only the image but also additional information required to invoke the image editor. As a result, each embedded image can significantly increase the size of your database. Note that background images added this way cannot be edited by double-clicking them, unlike OLE object images inserted on a Form.

A better option is the Linked setting, which keeps the image stored externally, leaving your database size unaffected. However, in either case, the image file must remain available in the same location relative to your database if it is moved or shared.

The Picture Size Mode property provides three options. The default option, Clip, displays the picture at its actual size, positioned according to the Picture Alignment setting—Top Left, Top Right, Bottom Right, Bottom Left, Center, or Form Center. The Center option places the image both vertically and horizontally centered on the Form, while Form Center aligns it vertically centered along the left edge.

The Stretch/Zoom/Tile Picture Methods

The Stretch Picture Size Mode option will stretch the image to fit the dimensions of the Form, resulting in distortion of the image if it is a picture of something.

The Zoom Picture Size Mode option will attempt to maintain the right proportions of the image when stretched to match the dimensions of the Form. But both the Stretch and Zoom options will show stretch marks when the Form is restored to its original size. This is much evident when a .jpeg or GIF image is used.

The One Pixel Width Image

We can modify our earlier .bmp file to a one-pixel-width image and Tile it across the Form, which will give a good quality gradient picture effect, and the image size will also be small.

  1. Open the earlier saved .bmp image in the MS Paint Program.

  2. Select Attributes... from Image Menu.

  3. Change the Width value to 1, and no change in the Height value.

  4. Check Units selected are Pixels.

  5. Save the image with a different name.

  6. Change the name of the background image to the new image in the Picture property of the Form.

    Caution: Do not attempt to use the Picture Size Mode property options Stretch or Zoom; MS-Access may hang up.

  7. Set the Picture Tiling Property Value to Yes and save the Form.

  8. Open the Form in Normal View and enjoy your creation.

Powered by Blogger.