Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introduction
Access add-ins come in three types:
Wizard – a series of forms guiding you through creating a new object such as a form
or report
Builder – A single form or dialog box that creates a property or expression
Menu Add-in – A non-context-specific function that runs from the Tools|Add-ins
menu
This document describes the updated version of a set of Access add-ins I wrote to
automate the process of renaming database objects (tables, queries, forms, reports,
macros and modules) and also controls on forms and reports. The Access 2007/2010
version only does control renaming, because the Find And Replace add-in it calls for
object renaming doesn't work reliably in Access 2007 or 2010 (though if you wish to try
it, I have found that the LNC Rename.mda add-in works with FAR v. 9.0g-9.0i, though
you have to accept a warning message about the version when renaming database
objects).
The three types of add-ins (with several subtypes) are listed in Table 1. Note that the
nomenclature isn't too consistent—in real life, any kind of add-in might be called a
Wizard.
Table 1: The Add-in Types
USysRegInfo Table
The USysRegInfo table is a system table that stores information about add-ins which is
written to the Windows Registry when the add-ins are installed. This table has four
fields, containing the data described in Table 2:
Table 2: The USysRegInfo Table
The USysRegInfo table for the LNC Rename add-ins library database is shown in Table
3. This table contains several groups of rows, one group for each of the add-in
components (two property builders).
Table 3. USysRegInfo Table Rows for the LNC Control Renaming 2007 Add-in
Note: Although |ACCDIR is supposed to reference the folder in which the Access
executable is stored (Microsoft Office\Office12 for Access 2007 and Office14 for Access
2010), because at one time (long ago) that is where add-ins were stored, it still works
with add-ins stored in the Addins folder.
To install the add-ins, copy the files in the zip to the locations indicated in Table 4 below:
Table 4: File Locations
The Choose Builder dialog opens, as shown below, where you can see two LNC Rename
Property Wizards (and perhaps others you may have installed).
Note: The Smart Rename builder is installed when you install FAR; since isn't needed, I
recommend deleting its key from the Registry, as shown below
Troubleshooting
AutoCorrect
Access 2000 added an AutoCorrect feature that many developers hoped would make it
easier to rename database objects, but unfortunately this feature has several serious
flaws, which make it basically unworkable. Basically, AutoCorrect fixes some (but not
all) references to renamed objects, and none of the references in VBA code, which makes
it pretty much worthless, since you will have to use a utility such as FAR to correct the
missed references. It's easier to just use FAR directly.
Additionally, AutoCorrect has a very annoying feature of "correcting" references that
should not be corrected. For example, if you are working on the design of a form called
frmOrders, and you make a backup copy of the form, called –frmOrders1, you will find
that references to frmOrders (say, in a query criterion) may be changed to –frmOrders1,
resulting in errors.
I recommend turning off AutoCorrect in the General tab of the Access Options dialog
and using LNC Rename and/or FAR to rename database objects as needed.
Debugging
If you have selected the Break on All Errors option in the Options dialog for modules,
you will get numerous error messages. Instead, select Break on Unhandled Errors so the
add-ins error handing will work correctly:
strOldCtlName = strCurrentValue
If strOldCtlName = "Detail" Then
strPrompt = "Please select a control to rename"
MsgBox strPrompt, vbExclamation
GoTo ErrorHandlerExit
End If
ObjectIsForm:
Set pfrm = Forms(strObjectName)
Set pctl = pfrm(strCtlName)
GoTo DetermineControlType
ObjectIsReport:
Set prpt = Reports(strObjectName)
Set pctl = prpt(strCtlName)
DetermineControlType:
lngControlType = pctl.ControlType
Case acComboBox
strPrefix = "cbo"
strNewCtlName = ControlCS(pctl, strPrefix, blnTag, False)
Case acBoundObjectFrame
strPrefix = "frb"
strNewCtlName = ControlCS(pctl, strPrefix, blnTag, False)
Case acListBox
strPrefix = "lst"
strNewCtlName = ControlCS(pctl, strPrefix, blnTag, False)
Case acAttachment
strPrefix = "att"
Call ControlCS(pctl, strPrefix, blnTag, False)
Case acOptionGroup
strPrefix = "fra"
strNewCtlName = ControlCS(pctl, strPrefix, blnTag, False)
Case acOptionButton
strPrefix = "opt"
strControlSource = pctl.ControlSource
If blnUnbound = False Then
strNewCtlName = ControlCS(pctl, strPrefix, blnTag, False)
Else
strNewCtlName = ControlNA(pctl, strPrefix, blnTag, False)
End If
Case acLabel
strPrefix = "lbl"
strNewCtlName = ControlCA(pctl, strPrefix, blnTag, False)
Case acCommandButton
strPrefix = "cmd"
strNewCtlName = ControlCA(pctl, strPrefix, blnTag, False)
Case acPage
strPrefix = "pge"
strNewCtlName = ControlCA(pctl, strPrefix, blnTag, False)
Case acImage
strPrefix = "img"
Case acTabCtl
strPrefix = "tab"
strNewCtlName = ControlNA(pctl, strPrefix, blnTag, False)
Case acLine
strPrefix = "lin"
strNewCtlName = ControlNA(pctl, strPrefix, blnTag, False)
Case acPageBreak
strPrefix = "brk"
strNewCtlName = ControlNA(pctl, strPrefix, blnTag, False)
Case acRectangle
strPrefix = "shp"
strNewCtlName = ControlNA(pctl, strPrefix, blnTag, False)
End Select
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If an option button or checkbox is unbound, set
'blnUnbound to True so the code uses the NA function instead of CS
Select Case Err.Number
Case 2455
blnUnbound = True
Resume Next
Case Else
MsgBox "Error No: " & Err.Number _
& " in LNCBuilder procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End Select
End Function
strOldCtlName = strCurrentValue
ObjectIsForm:
Set pfrm = Forms(strObjectName)
For Each pctl In pfrm.Controls
strCtlName = pctl.Name
lngControlType = pctl.ControlType
blnUnbound = False
Case acComboBox
strPrefix = "cbo"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acCheckBox
strPrefix = "chk"
strControlSource = pctl.ControlSource
If blnUnbound = False Then
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Else
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End If
Case acBoundObjectFrame
strPrefix = "frb"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acListBox
Case acOptionGroup
strPrefix = "fra"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acAttachment
strPrefix = "att"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acOptionButton
strPrefix = "opt"
strControlSource = pctl.ControlSource
If blnUnbound = False Then
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Else
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End If
Case acLabel
strPrefix = "lbl"
Call ControlCA(pctl, strPrefix, blnTag, blnPrompt)
Case acCommandButton
strPrefix = "cmd"
Call ControlCA(pctl, strPrefix, blnTag, blnPrompt)
Case acPage
strPrefix = "pge"
Call ControlCA(pctl, strPrefix, blnTag, blnPrompt)
Case acImage
strPrefix = "img"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acTabCtl
strPrefix = "tab"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acLine
strPrefix = "lin"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acPageBreak
strPrefix = "brk"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End Select
SkipToHereForm:
Next pctl
GoTo Success
ObjectIsReport:
Set prpt = Reports(strObjectName)
For Each pctl In prpt.Controls
strCtlName = pctl.Name
lngControlType = pctl.ControlType
blnUnbound = False
Case acComboBox
strPrefix = "cbo"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acCheckBox
strPrefix = "chk"
strControlSource = pctl.ControlSource
If blnUnbound = False Then
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Else
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End If
Case acBoundObjectFrame
strPrefix = "frb"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acListBox
strPrefix = "lst"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acOptionGroup
strPrefix = "fra"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acAttachment
strPrefix = "att"
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Case acOptionButton
strPrefix = "opt"
strControlSource = pctl.ControlSource
If blnUnbound = False Then
Call ControlCS(pctl, strPrefix, blnTag, blnPrompt)
Else
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End If
Case acLabel
strPrefix = "lbl"
Call ControlCA(pctl, strPrefix, blnTag, blnPrompt)
Case acCommandButton
strPrefix = "cmd"
Call ControlCA(pctl, strPrefix, blnTag, blnPrompt)
Case acImage
strPrefix = "img"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acTabCtl
strPrefix = "tab"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acLine
strPrefix = "lin"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acPage
strPrefix = "pge"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acPageBreak
strPrefix = "brk"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
Case acRectangle
strPrefix = "shp"
Call ControlNA(pctl, strPrefix, blnTag, blnPrompt)
End Select
SkipToHereReport:
Next pctl
Success:
MsgBox "All controls renamed!"
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If an option button or checkbox is unbound, set
'blnUnbound to True so the code uses the NA function instead of CS
If Err.Number = 2455 Then
blnUnbound = True
Resume Next
Else
End Function
i = 1
Do While i <= Len(strTestString)
'Find a strippable character
strTestChar = Mid$(strTestString, i, 1)
lngFound = InStr(strStripChars, strTestChar)
If lngFound > 0 Then
strTestString = Left(strTestString, i - 1) & Mid(strTestString, i + 1)
Else
i = i + 1
End If
Loop
StripNonAlphaNumericChars = strTestString
ErrorHandlerExit:
Exit Function
ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in StripNonAlphaNumericChars procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End Function
strControlSource = Nz(ctlSelected.ControlSource)
strOldCtlName = ctlSelected.ControlName
lngControlType = ctlSelected.ControlType
'Check whether control already is correctly named and also special case
'for controls whose original name starts with "Option" or "Frame"
'(same first three letters as prefix)
If Left(strOldCtlName, 3) = strPrefix And _
Left(strOldCtlName, 6) <> "Option" And _
Left(strOldCtlName, 3) = strPrefix And _
Left(strOldCtlName, 5) <> "Frame" Then
GoTo ErrorHandlerExit
AutoRename:
If blnPrompt = True Then
GoTo TestNewName
ElseIf blnPrompt = False Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
GoTo ErrorHandlerExit
End If
TestNewName:
'Show the user
' - the original control name
' - the control type
' - control source
' - proposed new name
'and ask if the new name is acceptable.
blnRenameFail = True
Do While blnRenameFail
blnRenameFail = False
strTitle = "Rename control"
strPrompt = "Rename " & ControlTypeName(lngControlType) _
& " control currently named " _
& strOldCtlName & vbCrLf & _
"(control source: " & strControlSource & ") " & _
"to" & vbCrLf & strNewCtlName & "?"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbYesNoCancel + vbQuestion + vbDefaultButton1, _
Title:=strTitle)
'If the user clicks the Yes button, rename the control
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If the proposed control name is already in use,
'return to the renaming dialog.
blnRenameFail = True
If Err.Number = 2104 Then
If blnPrompt = True Then
strTitle = "Duplicate Control Name"
strPrompt = "There is another control named " & _
strNewCtlName & "; please try again"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKCancel, _
Title:=strTitle)
If intReturn = vbOK Then
strNewCtlName = strNewCtlName & "1"
ElseIf intReturn = vbCancel Then
GoTo TestNewName
End If
ElseIf blnPrompt = False Then
strNewCtlName = strNewCtlName + CStr(Int((20 - 1) * Rnd + 1))
GoTo AutoRename
End If
ElseIf Err.Number = 2123 Then
strTitle = "Unacceptable Control Name"
strPrompt = "Please enter an acceptable control name"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle)
GoTo TestNewName
Else
MsgBox "Error No: " & Err.Number _
& " in ControlCS procedure; " _
& "Description: " & Err.Description
End If
End Function
strOldCtlName = ctlSelected.ControlName
strCaption = ctlSelected.Caption
lngControlType = ctlSelected.ControlType
AutoRename:
If blnPrompt = True Then
GoTo TestNewName
ElseIf blnPrompt = False Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
GoTo ErrorHandlerExit
End If
'If the user clicks the Yes button, rename the control
If intReturn = vbYes Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
ElseIf intReturn = vbNo Then
UserInputName:
'Pop up an input box to edit the name.
strProposedNewCtlName = _
StripNonAlphaNumericChars(InputBox("Modify new control name", _
"Rename control", strNewCtlName))
'Test whether proposed control name is blank, or just
'non-permitted characters
If strProposedNewCtlName = "" Then
'User canceled
GoTo ErrorHandlerExit
Else
strNewCtlName = strProposedNewCtlName
ctlSelected.ControlName = strNewCtlName
GoTo TestNewName
End If
ElseIf intReturn = vbCancel Then
GoTo ErrorHandlerExit
End If
Loop
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If the proposed control name is already in use,
'return to the renaming dialog.
blnRenameFail = True
If Err.Number = 2104 Then
If blnPrompt = True Then
strTitle = "Duplicate Control Name"
strPrompt = "There is another control named " & _
strNewCtlName & "; please try again"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKCancel, _
Resume Next
End Function
strOldCtlName = ctlSelected.ControlName
strSourceObject = Nz(ctlSelected.SourceObject)
lngControlType = ctlSelected.ControlType
AutoRename:
If blnPrompt = True Then
GoTo TestNewName
ElseIf blnPrompt = False Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
GoTo ErrorHandlerExit
End If
TestNewName:
'Show the user
' - the original control name
' - the control type
' - control source
' - proposed new name
'and ask if the new name is acceptable.
blnRenameFail = True
Do While blnRenameFail
blnRenameFail = False
strTitle = "Rename control"
strPrompt = "Rename " & ControlTypeName(lngControlType) _
& " control currently named " _
& strOldCtlName & vbCrLf & _
"(control source: " & strControlSource & ") " & _
"to" & vbCrLf & strNewCtlName & "?"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbYesNoCancel + vbQuestion + vbDefaultButton1, _
Title:=strTitle)
'If the user clicks the Yes button, rename the control
If intReturn = vbYes Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
ElseIf intReturn = vbNo Then
UserInputName:
'Pop up an input box to edit the name.
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If the proposed control name is already in use,
'return to the renaming dialog.
blnRenameFail = True
If Err.Number = 2104 Then
If blnPrompt = True Then
strTitle = "Duplicate Control Name"
strPrompt = "There is another control named " & _
strNewCtlName & "; please try again"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKCancel, _
Title:=strTitle)
If intReturn = vbOK Then
strNewCtlName = strNewCtlName & "1"
ElseIf intReturn = vbCancel Then
GoTo TestNewName
End If
ElseIf blnPrompt = False Then
strNewCtlName = strNewCtlName + CStr(Int((20 - 1) * Rnd + 1))
GoTo AutoRename
End If
ElseIf Err.Number = 2123 Then
strTitle = "Unacceptable Control Name"
strPrompt = "Please enter an acceptable control name"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle)
GoTo TestNewName
Else
MsgBox "Error No: " & Err.Number _
& " in ControlSO procedure; " _
& "Description: " & Err.Description
End If
Resume Next
End Function
strOldCtlName = ctlSelected.ControlName
lngControlType = ctlSelected.ControlType
AutoRename:
If blnPrompt = True Then
GoTo TestNewName
ElseIf blnPrompt = False Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
GoTo ErrorHandlerExit
End If
TestNewName:
'Show the user
' - the original control name
' - the control type
' - control source
' - proposed new name
'and ask if the new name is acceptable.
blnRenameFail = True
Do While blnRenameFail
blnRenameFail = False
strTitle = "Rename control"
strPrompt = "Rename " & ControlTypeName(lngControlType) _
& " control currently named " _
& strOldCtlName & vbCrLf & _
"(control source: " & strControlSource & ") " & _
"to" & vbCrLf & strNewCtlName & "?"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbYesNoCancel + vbQuestion + vbDefaultButton1, _
Title:=strTitle)
'If the user clicks the Yes button, rename the control
If intReturn = vbYes Then
If blnTag = True Then
ctlSelected.Tag = ctlSelected.ControlName
End If
ctlSelected.ControlName = strNewCtlName
ElseIf intReturn = vbNo Then
UserInputName:
'Pop up an input box to edit the name.
ErrorHandlerExit:
Exit Function
ErrorHandler:
'If the proposed control name is already in use,
'return to the renaming dialog.
blnRenameFail = True
If Err.Number = 2104 Then
If blnPrompt = True Then
strTitle = "Duplicate Control Name"
strPrompt = "There is another control named " & _
strNewCtlName & "; please try again"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKCancel, _
Title:=strTitle)
If intReturn = vbOK Then
strNewCtlName = strNewCtlName & "1"
ElseIf intReturn = vbCancel Then
GoTo TestNewName
End If
ElseIf blnPrompt = False Then
strNewCtlName = strNewCtlName + CStr(Int((20 - 1) * Rnd + 1))
GoTo AutoRename
End If
ElseIf Err.Number = 2123 Then
strTitle = "Unacceptable Control Name"
strPrompt = "Please enter an acceptable control name"
intReturn = MsgBox(prompt:=strPrompt, _
Buttons:=vbExclamation + vbOKOnly, _
Title:=strTitle)
GoTo TestNewName
Else
MsgBox "Error No: " & Err.Number _
& " in ControlNA procedure; " _
& "Description: " & Err.Description
End If
Resume Next
End Function
ErrorHandlerExit:
Exit Sub
ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in DeleteAndRecreate procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End Sub
Case 100
ControlTypeName = "Label"
Case 101
ControlTypeName = "Rectangle"
Case 102
ControlTypeName = "Line"
Case 103
ControlTypeName = "Image"
Case 104
ControlTypeName = "Command Button"
Case 105
ControlTypeName = "Option Button"
Case 106
ControlTypeName = "Check Box"
Case 107
ControlTypeName = "Option Group"
Case 109
ControlTypeName = "Text Box"
Case 110
ControlTypeName = "List Box"
Case 111
ControlTypeName = "Combo Box"
Case 112
ControlTypeName = "Subform/Subreport"
Case 114
ControlTypeName = "Object Frame"
Case 118
ControlTypeName = "Page Break"
Case 122
ControlTypeName = "Toggle Button"
Case 123
ControlTypeName = "Tab Control"
Case 124
ControlTypeName = "Page"
Case 126
ControlTypeName = "Attachment"
Case Else
ControlTypeName = "Unknown"
End Select
ErrorHandlerExit:
Exit Function
ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in ControlTypeName procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End Function
ErrorHandlerExit:
Exit Function
ErrorHandler:
If Err.Number = 3021 Then
CreateAndTestQuery = 0
Resume ErrorHandlerExit
Else
MsgBox "Error No: " & Err.Number _
& " in CreateAndTestQuery procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End If
End Function
ErrorHandlerExit:
Exit Sub
ErrorHandler:
MsgBox "Error No: " & Err.Number _
& " in DeleteTable procedure; " _
& "Description: " & Err.Description
Resume ErrorHandlerExit
End Sub
Notes
7/2/99 Added linefeed and carriage return characters (ASCII #13 and #10) to list of
characters to strip out of control names (primarily for multi-line labels)
7/7/01 Updated database to work with Access 2002/FAR 9e
7/26/07 Added dialog for entering custom LNC tags
7/29/07 Added confirmation message to allow automatic renaming of all form or
report controls.
1/21/11 Created this Access 2007 version of the add-in, for control renaming only.