Most people already know that I do not favor Embedded Macros in any capacity. Unlike VBA, Macros are more complicated to program, are not searchable making it hard to perform database updates.
Long story short, I was working on a project a short while ago where I need to do a major cleanup of object names, control names, … and was needing to identify where object were being used so I could update them. Then I decided, even better, let’s find all the Embedded Macros so I can simply convert them over to plain VBA and then this problem would not occur again in the future.
As such, I put together the following procedure which goes through all the database Forms and Reports and their respective controls to identify those that use Embedded Macros. Hopefully it can help someone else.
'---------------------------------------------------------------------------------------
' Procedure : FindEmbeddedMacros
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website : http://www.cardaconsultants.com
' Purpose : Search Forms & Reports to locate any Embedded Macros
' The search results are printed to the immediate window
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) - https://creativecommons.org/licenses/by-sa/4.0/
' Req'd Refs: Uses Late Binding, so none required
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' None
'
' Usage:
' ~~~~~~
' ?FindEmbeddedMacros
' Call FindEmbeddedMacros
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2017-01-07 Initial Release
' 2 2018-05-24 Copyright updated
'---------------------------------------------------------------------------------------
Public Sub FindEmbeddedMacros()
On Error GoTo Error_Handler
Dim oFrm As Object
Dim frm As Access.Form
Dim oRpt As Object
Dim rpt As Access.Report
Dim ctl As Access.Control
Dim prp As DAO.Property
Access.Application.Echo False
Debug.Print "Search Results"
Debug.Print "Object Type", "Object Name", "Control Name", "Event Name"
Debug.Print String(80, "-")
'Search the forms
For Each oFrm In Application.CurrentProject.AllForms
DoCmd.OpenForm oFrm.Name, acDesign
Set frm = Forms(oFrm.Name).Form
With frm
For Each prp In .Properties
'Form Properties
If InStr(prp.Name, "EMMacro") > 0 Then
If Len(prp.value) > 0 Then
Debug.Print "Form", frm.Name, , Replace(prp.Name, "EmMacro", "")
End If
End If
Next prp
'Form Control Properties
For Each ctl In frm.Controls
For Each prp In ctl.Properties
If InStr(prp.Name, "EMMacro") > 0 Then
If Len(prp.value) > 0 Then
Debug.Print "Form", frm.Name, ctl.Name, Replace(prp.Name, "EmMacro", "")
End If
End If
Next prp
Next ctl
End With
DoCmd.Close acForm, oFrm.Name, acSaveNo
Next oFrm
'Search the Reports
For Each oRpt In Application.CurrentProject.AllReports
DoCmd.OpenReport oRpt.Name, acDesign
Set rpt = Reports(oRpt.Name).Report
With rpt
'Report Properties
For Each prp In .Properties
If InStr(prp.Name, "EmMacro") > 0 Then
If Len(prp.value) > 0 Then
Debug.Print "Report", rpt.Name, , Replace(prp.Name, "EmMacro", "")
End If
End If
Next prp
'Report Control Properties
For Each ctl In rpt.Controls
For Each prp In ctl.Properties
If InStr(prp.Name, "EMMacro") > 0 Then
If Len(prp.value) > 0 Then
Debug.Print "Report", rpt.Name, ctl.Name, Replace(prp.Name, "EmMacro", "")
End If
End If
Next prp
Next ctl
End With
DoCmd.Close acReport, oRpt.Name, acSaveNo
Next oRpt
Debug.Print String(80, "-")
Debug.Print "Search Completed"
Error_Handler_Exit:
On Error Resume Next
Access.Application.Echo True
If Not prp Is Nothing Then Set prp = Nothing
If Not ctl Is Nothing Then Set ctl = Nothing
If Not rpt Is Nothing Then Set rpt = Nothing
If Not oRpt Is Nothing Then Set oRpt = Nothing
If Not frm Is Nothing Then Set frm = Nothing
If Not oFrm Is Nothing Then Set oFrm = Nothing
Exit Sub
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: FindEmbeddedMacros" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Sub
Thanks for the code. It was very helpful and saved me a lot of time!
Thank you, thank you, thank you. You saved me a lot of time. I have been searching for a lost embeded macro for days and I couldn’ find it.
In 2 minutes I found it and fixed it.
I will be using it often to find mistakes.
Thank you, thank you, thank you. You saved me a lot of time. I have been searching for a lost embeded macro for days and I couldn’ find it.
In 2 minutes I found it and fixed it.
I will be using it often to find mistakes.
Yes, I know: I copied it. But it’s exactly what I’m feeling right now.
Again: Thank-you, thank-you, thank-you
I am still learning and have a MS template with data macros. I can’t get this to work. I have saved it in a module and when I run it, it seems to work but I don’t see any output/report .. I’m not sure what I’m missing?
This function uses Debug.Print to output the results to the immediate window in the VBE. So you need to ensure you have the Immediate window open (in the visual basic editor – VBE- press Ctrl+G).
Brilliant !! This has saved hours of tedious work !!
Thank you, thank you, thank you !!
This is so great THANK YOU!
But why in the world would Access spit out an error and not tell you where the error occurred???
Excelente aporte! De verdad que me ahorra un montón de tiempo!!
Thank you! This is so helpful. Saved me so much time!
When running some maintenance code to get the name of all the Form Properties I came across that many of the event properties have a second one with the suffix of “EmMacro” – which let me to a search ending up on this webpage. Again excellent informative website! Thumbs up!
Question: What syntax (i.e. Sublime Text > View > Syntax as an example) do you use to get the nice colored syntax highlighting of the vba code presented on the web page?? As you can see I use Sublime Text a lot to archive VBA modules but I have found not Syntax selector that gives me such nice color highlighting. Thanks!
Thank you
An excellent solution that saved me hours of manually looking. I did find one enhancement was useful which was to look through all the forms and close them first else you get an error when it tries to open a particular form. Whilst trivial to close them manually it was nice to solve programatically.
‘Close any open forms
For Each oFrm In Application.CurrentProject.AllForms
If oFrm.IsLoaded Then DoCmd.Close acForm, oFrm.Name, acSavePrompt
Next