Databases - UIPickList

PickList aka ComboBox

Basically, a PickList is an Edit control with a down arrow. When the arrow is clicked a List of options is displayed.

MS Access | Delphi


MS Access 97

Normally, a Combo Box is used to enter data in a field. This page discusses placing one of these on a form.

When a table is defined, it is possible to associate a pick list or a lookup table with individual fields. Then, when one of those fields is placed on a form, a correctly configured Combo Box is automatically configured.

Some Combo Boxes are used for other purposes (and, therefore, not associated with fields). For instance, it is possible to Use a ComboBox to Pick A Record.


Adding a Combo Box via the Wizard

You can use the wizard to add combo boxes. (I suggest doing this the first few times.) At this point the control is not associated with a field. Be sure to set Control Source to the field.

TabProperty Value
DataControl source blank - the field is "unbound"
DataRow Source Type Table/Query
DataRow Source SELECT DISTINCTROW [TableName].[id], [TableName].[Country] FROM [TableName];
DataBound Column 1
FormatColumn Count 2
FormatColumn Widths 0";1"


General Notes

When a combo box contains more than one column, the following will populate 2 fields when the user selects one record.

It is possible to change a Combo Box to a List box, and vice versa. (Either right click the control and select Change To or select Format / Change To from the main menu.) Each control provides several ways to read the currect selection.
Combo Box
Note that Text and Value do not always have the same value.
  xx = xyz_UIComboBox.Value       'Returns the data in the bound column

  i = xyz_UIComboBox.ListIndex
  xx = xyz_UIComboBox.ItemData(i) 'Returns the data in the bound column

  xyz_UIComboBox.SetFocus         ' SetFocus is required if this code is in a button
  xx = xyz_UIComboBox.Text        ' and you want to read the Text property
                                  ' Returns the data displayed on the form


   ' When using the Column property
   '   The Columns are numbered from zero
   '      Be careful, the BoundColumn property numbers the columns from one
   '   The index is the SECOND parameter, 
   '      When typing in the development environment, 
   '        the popup help has the parameters in the wrong order
   '      The help file has them in the correct order
  xx = xyz_UIComboBox.Column(column)
  xx = xyz_UIComboBox.Column(column, index) ' This works
  xx = xyz_UIComboBox.Column(index, column) ' This FAILS - order in the popup help
  
List Box
  xx = xyz_UIListBox.Value       'Returns the data in the bound column

  i = xyz_UIListBox.ListIndex
  xx = xyz_UIListBox.ItemData(i) 'Returns the data in the bound column
ListIndex, Value, Text and are in the help (just search for them), but they are not listed as properties under either "Combo Box Control Properties" or "List Box Control Properties". Value is mentioned in the write up for Text. I have no idea how I found ListIndex. (Actually, there are lots of unlisted properties. I wonder how MS expects people to learn how to use this product.)

You can use the Column property to return data from a specified row and column.


Problems Accessing List Elements

Supposedly, in VisualBasic and VBA, the list(index) syntax can be used to both read and write list elements. In fact, the MS Access help explicitly states that the list elements can be read via However, when I try to run the code with MS Access 97 SR2, I get I get the same error with However, this works Another way to accomplish this is to set the ComboBox's Default property to (The initial equals sign - = - is optional.)

As far as writing values to a list, I get the values from a lookup table (named with an _LU). Tips for Access Database Users by Allen Browne shows how to Fill a ListBox or Combo using code. Wow, what a mess. For more details, in the MS Access help, find combo boxes, setting values / Create a ListBox ... that gets it values from a function, then click the button in step 1.

Now you see why I use lookup tables.


Filters

When defining filters, you can use either the value stored in the field or the value displayed. This example uses the value displayed. (In the picklist, the Row Source points to a table and FieldName is one of the fields returned. The form object is named ProductID_UIPickList, with only one underscore.)
  ((Lookup_ProductID__UIPickList.[FieldName]="String actually displayed"))


Content Problem

I frequently use lists that are populated via a query which gets criteria from fields on the form. What I want is to requery the list each time it is opened (such as when the down arrow is pressed). Unfortunately, I have not found a reliable way to do this.

Scenario


Sorting by the Contents of a Field

I have a form with a field/comboBox named LocationTypeID.

In order to sort the data based on the contents of that field, you have to set

I discovered this by using the Order buttons on the tool bar. There is no help at all on where Lookup_LocationTypeID.Type came from. I had assumed that LocationTypeID should have worked - wrong again.

On the same form, I have a pick list (comboBox) which is used to limit the displayed records. However, the following code

produced
Run-time error '3079'.

The specified field 'LocationTypeID' could refer to more than one table listed in the FROM clause of your SQL statement.

I can't figure out why.

When I deleted the OrderBy property, the code worked perfectly. Perhaps you can't OrderBy and Filter on the same field.

However, the following works

Go figure :)

In the final code, this seems to work

Apparently, MS Access can not tell which query I am referring to.


Delphi 5.0

The items in a PickList (TComboBox) are stored in a string list (TStrings - an array of strings) which supports Reading, Writing, Adding, Removing and more.

Based on the Delphi 5 help, the following are equivalent

For database access use

Multiple fields are tricky - there is only one DropDownWidth parameter (it's in pixels and defines to total list width) - there is no way to set the widths of the individual fields (which appear to be about 140 pixels each). The Delphi 5 help does not contain any examples.

This example generates a "view" (based on MS Access and KADAO tables)

The "view" allows me to concatenate several fields, with puctuation, and preferred sorting, for use in DBLookupComboBox1 without the problems of wierd column widths and only one field being shown in the edit window. (True Views are created in the database definitions ... however, MS Access does not support these. You can use a MS Access Query as a read only view.)

DBLookupComboBox does not have an event that detects when the KeyValue is changed. Therefore, I use both


DBLookupListBox

Almost everything that applies to a DBLookupComboBox also applies to a DBLookupListBox.

There is a problem when a DBLookupListBox is used to select a record - when the program begins, none of the list items is highlighted. The following code sets the highlight to the first item in the list.

Notice that the OnClick event is called when


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Databases / UIPickList.html