{"id":102,"date":"2025-06-14T22:20:34","date_gmt":"2025-06-14T22:20:34","guid":{"rendered":"https:\/\/loufab.alwaysdata.net\/blogaccess\/?p=102"},"modified":"2025-06-14T22:20:34","modified_gmt":"2025-06-14T22:20:34","slug":"vba-classe-et-gain-de-temps","status":"publish","type":"post","link":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/2025\/06\/14\/vba-classe-et-gain-de-temps\/","title":{"rendered":"VBA : Classe et gain de temps"},"content":{"rendered":"\n<p>Le concept de classe en VBA&nbsp;a certes des lacunes mais&nbsp;il ne doit pas \u00eatre n\u00e9glig\u00e9s pour autant.<\/p>\n\n\n\n<p>En effet&nbsp;par l&rsquo;utilisation&nbsp;des classes ont peut&nbsp;gagner un temps pr\u00e9cieux. Voici un petit exemple fonctionnel d&rsquo;une classe qui g\u00e8re les \u00e9v\u00e8nements <strong>DblClick<\/strong> et <strong>NotInList <\/strong>d&rsquo;une zone de liste d\u00e9roulante. Le <strong>DblClick<\/strong> permet d&rsquo;ouvrir un formulaire de saisie\/\u00e9dition avec l&rsquo;item de la liste, tandis que <strong>NotInList <\/strong>permet de saisir l&rsquo;item.<\/p>\n\n\n\n<p><strong>Cr\u00e9er le module de classe<\/strong><\/p>\n\n\n\n<p>Dans VBE faites Insertion\/Module de classe. En bas \u00e0 gauche dans la fen\u00eatre des propri\u00e9t\u00e9s vous devez renseigner le nom de l&rsquo;instance. cComboBox.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"252\" height=\"159\" src=\"http:\/\/loufab.alwaysdata.net\/blogaccess\/wp-content\/uploads\/2025\/06\/classe1.png\" alt=\"Comment changer un module standard en module de classe.\" class=\"wp-image-103\"\/><\/figure>\n<\/div>\n\n\n<p><strong>Instancing<\/strong> permet de d\u00e9finir si la classe n&rsquo;est visible que dans le fichier courant ou si elle est visible depuis l&rsquo;ext\u00e9rieur. Laissez <strong>1 &#8211; Private<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>D\u00e9claration<\/strong><\/h2>\n\n\n\n<p>Sur la ligne qui suit les <strong>options<\/strong>, nous allons d\u00e9clarer les variables n\u00e9cessaires. Tout d&rsquo;abord la plus importante, celle qui contiendra l&rsquo;objet <strong>Combobox<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Private WithEvents LmCombo As Access.ComboBox<\/code><\/pre>\n\n\n\n<p><strong>WithEvents<\/strong> indique que cet objet pourra lever des \u00e9v\u00e8nements.<\/p>\n\n\n\n<p><strong>Access.ComboBox<\/strong> est le type Liste d\u00e9roulante.<\/p>\n\n\n\n<p>Ensuite nous aurons besoin de&nbsp;variables de type String pour stocker diff\u00e9rents \u00e9l\u00e9ments n\u00e9cessaires \u00e0 l&rsquo;ouverture du formulaire.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>'nom du formulaire qui est appel\u00e9 lors du notinlist \nPrivate strFormNameLie As String \n\n'nom du champ id de la table recevant la nouvelle valeur \nPrivate strIdFieldName As String \n\n'nom du champ recevant la valeur saisie dans la combo \nPrivate strControlName As String \n\n'nom de la table recevant la nouvelle valeur \nPrivate strTableFormLie As String<\/code><\/pre>\n\n\n\n<p>En suivant nous \u00e9crivons deux m\u00e9thodes habituelles dans les classes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Private Sub Class_Initialize() \n' Initialise \nEnd Sub<\/code><\/pre>\n\n\n\n<p>La\u00a0<strong>Class_Initialize<\/strong> est ex\u00e9cut\u00e9e au d\u00e9marrage de la\u00a0classe. Elle ne contient rien dans cet exemple mais peu permettre d&rsquo;initialiser des propri\u00e9t\u00e9s ou des variables, ex\u00e9cuter des m\u00e9thodes &#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Private Sub Class_Terminate() \n' lib\u00e8re les variables \nOn Error Resume Next \n\nSet LmCombo = Nothing\n \nEnd Sub<\/code><\/pre>\n\n\n\n<p>Tandis que <strong>Class_Terminate<\/strong> est ex\u00e9cut\u00e9 lorsqu&rsquo;on lib\u00e8re la classe, qu&rsquo;on la d\u00e9charge. Celle-ci est importante car c&rsquo;est l\u00e0 qu&rsquo;on d\u00e9charge \u00e9galement toutes nos variables.<\/p>\n\n\n\n<p>Pour charger la combo depuis le formulaire il faut utiliser un Setteur. Le voici !<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Property Set objComboBox(objCombo As Access.ComboBox) \n   Set LmCombo = objCombo \n   LmCombo.OnDblClick = \"&#91;Event Procedure]\" \n   LmCombo.OnNotInList = \"&#91;Event Procedure]\" \nEnd Property<\/code><\/pre>\n\n\n\n<p>On voit qu&rsquo;on lui passe un objet <strong>combobox<\/strong> et qu&rsquo;il est charg\u00e9 dans la variable d\u00e9finie pr\u00e9c\u00e9demment. Les 2 lignes suivantes permettent d&rsquo;activer l&rsquo;\u00e9coute des \u00e9v\u00e8nements dont nous avons besoin : <strong>DblClick<\/strong> et <strong>NotInList<\/strong>.<\/p>\n\n\n\n<p>Les autres variables ou propri\u00e9t\u00e9s de la classe doivent \u00e9galement \u00eatre valoris\u00e9es toujours \u00e0 l&rsquo;aide de Setteurs.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Property Let frmNameLie(strNomFormulaireLie As String)\n   strFormNameLie = strNomFormulaireLie \nEnd Property<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Property Let idFieldName(strNomIdFieldFormulaireLie As String) \n   strIdFieldName = strNomIdFieldFormulaireLie \nEnd Property<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Property Let controlNameLie(strNomControleFormulaireLie As String)  \n   strControlName = strNomControleFormulaireLie \nEnd Property<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Property Let tableNameLie(strNomTableFormulaireLie As String) \n   strTableFormLie = strNomTableFormulaireLie \nEnd Property<\/code><\/pre>\n\n\n\n<p>Rien de bien particulier \u00e0 part qu&rsquo;on utilise un Let r\u00e9serv\u00e9 aux objets au lieu du Set.<\/p>\n\n\n\n<p>Nos variables sont devenus des propri\u00e9t\u00e9s de la classe.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>M\u00e9thode priv\u00e9e<\/strong><\/h2>\n\n\n\n<p>Une m\u00e9thode priv\u00e9e permettra d&rsquo;attendre la fermeture du formulaire de saisie avant de poursuivre l&rsquo;ex\u00e9cution du code.&nbsp;Nous&nbsp;d&rsquo;obtiendrons un d\u00e9roulement synchrone du processus.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Private Sub pAttendreFermeture(vlFrmRprt As Object) \n'----------------------------------------------------------- \n' Procedure : pAttendreFermeture \n' Author : Fabrice CONSTANS \n' Date : 20\/10\/2011 \n' Description : Attend la fermeture de l'objet pour rendre la main \n' Param\u00e8tres : vlFr est l'objet \u00e0 controler \n'----------------------------------------------------------- \nOn Error GoTo \npgAttenteFermeture_Error \n\nDo \n   DoEvents \nLoop While vlFrmRprt.Visible \n\npgAttenteFermeture_Error: \nOn Error GoTo 0 \n\nExit Sub \nEnd Sub<\/code><\/pre>\n\n\n\n<p><strong>Les \u00e9v\u00e8nements<\/strong><\/p>\n\n\n\n<p>Les \u00e9v\u00e8nements vont \u00eatre g\u00e9r\u00e9s \u00e0 l&rsquo;aide de proc\u00e9dure qui deviendront de fait des m\u00e9thodes de la classe. La diff\u00e9rence c&rsquo;est qu&rsquo;\u00e0 aucun moment nous ne devront les appeler pour qu&rsquo;elles fonctionnent. Ceci gr\u00e2ce au <strong>WithEvents<\/strong> de la d\u00e9claration et \u00e0 l&rsquo;activation des \u00e9couteurs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Le Notinlist<\/h2>\n\n\n\n<p>On remarque que la signature de la proc\u00e9dure est strictement identique \u00e0 celle qui pourrait \u00eatre g\u00e9n\u00e9r\u00e9e dans un formulaire. Je vous conseille d&rsquo;ailleurs d&rsquo;utiliser des signature g\u00e9n\u00e9r\u00e9e et de les copier dans la classe.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Sub LmCombo_NotInList(NewData As String, Response As Integer) \n'-------------------------------------------------------------------- \n' Procedure : LmContact_NotInList \n' Author : Fabrice CONSTANS (MVP) \n' Date : 21\/01\/2016 \n' Purpose : Nouveau contact, on appelle le formulaire de saisie. \n'------------------------------------------------------------------ \nDim strNouveauNumero As String \nOn Error GoTo Errsub \nIf vbYes = MsgBox(\"Cette valeur n'existe pas. \" &amp; _\n    \"Souhaitez-vous la cr\u00e9er ?\", vbInformation + vbYesNo, _ \n    \"classe ccombo\") Then \n\n   'ouverture du formulaire en mode Ajout \n   DoCmd.OpenForm strFormNameLie, acNormal, , , acFormAdd \n\n   'on g\u00e8le le contr\u00f4le reception de la valeur saisie      \n   Forms(strFormNameLie).Controls(strControlName).Enabled = False \n\n   'on ajoute la valeur saisie dans la liste    \n   Forms(strFormNameLie).Controls(strControlName).Value = NewData \n\n   'traitement synchrone \n   pAttendreFermeture Forms(strFormNameLie) \n\n   'V\u00e9rification que le valeur existe (peut-\u00eatre que l'utilisateur a \n   ' chang\u00e9 d'avis et a annul\u00e9 la cr\u00e9ation \n\n   If dLookUp(\"nz(\" &amp; strIdFieldName &amp; \",-1)\" _ \n      , strTableFormLie, strControlName &amp; \"=\"\"\" &amp; NewData &amp; \"\"\"\") > 0 Then \n\n      'la valeur a \u00e9t\u00e9 saisi \n      Response = acDataErrAdded \n   Else \n      'la valeur n'a pas \u00e9t\u00e9 saisi (annulation) \n      Response = acDataErrContinue \n      LmCombo.Parent.Undo \n   End If \nElse \n   'il ne souhaite pas la cr\u00e9ation \n    Response = acDataErrContinue \n    LmCombo.Parent.Undo \nEnd If \n\nExitsub: \nOn Error GoTo 0 \nExit Sub \n\nErrsub: \nmsgbox \"cComboBox.LmCombo_NotInList\", Err, Erl, Err.Description \n\nEnd Sub<\/code><\/pre>\n\n\n\n<p>Vous pouvez constater que nous utilisons bien les constantes habituelles pour ce type d&rsquo;\u00e9v\u00e8nement : <strong>NewData<\/strong>, <strong>acDataErrContinue<\/strong>, <strong>acDataErrAdded<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Le DblClick<\/h2>\n\n\n\n<p>Cet \u00e9v\u00e8nement est plus simple que le pr\u00e9c\u00e9dent puisqu&rsquo;il ne fait qu&rsquo;ouvrir le formulaire en mode consultation\/modification.<br>A la sortie on pense \u00e0 rafraichir le contenu de la combo au cas ou l&rsquo;utilisateur a modifi\u00e9 une valeur.<br>Il va de soit que pour cette derni\u00e8re le traitement doit \u00e9galement \u00eatre synchrone.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Public Sub LmCombo_DblClick(Cancel As Integer) \n'------------------------------------------------------------------ \n' Procedure : btnEditContact_Click \n' Auteur : Fabrice CONSTANS (MVP) \n' Date : 16\/02\/2016 \n' Purpose : edit et raffraichit la liste au retour \n'------------------------------------------------------------------ ' \nDim Id As Long \nOn Error GoTo Errsub \n\nIf IsNull(LmCombo.Column(0)) Then \n   MsgBox \"Pour cr\u00e9er un item vous devez entrer sa valeur.\", _ \n          vbInformation + vbOKOnly, \"classe ccombo\" \n   Exit Sub \nEnd If \n\nId = LmCombo.Column(0) \nDoCmd.OpenForm strFormNameLie, acNormal, , _ \n      strIdFieldName &amp; \"=\" &amp; Id, acFormEdit \n\npAttendreFermeture Forms(strFormNameLie) \nLmCombo.Undo \nLmCombo.Requery \nLmCombo.value = Id \n\nExitsub: On Error GoTo 0 \nExit Sub \nErrsub: msgbox (\"cComboBox.LmCombo_DblClick\", Err, Erl, Err.Description) \n\nEnd Sub<\/code><\/pre>\n\n\n\n<p>Voil\u00e0 la Classe <strong>cCombo <\/strong>est pr\u00eate \u00e0 \u00eatre utilis\u00e9e. Voyons cela dans les faits.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utiliser la classe dans un formulaire<\/h2>\n\n\n\n<p>En premier lieu il faut indiquer au formulaire que nous allons utiliser cette classe. Pour cela nous devons utiliser autant de variables qu&rsquo;il y a de zone de liste \u00e0 impl\u00e9menter. Ces variables doivent \u00eatre globale, donc d\u00e9clarer imm\u00e9diatement apr\u00e8s les 2 lignes d&rsquo;Options du module de classe du formulaire.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Dim cComboClient As cComboBox<\/code><\/pre>\n\n\n\n<p>Dans l&rsquo;\u00e9v\u00e9nement <strong>Sur Ouverture<\/strong> du formulaire on poursuit la d\u00e9claration.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Set cComboClient = New cComboBox \ncComboClient.controlNameLie = \"RaisonSociale\" \ncComboClient.frmNameLie = \"fClient\" \ncComboClient.idFieldName = \"id_Client\" \nSet cComboClient.objComboBox = Me.Controls(\"lmClient\") \ncComboClient.tableNameLie = \"tClient\"<\/code><\/pre>\n\n\n\n<p><strong>New<\/strong> permet de cr\u00e9er l&rsquo;instance de la classe et ainsi pouvoir acc\u00e9der aux propri\u00e9t\u00e9s.<\/p>\n\n\n\n<p>Dans cet exemple la liste d\u00e9roulante se nomme <strong>lmClient<\/strong>. Vous pouvez adapter ce code d\u00e9claratif \u00e0 votre propre cas. Vous ne devez jamais modifier la classe pour y int\u00e9grer des noms propres \u00e0 l&rsquo;application. Une classe doit rester g\u00e9n\u00e9rique sous peine de ne plus \u00eatre portable.<\/p>\n\n\n\n<p>Il va de soit qu&rsquo;\u00e0 chaque nouvelle liste d\u00e9roulante \u00e0 instancier, un code similaire devra \u00eatre ajout\u00e9.<\/p>\n\n\n\n<p>Une fois sauvegard\u00e9, vous pouvez utiliser le formulaire.<\/p>\n\n\n\n<p>Les tests de comportement&nbsp;\u00e0 faire :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Entrer une nouvelle valeur.<\/li>\n\n\n\n<li>Double cliquer sur la zone de liste.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Classe en VBA, quels avantages ?<\/h2>\n\n\n\n<p><strong>Le poids de l&rsquo;application :&nbsp;<\/strong>On remplace des centaines de lignes par une partie d\u00e9clarative.<\/p>\n\n\n\n<p><strong>L&rsquo;uniformit\u00e9 du comportement :<\/strong> Comme on utilise le m\u00eame code pour tous les contr\u00f4les nous sommes s\u00fbr que le comportement sera la m\u00eame.<\/p>\n\n\n\n<p><strong>Maintenance et \u00e9volution :<\/strong> Si un bug est constat\u00e9 ou que l&rsquo;on souhaite faire \u00e9voluer le comportement, une seule intervention est n\u00e9cessaire. Le recopie de code ne sont plus n\u00e9cessaires avec leur lots d&rsquo;erreurs potentielles.<\/p>\n\n\n\n<p><strong>Rapidit\u00e9 de conception :<\/strong> Une simple d\u00e9claration permet d&rsquo;exploiter la classe.<\/p>\n\n\n\n<p><strong>Le revers de la m\u00e9daille : <\/strong>En cas d&rsquo;erreur non trait\u00e9e, il peut se produire un d\u00e9chargement des classes. Il faudra alors ex\u00e9cuter les d\u00e9clarations une nouvelle fois.<\/p>\n\n\n\n<p>La mise au point peut s&rsquo;av\u00e9rer plus complexe qu&rsquo;avec un code standard, c&rsquo;est pour cela qu&rsquo;il est conseill\u00e9 lorsqu&rsquo;on d\u00e9bute, de concevoir les traitements dans un formulaire pour ensuite le transformer en classe.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>J&rsquo;esp\u00e8re que ce tuto vous aura plu et qu&rsquo;il vous donnera des id\u00e9es d&rsquo;impl\u00e9mentations pour vos d\u00e9veloppements.<\/p>\n\n\n\n<p>Bonne utilisation !<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le concept de classe en VBA&nbsp;a certes des lacunes mais&nbsp;il ne doit pas \u00eatre n\u00e9glig\u00e9s pour autant. En effet&nbsp;par l&rsquo;utilisation&nbsp;des classes ont peut&nbsp;gagner un temps pr\u00e9cieux. Voici un petit exemple fonctionnel d&rsquo;une classe qui g\u00e8re les \u00e9v\u00e8nements DblClick et NotInList &hellip; <a href=\"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/2025\/06\/14\/vba-classe-et-gain-de-temps\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,6],"tags":[11,7],"class_list":["post-102","post","type-post","status-publish","format-standard","hentry","category-access","category-code-vba","tag-access","tag-code-vba"],"_links":{"self":[{"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/posts\/102","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/comments?post=102"}],"version-history":[{"count":3,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/posts\/102\/revisions"}],"predecessor-version":[{"id":106,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/posts\/102\/revisions\/106"}],"wp:attachment":[{"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/media?parent=102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/categories?post=102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/loufab.alwaysdata.net\/blogaccess\/index.php\/wp-json\/wp\/v2\/tags?post=102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}