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
So be patient while the function does its thing!
The above relies on the GetControlTypeName() helper function that can be found at:
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 !
Dans ma version que je me sers, c’est pareil.
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?
https://www.devhut.net/access-vba-convert-controltype-to-name/
Tu pourrais evaluer la propriété PictureType et puis utiliser la propriété Picture en conjonction avec le FSO pour determiner la taille de l’image.