VBA : Arguments multiples pour un même paramètre par l’exemple

Certaines syntaxes permettent de passer plusieurs arguments dans le paramètre. C’est le cas de la commande MsgBox par exemple, où le paramètre Buttons accepte plusieurs valeurs de l’énumérateur vbMsgBoxStyle.

Il est assez simple d’utiliser cette technique dans vos propres commandes ou fonctions. Voici comment procéder :

L’énumérateur

Commencez par créer un module standard pour accueillir la fonction. Dans l’en-tête, après la ligne Option Explicit, nous allons définir l’énumérateur. L’énumérateur est une simple structure de données de variable.





Option Compare Database
Option Explicit

Public Enum efFichierExt
    Unite = 8
    Chemin = 16
    Fichier = 32
    Extension = 64
End Enum

Pour en savoir plus sur l’énumération en VBA, son potentiel et ses bienfaits dans votre code, consultez mon tutoriel : http://loufab.developpez.com/tutoriels/access/enumVBA/

Il est très important que les valeurs de l’enum soit en base 8, comme vous le verrez par la suite.

La fonction

L’écriture de la fonction est assez triviale. La signature de la fonction fait référence à l’enum comme un type classique.

Public Function fFichierExt(strCheminFichier As String, _
                            iType As efFichierExt) As String

'-----------------------------------------------------------------

Le paramètre iType est donc de type efFichierExt, notre enum.

Maintenant, pour tester la présence des différentes valeurs dans iType, il ne faut pas utiliser les opérateurs logiques (=, <>…) habituels mais AND.

Voici comme on procède :

If iType And Unite Then      ' l'unité
   vRetour = Left(strCheminFichier, InStr(strCheminFichier, ":"))
End If

iType And Unite est l’équivalent de « Est-ce que iType contient Unite ? »

Voici la fonction complète qui permet d’extraire de parties du chemin d’un fichier.





Public Function fFichierExt(strCheminFichier As String, _
                iType As efFichierExt) As String
'--------------------------------------------------------------
' Procedure : fFichierExt
' Author    : Fabrice CONSTANS (MVP) blogaccess.free.fr
' Date      : 13/03/2013
' Purpose   : Retourne l'un des éléments suivant le chemin/fichier '               passé
' Parametres:
' strCheminFichier contient le chemin et fichier
' strType = enum eTypeFichierExt
'    64   renvoi l'extension du fichier sans le point
'    32   renvoi le nom du fichier sans son extension
'    16   renvoi le chemin sans le nom ni l'extension
'    8    renvoi l'unité
'--------------------------------------------------------------
   On Error GoTo Errsub

   Dim vRetour As String
   If iType And Unite Then      ' l'unité
        
     vRetour = Left(strCheminFichier, InStr(strCheminFichier, ":"))

   End If
   If iType And Chemin Then     ' le chemin

      vRetour = vRetour & Mid(strCheminFichier, 3, _
                  InStrRev(strCheminFichier, "\") - 2)

   End If
   If iType And Fichier Then

      Dim tmpFic As String

      If strCheminFichier Like "*.*" Then

         tmpFic = Right(strCheminFichier, _
         Len(strCheminFichier) - InStrRev(strCheminFichier, "\"))
         vRetour = vRetour & Left(tmpFic, InStrRev(tmpFic, ".") - 1)
      Else
         vRetour = strCheminFichier
      End If

  End If

    
  If iType And Extension Then   ' renvoi l'extension
     If iType And Fichier Then vRetour = vRetour & "."
        vRetour = vRetour & Right(strCheminFichier, _
           Len(strCheminFichier) - InStrRev(strCheminFichier, "."))
  End If
  fFichierExt = vRetour
  Exit Function

Errsub:
   
'ici utiliser votre propre traitement d'erreur
Exit Function

End Function

Comme vous le voyez, iType est analysé plusieurs fois. A chaque analyse on concatène ou non l’élément souhaité.

La première analyse détermine si l’on doit renvoyer l’unité, la deuxième le chemin etc.

L’appel se fait de la manière suivante :

? fFichierExt("c:\windows\temp\monfichier.tmp", Fichier + Extension)

On remarque que, comme pour MsgBox, les paramètres multiples sont additionnés.

Dans cet exemple le résultat sera :

monfichier.tmp

On peut donc renvoyer tout ou partie de la valeur passée. Par exemple :

? fFichierExt("c:\windows\temp\monfichier.tmp", Unite + Chemin + _
                    Fichier + Extension)

Evidemment, vous pouvez faire l’addition dans l’ordre que vous souhaitez, le résultat sera toujours le même.

? fFichierExt("c:\windows\temp\monfichier.tmp", Extension + Fichier)

Conclusion

L’utilisation d’un enum en base 8 et de l’opérateur logique AND permet de passer autant de paramètres que l’on souhaite. Encore faut-il en avoir l’utilité…

Vous pouvez utiliser la fonction ci-dessus dans vos applications dans la mesure où vous ne modifiez pas le nom de l’auteur.

Erreur 3061 : Trop peu de paramètres 1 requis

Ce message est assez commun lorsque vous manipulez des requêtes dans VBA. Nous allons voir pourquoi cela s’affiche et quelles sont les solutions à y apporter. Dans l’exemple suivant tout est correct , aucune erreur n’est déclenchée.

Sub getName()
Dim db As dao.Database
Dim rst As dao.Recordset

Set db = CurrentDb
Set rst = db.OpenRecordset("SELECT [Nom] FROM " & _
          "tCONTACT WHERE Nom='Martin';", dbOpenSnapshot)

MsgBox "son nom est " & rst.Fields("Nom").Value

rst.Close
Set rst = Nothing
Set db = Nothing

End Sub

Lorsqu’on utilise cette requête avec un paramètre issue d’un formulaire comme ci-dessous :

Sub getName()

...
Set rst = db.OpenRecordset("SELECT [Nom] FROM " & _
          "tCONTACT WHERE Nom=forms.fChercher.txt_nom;", dbOpenSnapshot)

MsgBox "son nom est " & rst.Fields("Nom").Value
...

End Sub

Voici le message Erreur 3061 Trop peu de paramètres… qui apparaît :

Erreur 3061 Trop peu de paramètres. 1 attendu.
Erreur 3061 Trop peu de paramètres. 1 attendu.

La seule solution à ce problème est que les paramètres de provenant de l’IHM, du Form, soient interprétés non plus par le moteur de base de données comme avec ce code mais directement par VBA.

1ère Solution :

La partie IHM est directement interprétée par VBA qui n’envoie que la valeur au moteur de base de données.

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _

          "WHERE Nom=""" & Forms.fChercher.txt_nom & """;", dbOpenSnapshot)

C’est ceci qui est envoyé au moteur de base de données :

SELECT [Nom] FROM tCONTACT WHERE Nom="Martin";

2ème Solution :

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _

          "WHERE Nom=Eval('Forms.fChercher.txt_nom');", dbOpenSnapshot)

Ici c’est un peu différent, c’est la fonction VBA Eval() qui fait la liaison entre le moteur de base de données et l’interface (formulaire). Eval() résout l’expression Forms et renvoi sa valeur.

3ème Solution :

Celle-ci est un peu plus complexe car elle nécessite l’écriture d’une fonction utilisateur.

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _
           "WHERE Nom=fDonneNom();", dbOpenSnapshot)

Dans un module standard écrivez cette fonction :

Public Function fDonneNom() As Variant
    fDonneNom = Forms.fChercher.txt_nom
End Function

Ce cas est plutôt à envisager lorsque la valeur renvoyée est le résultat d’une opération complexe comme un calcul, une concaténation…

Public Function fDonneNom() As String
    fDonneNom = Forms.fChercher.txt_nom
End Function

4ème Solution :

Cette solution est à envisager surtout si vous avez de nombreux paramètres issus de l’IHM ou qu’ils sont hétérogènes ; issus de plusieurs sources (VBA, résultat de requête, IHM…).

Commencez par modifier la requête en utilisant la clause PARAMETERS. Vous pouvez utiliser le QBE (Query By Exemple), autrement dit l’éditeur de requêtes de Microsoft Access, en Mode Création pour créer cette clause et l’alimenter.

Le menu Parameters.
Le menu Parameters.

Remplissez le tableau qui apparaît avec un paramètre par ligne et réglez son type (texte, date, entier…). Une fois ceci effectué placez vos paramètres sur la ligne de critères.

Si vous basculer en mode SQL, voici ce que vous pourrez observer :

PARAMETERS [txt_nom] Text ( 255 ), [NumSociete] Long;

SELECT tContact.Nom, tContact.Prenom, tContact.IdSociete 
FROM tContact

WHERE (((tContact.Nom) Like [txt_nom]) 
AND ((tContact.IdSociete)=[NumSociete]));

 La clause PARAMETERS et ses arguments sont terminés par un point-virgule. Coté VBA voici comment utiliser les PARAMETERS de cette requête.

Sub getName()

Dim db As DAO.Database
Dim qry As DAO.QueryDef
Dim rst As DAO.Recordset
Dim sql As String

Set db = CurrentDb

'composition de la requete SQL
sql = "PARAMETERS [txt_nom] Text ( 255 ), [NumSociete] Long; "
sql = sql & " SELECT tContact.Nom, tContact.Prenom, " 
sql = sql & "        tContact.IdSociete"
sql = sql & " FROM tContact"
sql = sql & " WHERE tContact.Nom Like [txt_nom] "
sql = sql & "     AND tContact.IdSociete=[NumSociete];"

'creation de la requete
Set qry = db.CreateQueryDef("rqtemporaire", sql)

'affectation des valeurs aux parametres
qry.Parameters("txt_nom") = Forms.FChercher.txt_nom
qry.Parameters("NumSociete") = Forms.FChercher.numSociete

'composition du recordset
Set rst = qry.OpenRecordset(dbOpenSnapshot)

'Resultat
MsgBox "Il s'apelle " & rst.Fields("Nom").Value

rst.Close
qry.Close

Set qry = Nothing
Set rst = Nothing
Set db = Nothing

End Sub

Comme vous le voyez il faut passer par un objet Query pour accéder aux Parameters, puis faire un recordset à partir de ce dernier. C’est plus complexe mais lorsque vous avez de nombreuses valeurs à passer à la requête vous gagnez du temps.

Early ou Late Binding : Qu’est-ce que c’est ? Comment choisir ?

Si vous utilisez des bibliothèques externes à MS Access, comprenez qui ne sont pas distribuées avec MS Access, cet article vous intéresse.

Earlybinding, vous l’utilisez systématiquement sans le savoir.

Pour utiliser une bibliothèque avec MS Access, habituellement on ouvre VBE, l’éditeur de VBA, et on utilise Outils/Références. La liste qui s’affiche dans cette fenêtre sont les bibliothèques disponibles sur le poste. Il suffit de cocher la bibliothèque que l’on souhaite utiliser.

Exemple de références d'une application MS ACCESS.
Exemple de références d’une application MS ACCESS.

Dans ce cas on utilise le Earlybinding qu’on peut traduire approximativement par liaison en amont. MS Access se comporte alors de la manière suivante. Au moment de l’ouverture de l’application et avant que la première ligne de code de l’application ne  s’exécute, MS Access va vérifier que les bibliothèques requises existent. Il va sans dire qu’aucun contrôle n’est possible durant cette phase.

Cela occasionne des problèmes lorsque la bibliothèque n’est pas installée sur le poste cible ou qu’elle a une version différente. Dans ce cas, un message d’erreur s’affiche et l’application ne démarre pas.

Voici l’exemple d’un code en Earlybinding en relation avec la bibliothèque Microsoft Word x.xx Object Library :

      Dim wApp As Word.Application
      Dim oDoc As Word.Document

      'crée l'objet Word
      Set wApp = CreateObject("Word.Application")
      wApp.Visible = False
      Set oDoc = wApp.Documents.Open(Chemin)
      With oDoc
        .MailMerge.OpenDataSource Name:="c:\temp\export.csv"
      ...

On remarque que les objets sont fortement typés lors de leur déclaration.

Latebinding ou comment contrôler la présence des bibliothèques.

Heureusement, le langage VBA dispose de moyen de prévenir l’absence de la bibliothèque au moyen du Latebinding ou liaison tardive.

Avec le LateBinding la bibliothèque n’est plus déclarée avant, c’est à dire dans les références, mais bel et bien dans le code au moment de son utilisation. Les objets ne sont plus fortement typés mais reçoivent le type générique Object. De même éventuelles constantes ne sont plus disponibles, il faudra donc les recréer.

Voici un cas concret d’une transformation Early vers Late pour palier un problème de version d’Office lors d’une automation avec Word.

On recrée les constantes correspondantes à la bibliothèque Microsoft Office x.xx Object Library.

Option Compare Database
Option Explicit

Const wdDoNotSaveChanges = 0
Const wdExportFormatPDF = 17

Les objets sont typés de manière générique.

'Debug
'Dim wApp As Word.Application   
'Dim oDoc As Word.Document 
               
'Exploitation
Dim wApp As Object
Dim oDoc As Object

Set wApp = CreateObject("Word.Application")
wApp.Visible = False
Set oDoc = wApp.Documents.Open(Chemin)
With oDoc
     .MailMerge.OpenDataSource Name:="C:\export.csv"
...
.Close (wdDoNotSaveChanges)

Notez la mise en commentaires des lignes Earlybinding pour permettre une maintenance/évolution facilité.

Cette technique permet, dans la limite de la compatibilité des bibliothèques, de déployer l’application sur n’importe quel Office puisque le code n’est plus attaché à une version unique de Word.

Dans les références on peut se passer de la déclaration comme on peut le voir ci-dessous.

Sans la bibliothèque.
Sans la bibliothèque.

Voici un cas concret d’une vérification de présence de Word lors de l’ouverture d’un formulaire.

Private Sub Form_Open(Cancel As Integer)
On Error GoTo ErrSub 

Dim wApp As Object
Set wApp = CreateObject("Word.Application")
Set wApp = Nothing
Exit Sub

ErrSub:
If Err.Number = 429 Then
   MsgBox "Vous devez disposer de Word pour utiliser cette fonctionnalité."
   vComposant = False 
End If

End Sub

L’erreur 429 est remontée lorsqu’une bibliothèque est absente.

Conclusion

Si le LateBinding est préférable pour une application en exploitation, il n’en va pas de même lors du développement. En effet le Earlybinding donne accès à l’autocomplétion, ce qui est un confort non négligeable dans cette phase du projet.

MS ACCESS et persistance (1)

Nous sommes conscient que la séparation des données de l’ihm est primordiale pour une application MS Access. L’attachement automatique est depuis de nombreuses années rentré dans les mœurs, chaque développeur utilise le sien.

Si au moment de l’installation, il est obligatoire de spécifier le chemin du fichier de données, lors des mises à jour de l’application cela peut agacer l’utilisateur. Surtout si elles sont régulières. On se doit alors d’utiliser la persistance pour sauvegarder ces paramètres.

Comment créer de la persistance pour les paramètres d’une application ?

En fait il n’y a pas une, mais plusieurs méthodes pour stocker ses valeurs de configuration. La première utilise les fichiers ini. Ce sont des fichiers texte qui ont une structure particulière dont voici un exemple :

[Etiquette1]
parametre1=Valeur
parametre2=Valeur

[Etiquette2]
parametre1=Valeur

Lire et écrire dans un fichier ini

Lire et écrire dans ce type de fichier ne constitue pas une grosse difficulté puisque Windows possède ces 2 fonctions dans l’API Kernel32.

Je vous livre ici ces 2 fonctions implémentées en VBA qui permettent de gérer un fichier ini dans le répertoire de l’application.

Private Declare Function GetPrivateProfileString Lib "kernel32" _
                       Alias "GetPrivateProfileStringA" _ 
           (ByVal lpApplicationName As String, _
            ByVal lpKeyName As Any, ByVal lpDefault As String, _ 
            ByVal lpReturnedString As String, _
            ByVal nSize As Long, _
            ByVal lpFileName As String) As Long

Private Declare Function WritePrivateProfileString Lib _
            "kernel32" Alias "WritePrivateProfileStringA" _ 
           (ByVal lpApplicationName As String, _
            ByVal lpKeyName As Any, ByVal lpString As Any, _ 
            ByVal lpFileName As String) As Long

Const vgInifile = "monapplication.ini"

Function pIniLireParametre(vlEntete As String, _
                           vlNomParametre As String) As String
'----------------------------------------------------------------
' Procedure    : pIniLireParametre
' Description  : renvoi un paramètre depuis un fichier ini 
'                spécifié par vgIniFile
' Parameters   : vlNomParametre est le nom du paramètre à renvoyer
' Return       : le paramètre correspondant à vlNomParametre
'----------------------------------------------------------------
On Error GoTo Errsub
Dim vParam As String, vlLong As Long
vParam = String(255, 0)

vlLong = GetPrivateProfileString(vlEntete, vlNomParametre, _
          "", vParam, 255, CurrentProject.Path & "\" & vgInifile)

If vlLong <> 0 Then vParam = Left$(vParam, vlLong)

pIniLireParametre = RTrim(vParam)

Exit Function

Errsub:
pIniLireParametre = ""

End Function

Function pIniEcrireParametre(vlEntete As String, _
        vlNomParametre As String, _
        vlValeurParametre As String) As Boolean

'--------------------------------------------------------------
' Procedure    : pIniEcrireParametre
' Description  : remplace le paramètre dans un fichier ini spécifié
' Parameters   : vlEntete est l'entête de la rubrique []
'                vlNomParametre est le nom du paramètre
'                vlValeurParametre est la valeur du paramètre
' Return       : N/A
'--------------------------------------------------------------
'
On Error GoTo Errsub
pIniEcrireParametre = True

WritePrivateProfileString vlEntete, vlNomParametre, vlValeurParametre, _
                          CurrentProject.Path & "\" & vgInifile
Exit Function

Errsub:
pIniEcrireParametre = False

End Function

Mise en œuvre de la persistance

Admettons un fichier Ini comportant plusieurs paramètres dont celui indiquant le répertoire du fichier de données.

[Donnees]
CheminData=C:\Users\fabrice\ApplicationData\data.accdb

La lecture se fera via l’instruction suivante :

vFichierData = pIniLireParametre("Donnees", "CheminData")

Il sera alors très simple de vérifier le chemin fourni et celui des tables attachées.

Pour écrire le paramètre on utilise cette instruction lors de la première installation :

pIniEcrireParametre "Donnees", "CheminData", _
        "c:\Users\fabrice\ApplicationData\data.accdb"

Conclusion

En quelques commandes vous avez donné de la persistance à votre application et apporter un sérieux gain de confort à l’utilisateur.

Sélectionner un valeur connue dans une liste

Autant la sélection automatique d’un item dans une liste modifiable est facile grâce à une simple affectation, autant avec une liste classique c’est plus compliqué.

Je vous livre l’astuce consistant à mettre un peu de code dans une liste déroulante reprenant les valeurs de la liste.

Dans l’événement Après MAJ de la liste déroulante ou d’une zone de texte mettre le code VBA ci-dessous :

Dim i As Long
Dim i_save As Long  
Me.lstMultiple.Selected(0) = True    
'désélection de la liste multiple 
For i = 1 To Me.lstMultiple.ListCount - 1  'parcours la liste multiple
   Me.lstMultiple.Selected(i) = False      
   'déselection de l'élement courant   
   If (Me.lstMultiple.ItemData(i) = CStr(Nz(Me.lstRecherche, ""))) Then   
      's'il est identique à ce que je cherche        
      i_save = i  'je repère la ligne     
   End If 
Next 
Me.lstMultiple.Selected(i_save) = True  'en sortant je sélectionne la liste

lstMultiple est la liste classique et lstRecherche est la liste modifiable ou la zone de texte ou vous sélectionnez la valeur à trouver.

L’astuce consiste à parcourir la liste à la recherche de la valeur, d’en capter l’indice de la ligne pour l’affecter à cette même liste.

Astuce : Connaitre l’équivalent VBA d’une propriété.

Je vous livre une petite astuce simple pour connaître l’équivalent d’une propriété d’un formulaire ou d’un état en VBA :

En mode création, placez-vous que la propriété voulue, puis pressez la touche F1.

Vous aurez l’équivalent VBA de la propriété, son utilité et souvent un exemple d’utilisation VBA.

Bonne utilisation !

MS ACCESS : Afficher/Cacher le ruban à la demande

Cette fois-ci je vous livre l’une de mes astuces que j’utilise systématiquement dans toutes mes applications : Afficher/Cacher le ruban à la demande.

La méthode est simple, une variable globale permet de fixer l’état du ruban. Un raccourci dans une macro Autokey permet de changer l’état du ruban et une fonction VBA affiche ou cache le ruban suivant l’état de la variable.

Option Compare Database
Option Explicit
Dim StateRibbon As Boolean

Function DisplayRibbon()
' Auteur : Fabrice CONSTANS (MVP)
' Description : Affiche/cache le ruban
' ctrl+shift+R

Nz StateRibbon, False  ' 1er passage initialise à faux
' (ribbon invisible)

DoCmd.ShowToolbar "Ribbon", IIf(StateRibbon, acToolbarNo, acToolbarYes)

StateRibbon = Not StateRibbon  ' inverse la valeur

End Function

Le raccourci :

+^{R}  ExecuterCode DisplayRibbon()

Cacher le ruban permet de cacher également les boutons Restaurer/ Fermer ce qui donne une touche professionnelle à l’application.

MSACCESS : Déselection zone de liste

Lorsque vous utilisez une zone de liste sans sélection multiple, il peut arriver d’avoir besoin de désélectionner la ligne. Inutile de vous acharner sur la ligne sélectionnée avec votre souris, elle restera en surbrillance.

Je vous livre ici ma méthode pour enlever la sélection :

Dim itSel As Integer

Private Sub Form_Open(Cancel As Integer)
'initialise à -1 pour ne pas perturber la première sélection
itSel = -1 
End Sub

Private Sub Liste_Click()
'la selection est identique à la précédent
If Me.Liste.ListIndex = itSel Then
   Me.Liste.ListIndex = -1  'on déselectionne
   itSel = -1
Else
   'on fixe le choix pour la prochaine comparaison
   itSel = Me.Liste.ListIndex
End If

End Sub

La liste se nomme Liste. On déclare une variable globale au  formulaire, que l’on nomme itSel, elle permettra de conserver le précédent choix opéré, soit un entier positif pour une sélection et -1 pour la dé-sélection.

Sur l’ouverture du formulaire on considère que rien n’est sélectionné et on attribue la valeur -1 à itSel. Lorsqu’on clique sur la zone de liste, on vérifie si le clic correspond à la sélection en cours au moyen de la propriété ListIndex.

Cette propriété retourne un entier de 0 à x ou x est le dernier item de la liste. Lorsque qu’on attribue une valeur à ListIndex l’item correspond est sélectionné, par contre si l’on met -1 aucune ligne n’est sélectionnée.

Simple et efficace.

MS ACCESS : Contrôle OLE lié et application manquante

Dans les applications MS Access, il peut arriver d’avoir des contrôles OLE liés à des applications qui ne sont pas ou plus installées. Dans ce cas, toutes les tentatives d’interventions se soldent par le message :

Impossible de modifier cette propriété : elle est en lecture seule.

ou encore.

Le serveur OLE n'est pas inscrit.
Pour l'inscrire, réinstallez-le.

Une seule méthode pour s’en débarrasser :

Clic-droit sur l’objet, Remplacer par…, Image

Un joli message s’affiche :

Vous ne pouvez pas annuler cette opération et ne
 pourrez plus modifier cet objet.

Cliquez sur Oui.

Votre objet est à nouveau accessible mais bien entendu, pas avec l’application originelle puisque celle-ci n’est pas installée.

MS ACCESS : Réparer un fichier accdb ou mdb (nouvelle édition)

Avec Microsoft Access, il peut arriver d’avoir du code VBA lié aux formulaires ou aux états qui ne soit plus accessible ou qui provoque des erreurs inexplicables. C’est rageant ! Surtout que les moyens de réparation sont rares. Je vous livre ici une méthode qui, pour moi, a fait ses preuves dans de nombreux cas. Cela consiste à traiter le fichier avec deux commandes.

Attention vous devez traiter uniquement une copie de la base endommagée. C’est pour cette raison que le fichier est copié avant d’être traité.

Voici donc un batch (.cmd) qui peut être utilisé directement par Windows.

rem @echo off
echo --------------- GUIDE D'UTILISATION --------------------------------
echo Copiez ce fichier dans le répertoire racine à traiter.
echo Decompile et compacte le fichier.
echo Enfoncé la touche Shift pour la première passe.
echo --------------------------------------------------------------------
echo AUTEUR : FABRICE CONSTANS MVP
copy %1 %1.sav
SET NoExecuteApplication = "Oui"
"C:\Program files\Microsoft Office\OFFICE14\MSACCESS.EXE" %1 /Decompile
"C:\Program files\Microsoft Office\OFFICE14\MSACCESS.EXE" %1 /Compact
SET NoExecuteApplication=

Faites-glisser la copie de votre application sur le batch en maintenant le shift appuyé pour éviter l’exécution du code. Lorsque la barre de progression d’Access est terminée fermez l’application pour démarrer le compactage. Vous décompilez (reconstruction des liens VBA) et compactez la base. Vous pouvez l’utilisé à partir de la version 97.

Notez que suivant la version d’Access vous devrez remplacer le chemin MSACCESS.EXE par le votre.

NoExecuteApplication permet à votre application de ne pas s’exécuter lors de ce traitement. Il faut dans l’application prévoir ce cas en utilisant ce code dans votre procédure de démarrage de l’application :

'debogage, decompil, compactage

If Not Environ("NoExecuteApplication") = "" Then

   'autres traitements possibles en post livraison
   Application.Quit   'quitte

End If

Bonne utilisation !