0% found this document useful (0 votes)
51 views

Access 2017 - Manejo de Columnas

This document describes a method for selecting countries in an Access database form that provides an easy yet accurate country selection. It involves creating a query that filters the list of all countries to only include those with a sort order value, ordered by the sort order. A separate form allows the user to assign sort orders to countries, effectively customizing the list of selectable countries. When a country is selected, phone numbers entered on the form are formatted according to conventions for that country using custom formatting functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views

Access 2017 - Manejo de Columnas

This document describes a method for selecting countries in an Access database form that provides an easy yet accurate country selection. It involves creating a query that filters the list of all countries to only include those with a sort order value, ordered by the sort order. A separate form allows the user to assign sort orders to countries, effectively customizing the list of selectable countries. When a country is selected, phone numbers entered on the form are formatted according to conventions for that country using custom formatting functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 21

Access Archon Column #218 – Selecting Countries

By Helen Feddema
Access versions: 2002-2010
Level: Intermediate

Introduction
If you let users enter country names into a field on a form, you may end up with several
variations on a single country name, such as UK, United Kingdom, England, Britain.
This leads to problems when getting totals or filtering by country. To avoid this, you can
prepare a lookup table of country names. That works fine for a limited selection (say,
just NAFTA countries or EuroZone countries). But what if a customer could be in any
country in the world? Users will balk at making a selection from a list of 100 or so
countries. This article describes a way of making country selection both easy and
accurate.

The Sample Database


The sample database for this article, Selecting Countries (AA 218).mdb, has a standard
Contacts form plus two other forms, one for selecting countries and one for selecting
time zones. On frmContacts, shown in Figure A, there is a combo box for selecting a
country and another for selecting a time zone. (The same techniques are used for
countries and time zones, so I will only discuss the techniques for selecting countries in
this article.)

Access Archon Column 218 Page 1


Figure A. The Contacts form, with Country and Time Zone selector combo
boxes
The cboCountry combo box's row source is qrySelectedCountries, shown in Design and
Datasheet view in Figure B.

Access Archon Column 218 Page 2


Figure B. A query used as the row source of the cboCountry combo box
This query only shows countries with a value in the SortOrder field, ordered by
SortOrder. Country sort orders are set in frmCountries, shown in Figure C.

Access Archon Column 218 Page 3


Figure C. A form for setting country sort orders
This form has two listboxes, one for available countries (the list of countries and Internet
codes was obtained from the Web), and one for selected countries (these are the ones
that will appear in cboCountry's drop-down list). This method lets you select the
countries that are most likely to be needed, while still allowing for change. Maybe one
day you will get a customer from Angola or Turkmenistan, and then all you need to do is
open frmCountries, and add that country to the Selected Countries list. The Up and
Down buttons are used to move a selected country up or down in the sort order
(generally it is a good idea to place the most frequently used countries at the top). There
is a button to renumber the sort order after you have moved items up or down, and
another to clear all selections so you can start fresh.
Figure D shows the cboCountry list dropped down to select a country from the limited
list.

Figure D. Selecting a country from the list of selected countries


The little buttons to the right of the Country and Time Zone selector combo boxes open
the Countries or Time Zones form so you can select a new item for the limited list to

Access Archon Column 218 Page 4


display in the drop-down list. After making the selection, when you close the Countries
or Time Zones form, the Contacts form reopens, with requeried combo boxes.
The country is selected before the other components of the address because it is used in
formatting phone numbers. When you enter a phone number into the ID or Phone
column of the IDs and Phones subform on frmContacts, the txtIDOrPhone textbox's
AfterUpdate procedure (listed below) calls the FormattedPhoneNo procedure, after
stripping any nonalphanumeric characters from the entered phone number using the
StripNonAlphanumericChars procedure.

Private Sub txtIDOrPhone_AfterUpdate()

On Error GoTo ErrorHandler

Dim strRawPhone As String


Dim strDescription As String
Dim strCountryCode As String
Dim strInternetCode As String
Dim txt As Access.TextBox
Dim cbo As Access.ComboBox
Dim strCity As String

strDescription = Nz(Me![cboDescription].Value)
Set txt = Me![txtIDOrPhone]
Set cbo = Parent![cboContactCountry]
strInternetCode = Nz(cbo.Column(1))
strCountryCode = Nz(cbo.Column(2))
strCity = Nz(Parent![txtContactCity])

If strInternetCode = "" Then


strTitle = "No country selected"
strPrompt = "Please select a country"
MsgBox prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle
cbo.SetFocus
cbo.Dropdown
GoTo ErrorHandlerExit
Else
If InStr(strDescription, "Cell") > 0 Or _
InStr(strDescription, "Mobile") > 0 Then

'Format cell phone numbers

Access Archon Column 218 Page 5


strRawPhone = StripNonAlphaNumericChars(Nz(txt.Value))
txt.Value = FormattedPhoneNo(strRawPhone, strInternetCode, _
strCountryCode, strCity, True)
ElseIf InStr(strDescription, "Phone") > 0 Or _
InStr(strDescription, "Line") > 0 Or _
InStr(strDescription, "Fax") > 0 Then

'Format phone and fax numbers


strRawPhone = StripNonAlphaNumericChars(Nz(txt.Value))
txt.Value = FormattedPhoneNo(strRawPhone, strInternetCode, _
strCountryCode, strCity, False)
End If
End If

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

The FormattedPhoneNo procedure is listed below. It formats phone numbers correctly


for a variety of countries; the strCity argument is needed because of the great variety of
phone formats within the UK. If you don't need to format phone numbers for very many
countries, you can use a simpler procedure, such as the FormattedUSCanadaPhoneNo
procedure, which only has a strCountry argument. This procedure only formats U.S. and
Canadian phone numbers; all others are left as entered. These procedures, plus the
StripNonAlphaNumericChars procedure used to prepare the entered phone number for
formatting, are listed below.
Public Function FormattedPhoneNo(strRawPhoneNo As String, _
strInternetCode As String, strCountryCode As String, _
strCity As String, blnCell As Boolean) As String

On Error GoTo ErrorHandler

intLength = Len(strRawPhoneNo)
strNumberPortion = Left(strRawPhoneNo, 10)

Access Archon Column 218 Page 6


intxPosition = Nz(InStr(strRawPhoneNo, "x"))

If intxPosition > 0 Then


strExtPortion = Mid(strRawPhoneNo, intxPosition)
End If

Select Case strInternetCode

Case "US"
strTitle = "Format problem"
strPrompt = "United States phone numbers must have 10 digits"

Select Case intLength

Case 10
FormattedPhoneNo = Format(strRawPhoneNo, "(###) ###-####")

Case Is < 10
MsgBox strPrompt, vbExclamation, strTitle

Case Is > 10
If intxPosition > 0 Then
FormattedPhoneNo = Format(strNumberPortion, _
"(###) ###-####") _
& " " & Trim(strExtPortion)
Else
MsgBox strPrompt, vbExclamation, strTitle
End If

End Select

Case "CA"
strTitle = "Format problem"
strPrompt = "Canadian phone numbers must have 10 digits"

Select Case intLength

Case 10
FormattedPhoneNo = Format(strRawPhoneNo, "(###) ###-####")

Access Archon Column 218 Page 7


Case Is < 10
MsgBox strPrompt, vbExclamation, strTitle

Case Is > 10
If intxPosition > 0 Then
FormattedPhoneNo = Format(strNumberPortion, _
"(###) ###-####") _
& " " & Trim(strExtPortion)
Else
MsgBox strPrompt, vbExclamation, strTitle
End If

End Select

Case "UK"

'Because of the great complexity of UK phone formatting,


'not all numbers may be formatted correctly

[UK formatting code omitted – see the module for details]

Case "AU"
strTitle = "Format problem"
strPrompt = "Australian phone numbers must have 10 digits"

Select Case intLength

Case 10
If blnCell = True Then
FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strRawPhoneNo, "####-###-###")
ElseIf blnCell = False Then
FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strRawPhoneNo, "(##) ####-####")
End If

Case Is < 10
MsgBox strPrompt, vbExclamation, strTitle

Case Is > 10
If intxPosition > 0 Then

Access Archon Column 218 Page 8


FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strNumberPortion, "(##) ####-####") _
& " " & Trim(strExtPortion)
Else
MsgBox strPrompt, vbExclamation, strTitle
End If
End Select

Case "ZA"
strTitle = "Format problem"
strPrompt = "South African phone numbers must have 10 digits"

Select Case intLength

Case 10
FormattedPhoneNo = Format(strRawPhoneNo, "(###) ###-####")

Case Is < 10
MsgBox strPrompt, vbExclamation, strTitle

Case Is > 10
If intxPosition > 0 Then
FormattedPhoneNo = Format(strNumberPortion, _
"(###) ###-####") & " " & Trim(strExtPortion)
Else
MsgBox strPrompt, vbExclamation, strTitle
End If

End Select

Case "NZ"
strTitle = "Format problem"
strPrompt = "New Zealand phone numbers must have from 9 to 11 digits"

Select Case intLength

Case 9
If blnCell = False Then
FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strRawPhoneNo, "(##) ###-####")

Access Archon Column 218 Page 9


ElseIf blnCell = True Then
MsgBox strPrompt, vbExclamation, strTitle
End If

Case 10
If blnCell = True Then
FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strRawPhoneNo, "(###) ###-####")
ElseIf blnCell = False Then
MsgBox strPrompt, vbExclamation, strTitle
End If

Case 11
If blnCell = True Then
FormattedPhoneNo = "+" & strCountryCode & " " _
& Format(strRawPhoneNo, "(####) ###-####")
ElseIf blnCell = False Then
MsgBox strPrompt, vbExclamation, strTitle
End If

Case Else
MsgBox strPrompt, vbExclamation, strTitle

End Select

End Select

ErrorHandlerExit:
Exit Function

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in FormattedPhoneNo procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Function

Public Function FormattedUSCanadaPhoneNo(strRawPhoneNo As String)

Access Archon Column 218 Page 10


On Error GoTo ErrorHandler

Dim strNumberPortion As String


Dim strExtPortion As String
Dim intxPosition As Integer

intLength = Len(strRawPhoneNo)
strNumberPortion = Left(strRawPhoneNo, 10)
intxPosition = Nz(InStr(strRawPhoneNo, "x"))

If intxPosition > 0 Then


strExtPortion = Mid(strRawPhoneNo, intxPosition)
End If

strTitle = "Format problem"


strPrompt = "United States and Canadian phone numbers must have 10 digits"

Select Case intLength

Case 10
FormattedUSCanadaPhoneNo = Format(strRawPhoneNo, _
"(###) ###-####")

Case Is < 10
MsgBox strPrompt, vbExclamation, strTitle

Case Is > 10
If intxPosition > 0 Then
FormattedUSCanadaPhoneNo = Format(strNumberPortion, _
"(###) ###-####") & " " & Trim(strExtPortion)
Else
MsgBox strPrompt, vbExclamation, strTitle
End If

End Select

ErrorHandlerExit:
Exit Function

ErrorHandler:

Access Archon Column 218 Page 11


MsgBox "Error No: " & Err.Number _
& " in FormattedPhoneNo procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Function

Public Function StripNonAlphaNumericChars(strText As String) As String


'Strips a variety of non-alphanumeric characters from a text string
'Created by Helen Feddema 10-15-97
'Modified by Ruud H.G. van Tol 6-18-99
'Modified by Brad Beacham 6-Feb-2005
'Last modified by Helen Feddema 7-Feb-2005

On Error GoTo ErrorHandler

Dim strTestString As String


Dim strBadChar As String
Dim i As Integer
Dim strStripChars As String

strStripChars = " `~!@#$%^&*()-_=+[{]};:',<.>/?" & Chr$(34) & Chr$(13) _


& Chr$(10)
strTestString = strText

For i = 1 To Len(strStripChars)
strBadChar = Mid(strStripChars, i, 1)
strTestString = Replace(strTestString, strBadChar, vbNullString)
Next

StripNonAlphaNumericChars = strTestString

ErrorHandlerExit:
Exit Function

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in StripNonAlphaNumericChars procedure; " _
& "Description: " & Err.Description

Access Archon Column 218 Page 12


Resume ErrorHandlerExit

End Function

VBA Code
The frmCountries code module is listed below (frmTimeZones has similar code):
Option Explicit

Private lngCounter As Long


Private lstAvailable As Access.ListBox
Private lstSelected As Access.ListBox
Private lngSortOrder As Long
Private strTable As String
Private rst As DAO.Recordset
Private strSearch As String
Private strCountry As String
Private strPrompt As String
Private strTitle As String
Private strQuery As String

Private Sub cmdClearAll_Click()

On Error GoTo ErrorHandler

Set lstSelected = Me![lstSelectedCountries]


strTable = "tblCountries"
strQuery = "qrySelectedCountries"
lngCounter = 1

Set rst = CurrentDb.OpenRecordset(strTable)

Do While Not rst.EOF


rst.Edit
rst![SortOrder] = Null
rst.Update
rst.MoveNext
Loop

Access Archon Column 218 Page 13


lstAvailable.Requery
lstSelected.Requery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub cmdDeselectCountry_Click()

On Error GoTo ErrorHandler

Set lstAvailable = Me![lstAvailableCountries]


Set lstSelected = Me![lstSelectedCountries]
strTable = "tblCountries"
strCountry = Nz(lstSelected.Column(0))

If strCountry = "" Then


strTitle = "No country selected"
strPrompt = "Please select a country to move"
MsgBox prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle
GoTo ErrorHandlerExit
End If

Set rst = CurrentDb.OpenRecordset(strTable, dbOpenDynaset)


strSearch = "[CountryName] = " & Chr(39) & strCountry _
& Chr(39)
Debug.Print "Search string: " & strSearch
rst.FindFirst strSearch
If rst.NoMatch = False Then
rst.Edit
rst![SortOrder] = Null

Access Archon Column 218 Page 14


rst.Update
End If
rst.Close

lstSelected.Requery
lstAvailable.Requery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub cmdMoveDown_Click()

On Error GoTo ErrorHandler

Set lstSelected = Me![lstSelectedCountries]


strTable = "tblCountries"
strQuery = "qrySelectedCountries"
strCountry = Nz(lstSelected.Column(0))

If strCountry = "" Then


strTitle = "No country selected"
strPrompt = "Please select a country to move"
MsgBox prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle
GoTo ErrorHandlerExit
End If

Set rst = CurrentDb.OpenRecordset(strQuery, dbOpenDynaset)


strSearch = "[CountryName] = " & Chr(39) & strCountry _
& Chr(39)
Debug.Print "Search string: " & strSearch

Access Archon Column 218 Page 15


rst.FindFirst strSearch
If rst.NoMatch = False Then
rst.Edit
lngSortOrder = rst![SortOrder]
rst![SortOrder] = lngSortOrder + 1
rst.Update
rst.MoveNext
rst.Edit
rst![SortOrder] = lngSortOrder
rst.Update
End If

lstSelected.Requery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub cmdMoveUp_Click()

On Error GoTo ErrorHandler

Set lstSelected = Me![lstSelectedCountries]


strTable = "tblCountries"
strQuery = "qrySelectedCountries"
strCountry = Nz(lstSelected.Column(0))

If strCountry = "" Then


strTitle = "No country selected"
strPrompt = "Please select a country to move"
MsgBox prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle

Access Archon Column 218 Page 16


GoTo ErrorHandlerExit
End If

Set rst = CurrentDb.OpenRecordset(strQuery, dbOpenDynaset)


strSearch = "[CountryName] = " & Chr(39) & strCountry _
& Chr(39)
Debug.Print "Search string: " & strSearch
rst.FindFirst strSearch
If rst.NoMatch = False Then
rst.Edit
lngSortOrder = rst![SortOrder]
rst![SortOrder] = lngSortOrder - 1
rst.Update
rst.MovePrevious
rst.Edit
rst![SortOrder] = lngSortOrder
rst.Update
End If

lstSelected.Requery
lstSelected.RowSource = strQuery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub cmdRenumberItems_Click()

On Error GoTo ErrorHandler

Set lstSelected = Me![lstSelectedCountries]


strQuery = "qrySelectedCountries"
lngCounter = 1

Access Archon Column 218 Page 17


Set rst = CurrentDb.OpenRecordset(strQuery)

Do While Not rst.EOF


rst.Edit
rst![SortOrder] = lngCounter
rst.Update
lngCounter = lngCounter + 1
rst.MoveNext
Loop

lstSelected.RowSource = strQuery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub cmdSelectCountry_Click()

On Error GoTo ErrorHandler

Set lstAvailable = Me![lstAvailableCountries]


Set lstSelected = Me![lstSelectedCountries]

strTable = "tblCountries"
strCountry = Nz(lstAvailable.Column(0))

If strCountry = "" Then


strTitle = "No country selected"
strPrompt = "Please select a country to move"
MsgBox prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle

Access Archon Column 218 Page 18


GoTo ErrorHandlerExit
End If

strSearch = "[CountryName] = " & Chr(39) & strCountry _


& Chr(39)
Debug.Print "Search string: " & strSearch
lngSortOrder = Nz(DMax("[SortOrder]", strTable))

Set rst = CurrentDb.OpenRecordset(strTable, dbOpenDynaset)


rst.FindFirst strSearch
If rst.NoMatch = False Then
rst.Edit
rst![SortOrder] = lngSortOrder + 1
rst.Update
rst.Close
End If

lstSelected.Requery
lstAvailable.Requery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.ActiveControl.Name & " procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit

End Sub

Private Sub Form_Close()

On Error GoTo ErrorHandler

Dim prj As Object

Set prj = Application.CurrentProject

If prj.AllForms("fmnuMain").IsLoaded = True Then

Access Archon Column 218 Page 19


Forms![fmnuMain].Visible = True
Else
DoCmd.OpenForm "fmnuMain"
End If

ErrorHandlerExit:
Exit Sub

ErrorHandler:
If Err.Number = 40036 Then
Resume ErrorHandlerExit
Else
MsgBox "Error No: " & Err.Number _
& " in Form_Close procedure; Description: " _
& Err.Description
Resume ErrorHandlerExit
End If

End Sub

Private Sub Form_Load()

On Error Resume Next

DoCmd.RunCommand acCmdSizeToFitForm

On Error GoTo ErrorHandler

Set lstAvailable = Me![lstAvailableCountries]


Set lstSelected = Me![lstSelectedCountries]
lstAvailable.Requery
lstSelected.Requery

ErrorHandlerExit:
Exit Sub

ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in " & Me.Name & " Form_Load procedure; " _
& "Description: " & Err.Description

Access Archon Column 218 Page 20


Resume ErrorHandlerExit

End Sub

References
The code in the sample database does not need any special references.

Supporting Files
The zip file containing this article, in Word 97-2003 format, plus the supporting file(s),
may be downloaded from the Access Archon page of my Web site, as accarch218.zip,
which is the last entry in the table of Access Archon columns for Access Watch.
Document Name Document Type Place in
Selecting Countries (AA Access 2002-2003 database Wherever you want
218).mdb (can also be used in higher
versions of Access)

Access Archon Column 218 Page 21

You might also like