Access – VBA – Find Images In Forms and Reports

Experienced developers know that we always want to minimize the file size of a database so it loads faster.  We always want to squeeze the most performance out of every element and also ensure we never near Microsoft Access’ 2GB file size limit.

To that end, whenever I am asked to look over a database, one aspect I always review is the use of images.  Novice developers often insert images without first resizing them for their use within the database.

For instance, I’ve shrunk a db by over 250MB just by resizing 3 images! In that specific instance, I reduced the database by 1.2GB once I had properly optimized all the images within the database. So this can have huge implications.


To that end, below is a simple function you can use to loop through the database forms and reports to identify the places images are used.  Then, you can perform further analysis to determine if you need to better optimize things, or not.

'---------------------------------------------------------------------------------------
' Procedure : db_FindImages
' Author    : Daniel Pineault, CARDA Consultants Inc.
' Website   : http://www.cardaconsultants.com
' Purpose   : Locate the use of images within the database forms and reports
' 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: None required
' Dependencies: GetControlTypeName()
'
' Usage:
' ~~~~~~
' db_FindImages
'   Returns -> Listing of Objects/Controls containing images to the Immediate Window
'
' Revision History:
' Rev       Date(yyyy-mm-dd)        Description
' **************************************************************************************
' 1         2008-03-25              Initial Release
'---------------------------------------------------------------------------------------
Public Sub db_FindImages()
    On Error GoTo Error_Handler
    Dim oAO                   As Access.AccessObject
    Dim oCtl                  As Access.Control

    Application.Echo False

    'Forms
    For Each oAO In CurrentProject.AllForms 'Loop through the Forms
        DoCmd.OpenForm oAO.Name, acDesign
        For Each oCtl In Forms(oAO.Name).Form.Controls 'Loop through the Form Controls
            Select Case oCtl.ControlType
                Case acImage, acBoundObjectFrame, acObjectFrame, acCustomControl
                    Debug.Print oAO.Name, oCtl.Name, GetControlTypeName(oCtl.ControlType)
                Case acCommandButton
                    If oCtl.Picture <> "" And oCtl.Picture <> "(none)" Then
                        Debug.Print oAO.Name, oCtl.Name, GetControlTypeName(oCtl.ControlType)
                    End If
            End Select
        Next oCtl
        DoCmd.Close acForm, oAO.Name, acSaveNo
        DoEvents
    Next oAO

    'Reports
    For Each oAO In CurrentProject.AllReports 'Loop through the Reports
        DoCmd.OpenReport oAO.Name, acViewDesign
        For Each oCtl In Reports(oAO.Name).Report.Controls 'Loop through the Report Controls
            Select Case oCtl.ControlType
                Case acImage, acBoundObjectFrame, acObjectFrame, acCustomControl
                    Debug.Print oAO.Name, oCtl.Name, GetControlTypeName(oCtl.ControlType)
                Case acCommandButton
                    If oCtl.Picture <> "" And oCtl.Picture <> "(none)" Then
                        Debug.Print oAO.Name, oCtl.Name, GetControlTypeName(oCtl.ControlType)
                    End If
            End Select
        Next oCtl
        DoCmd.Close acReport, oAO.Name, acSaveNo
        DoEvents
    Next oAO

Error_Handler_Exit:
    On Error Resume Next
    Application.Echo True
    Set oCtl = Nothing
    Set oAO = Nothing
    Exit Sub

Error_Handler:
    MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
           "Error Source: db_FindImages" & vbCrLf & _
           "Error Number: " & Err.Number & 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

Then, to run it, you need only do

db_FindImages

and then wait while each form and report is processed. Once completed, you will get a listing of all the object and controls that contain images listed in the VBE Immediate Window. Something along the lines of:

frmAdContDetails            btnBacktoMain Command Button
frmAdInvoiceDetails         btnBacktoMain Command Button
frmAdsOutstandingDetails    btnBacktoMain Command Button
frmImailLetterDetails       btnBacktoMain Command Button
frmImailLetterDetails       xCalFrom      ActiveX
frmMISDetails               btnBacktoMain Command Button
frmHELPMailingList          OLEUnbound0   Unbound Object Frame
frmAgencies                 btnBacktoMain Command Button
frmContacts                 btnBacktoMain Command Button
frmContacts                 btnWarning    Command Button
frmMain                     oleW4         Image
frmMain                     btnQuit       Command Button
Be Patient
The iterative nature of this process will make your application flicker and can take more or less time depending on the number of objects (forms and report) and their complexity.

So be patient while the function does its thing!

The above relies on the GetControlTypeName() helper function that can be found at:

4 responses on “Access – VBA – Find Images In Forms and Reports

  1. Robert Simard

    Fonction très utile !
    J’ai ajouté sur la ligne Debug.Print oCtl.PictureType pour trouver rapidement les images qui sont incorporés ou liés. (0/1)

    Merci pour le partage !

  2. azer

    Apres avoir inséré en module de classe et que je fais executer , j’ai une erreur “erreur de compilation : sub ou function non definie” et ce code la se met en bleue : GetControlTypeName(oCtl.ControlType) .
    je suis sur access 2010 32 bits.

    ya t’il une piste , c’est surement une erreur de debutant que je fais.

    PS: y ’til un moyen de savoir quell taille prend chauqe image pour prioriser celles à traiter en premier?