I recently had to make a minor change to a poorly designed, but large database and had to determine where certain fields were being used so I could go make the necessary changes. In this case, I had to review hundreds of MS Access objects, so a manual approach was just not acceptable. As such, I created a VBA to let the computer do the checking for me and report back. Below is the fruits of my labor.
'---------------------------------------------------------------------------------------
' Procedure : FindFieldUsedWhere
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Locate where a field is used within queries, forms and reports
' Copyright : The following may be altered and reused as you wish so long as the
' copyright notice is left unchanged (including Author, Website and
' Copyright). It may not be sold/resold or reposted on other sites (links
' back to this site are allowed).
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sFieldName : Field Name to search for in the various Access objects
'
' Usage:
' ~~~~~~
' FindFieldUsedWhere("Type A")
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2011-04-08 Initial Release
'---------------------------------------------------------------------------------------
Function FindFieldUsedWhere(sFieldName As String)
On Error GoTo Error_Handler
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim sSQL As String
Dim ctl As Control
Dim frm As AccessObject
Dim DbO As AccessObject
Dim DbP As Object
Set db = CurrentDb
Debug.Print "FindFieldUsedWhere Begin"
Debug.Print "Searching for '" & sFieldName & "'"
Debug.Print "================================================================================"
'Check Queries
For Each qdf In db.QueryDefs
'qdf.Name 'The current query's name
'qdf.SQL 'The current query's SQL statement
sSQL = qdf.SQL
If InStr(sSQL, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Query: " & qdf.Name
End If
Next
'Check Forms
For Each frm In CurrentProject.AllForms
DoCmd.OpenForm frm.Name, acDesign
If InStr(Forms(frm.Name).RecordSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Form: " & frm.Name
End If
'Loop throught the Form Controls
For Each ctl In Forms(frm.Name).Form.Controls
Select Case ctl.ControlType
Case acComboBox
If Len(ctl.Tag) > 0 Then
If InStr(ctl.Tag, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
End If
If InStr(ctl.ControlSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
End If
End If
Case acTextBox, acCheckBox
If InStr(ctl.ControlSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Form: " & frm.Name & " :: Control: " & ctl.Name
End If
End Select
Next ctl
DoCmd.Close acForm, frm.Name, acSaveNo
Next frm
'Check Reports
Set DbP = Application.CurrentProject
For Each DbO In DbP.AllReports
DoCmd.OpenReport DbO.Name, acDesign
If InStr(Reports(DbO.Name).RecordSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Report: " & DbO.Name
End If
'Loop throught the Report Controls
For Each ctl In Reports(DbO.Name).Report.Controls
Select Case ctl.ControlType
Case acComboBox
If Len(ctl.Tag) > 0 Then
If InStr(ctl.Tag, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
End If
If InStr(ctl.ControlSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
End If
End If
Case acTextBox, acCheckBox
If InStr(ctl.ControlSource, sFieldName) Then
'The Query is a Make Table Query and has our TableName we are looking for
Debug.Print "Report: " & DbO.Name & " :: Control: " & ctl.Name
End If
End Select
Next ctl
DoCmd.Close acReport, DbO.Name, acSaveNo
Next DbO
Debug.Print "================================================================================"
Debug.Print "FindFieldUsedWhere End"
Error_Handler_Exit:
On Error Resume Next
Set qdf = Nothing
Set db = Nothing
Set ctl = Nothing
Set frm = Nothing
Set DbP = Nothing
Set DbO = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: FindFieldUsedWhere" & vbCrLf & _
"Error Description: " & Err.Description, vbCritical, "An Error has Occurred
Resume Error_Handler_Exit
End Function
This is my first draft and I haven’t looked at optimizing my code. It was more about getting results than developing a procedure to be reused often. Hopefully it can help someone else in the same boat as I found myself! Simply execute the procedure and it will return a listing of what Access objects use the specified field in the immediate window of the VBE console.
Thierry,
J’ai revisé la procedure et elle devrait marcher pour toi maintenant!
This is great. Thank you!!
Simply, once I have the VBA inside my database, how do I get it to show results? How do I run it?
That depends on you and what you’re trying to do exactly. Most of the time I simply call the function in the immediate window by typing
? FindFieldUsedWhere(“NameOfTheFieldImLookingFor”)
great thanks. I’ve set this up on a button in my databases and output the results to screen
11 YEARS later and still useful!
Thanks,
VInce
Fantastic function.
I have a question.
When running the function using a Constant, the procedure (or VBA itself) changes the Constant into its value.
In my test, the Const is fCMD_ALIENJO and the Value is “frmUC28_R10”.
So, instead of searching for fCMD_ALIENJO, it searched for “frmUC28_R10”.
Is this behavior by design?
Thanks
I’ve never experience what you described, but without a concrete example/demo db to see the issue firsthand it is impossible for me to comment as to what may be going on.