Office VBA : Suppression Références manquantes

  • Initiateur de la discussion Initiateur de la discussion zenixNT
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

zenixNT

XLDnaute Nouveau
Bonjour,

Je suis à la recherche d'une solution (pour changer) concernant un problème de gestion des références.
J'ai un document Word contenant des références, dont une est MANQUANTE. J'aimerai automatiser le traitement de suppression de cette référence qui ne sert à rien dans mon code (System Monitor Control) puisque je ne fais pas de monitoring sur ce genre de document.
J'ai trouvé beaucoup de solutions pour supprimer les réferences, notamment en utilisant le lien suivant, la boucle

Code:
For Each chkRef In vbProj.References
 
      ' If the reference is broken, send the name to the Immediate Window.
      If chkRef.IsBroken Then
         vbProj.References.Remove chkRef
      End If
 
   Next

Ce code ne fonctionne pas car la référence ne peut pas être "atteinte" car elle n'est pas renseignée dans le registre (effectivement le GUID est absent du registre)... Du coup impossible de supprimer cette référence du projet puisqu'elle est absente du registre...

Y a-t-il quelqu'un qui aurait une idée sur la méthode de suppression d'une référence absente du registre ?

Je vous remercie beaucoup pour votre réponse et vous souhaite une bonne journée!

zenixNT
 
Re : Office VBA : Suppression Références manquantes

Bonsoir à tous

Testé sur un *.doc avec la référence cochée (avec Word 2013)
Après exécution du code ci-dessous la référence n'est plus cochée.
Code:
Sub RemoveReference()
     Dim Reference As Object
     For Each Reference In ActiveDocument.VBProject.References
           If Reference.Description = "System Monitor Control" Then
                 ActiveDocument.VBProject.References.Remove Reference
           End If
     Next
End Sub

PS: Il faut que soit cochée cette référence:
Microsoft Visual Basic for Application Extensibility 5.3
et que dans Sécurité Macros ceci soit coché.
approuve.png
 
Re : Office VBA : Suppression Références manquantes

Bonjour Staple1600 et merci beaucoup pour ta réponse et le temps pris pour le test !

Je suis tout à fait d'accord que ce code fonctionne si la référence est initialement cochée et fonctionnelle. Cependant, le code que j'utilise et le tien, ne fonctionnent pas si la référence est notée comme MANQUANTE dans la liste des références. A ce moment, aucun moyen de la décocher puisqu'elle est absente du registre... C'est vraiment le fait qu'elle soit MANQUANTE qui m'empêche de supprimer la référence...
J'avoue que le cas de test est assez difficile à recréer, mais pour ceux qui en auront le courage, je vous remercie de votre aide !

Cordialement, et vous souhaitant beaucoup de courage et ténacité pour résoudre tous les problèmes,

zenixNT
 
Re : Office VBA : Suppression Références manquantes

Bonjour Staple1600 et merci beaucoup pour ta réponse et le temps pris pour le test !

Je suis tout à fait d'accord que ce code fonctionne si la référence est initialement cochée et fonctionnelle. Cependant, le code que j'utilise et le tien, ne fonctionnent pas si la référence est notée comme MANQUANTE dans la liste des références. A ce moment, aucun moyen de la décocher puisqu'elle est absente du registre... C'est vraiment le fait qu'elle soit MANQUANTE qui m'empêche de supprimer la référence...
J'avoue que le cas de test est assez difficile à recréer, mais pour ceux qui en auront le courage, je vous remercie de votre aide !

Cordialement, et vous souhaitant beaucoup de courage et ténacité pour résoudre tous les problèmes,

zenixNT
Bonjour

Je rencontre aujourd'hui le même problème.
Y a t il une solution en VBA sans utiliser la liaison retardée (Late Binding), peut-être en listant l'ensemble des références possibles par le registre, récupérer une information (par exemple GUID ou autre) puis effectuer une opération soit le registre ou dans VBE ?

Merci de ne pas insister sur la solution "Late Binding", je désire garder l'aide au développement avec l'affichage des méthodes et propriétés en ligne... ;-)

Merci d'avance.
Jean-Marie
 
Dernière édition:
bonjour,
le problème vient du fait que les librairies sont embarqué dans le projet vb, donc tes références sont attachés au classeur. rien a voir avec l'instenciation tardive.

ton fichier provient d'un autre système d'exploitation et/ou version excel.

soit c'est la première utilisation sur cette machine et accessoirement sur des ordinateurs de même facture, dans ce cas le plus simple est de décrocher un fois pour toutes les références manquantes.

soit ton application fait des alé retour et dans ce cas il faut utiliser l'instance qui est réellement instancié.

le plus souvent il s'agit de Visual Basic for application
par exemple tu as un erreur sur trim trim fait partie de la librairie VBA dans ce cas tu décline VBA.Trim.
 
Merci Barbatruc (plus facile à écrire...) ;-)

Je pense comprendre mais voici exactement le contexte...
Les plateformes de distribution de mon classeur sont les mêmes : Windows réel sur un PC (pas d'autre systèmes d'exploitation avec une émulation Windows ou Office), avec la même version Office (365).
L'ensemble des références "standards" Windows et Office ne posent pas de problème, ce sont les même chez moi et chez les autres. Je rencontre une difficulté avec 1 seul fichier personnel ".xlam" personnel.

J'ai développé différentes macros très "généralistes" dans un fichier ".xlam" utilisé par un lien indiqué par une référence.
Ce fichier peut évoluer et est mis dans le même dossier que le classeur suivant l'évolution des versions de mon classeur, mais ce dossier est différent suivant l'ordinateur des personnes à qui je distribue mon classeur.

Ce dossier étant différent, la référence devient "Manquante" lorsque la nouvelle version du classeur est copiée sur la plateforme cible.
J'essaie de développer une macro qui teste le bon référencement de ce fichier dans l'événement 'Open' du classeur. La référence étant indiquée "Manquante", je n'arrive pas à supprimer automatiquement cette mauvaise référence pour réaffecter le bon fichier situé sur le dossier du classeur.

Je ne sais pas si j'ai été clair...
Jean-Marie
 
non c'est faux désolé une erreur provoqué par une librairie manquante peux se produire nimporte ou
sur du code qui a rien a voir avec la ref
et en effet tenter de supprimer la ref si "isbroken" ne peut fonctionner car vba ne sais pas l'identifier
par contre je n'ai pas tester mais par l'index en gerant l'erreur si erru on suprime la ref(x)
donc a tester
VB:
Sub SupprimerReferencesManquantes()
    Dim i As Long
    Dim refBroken As Boolean
    Dim supprimees As Long
    
    supprimees = 0
    
    For i = ThisWorkbook.VBProject.References.Count To 1 Step -1
        On Error Resume Next
        
        refBroken = ThisWorkbook.VBProject.References(i).IsBroken
        
        If Err.Number = 0 And refBroken Then
            ' Supprimer directement par INDEX
            ThisWorkbook.VBProject.References.Remove ThisWorkbook.VBProject.References.Item(i)
            
            If Err.Number = 0 Then
                supprimees = supprimees + 1
            End If
        End If
        
        Err.Clear
        On Error GoTo 0
    Next i
    
    MsgBox supprimees & " référence(s) manquante(s) supprimée(s)", vbInformation
End Sub
 
Bonjour à tous

Après de multiples recherches et tests divers, j'ai trouvé une solution qui fonctionne parfaitement chez moi...

Rappel de l'environnement :
- J'ai créé des variables et constantes globales et ai développé des procédures et fonctions stockés dans un module situés dans un fichier indépendant nommé "Outils_Generaux.xlam". Ce fichier est déposé dans un dossier relatif à mon classeur dans le sous-dossier 'Outils'.
- J'ai effectué une référence vers ce fichier sur mon PC de développement afin d'avoir accès à l'ensemble des définitions des variables, constantes, procédures et fonctions dans mon classeur. Référencement vers "Outils\Outils_Generaux.xlam".

Rappel du problème :
- Lorsque je transfère mon classeur et le dossier complet 'Outils' avec le fichier 'Outils_Generaux.xlam' vers un autre PC, je perds la référence et ai une erreur lors de l'ouverture de mon classeur car l'événement 'Workbook_Open' de mon classeur a besoin des outils.

MA SOLUTION :
Je ne prétends pas avoir la science infuse mais cette solution fonctionne !
Il y a 2 étapes importantes à faire :
- A l'ouverture du classeur, créer la référence vers mes outils généraux dans l'événement 'Workbook_Open'.
- A la fermeture du classeur, supprimer cette référence puis sauvegarder le classeur sans la référence.

1) Dans mon classeur, je créé un module contenant une fonction que je nommerai ici 'G2_AAA_Verif_References' qui effectue les opérations suivantes :
- S'assure que toutes les références nécessaires sont bien présentes (celles de Microsoft par exemple et celle vers mes outils généraux) et si elles ne le sont pas ('Broken' ou 'Absente'), créé les références.
- Rends un Boolean : 'True' si toutes les références sont présentes ou correctements créées, 'False' dans le cas contraire (et dans ce cas j'affiche un message à l'utilisateur avec le nom des références qui ont généré des erreurs).
VB:
Function G2_AAA_Verif_References( _
            ) As Boolean

--------------------------
' Déclaration des variables
'--------------------------

' Liste des références minimum nécessaires (ne pas indiquer la référence vers les outils généraux)
Dim DI_LISTEREFMINI(7) As String
DI_LISTEREFMINI(1) = "Visual Basic For Applications"
DI_LISTEREFMINI(2) = "Microsoft Excel 16.0 Object Library"
DI_LISTEREFMINI(3) = "OLE Automation"
DI_LISTEREFMINI(4) = "Microsoft Office 16.0 Object Library"
DI_LISTEREFMINI(5) = "Microsoft Forms 2.0 Object Library"
DI_LISTEREFMINI(6) = "Microsoft Scripting Runtime"
DI_LISTEREFMINI(7) = "Microsoft Word 16.0 Object Library"

Dim DI_NbRefActu As Integer     ' nombre de références actuelles
Dim DI_ObjRef As Object         ' objet permettant l'accès aux références VBA
Dim DI_Mess As String           ' message divers
Dim DI_Mess1 As String          ' message divers tests 1
Dim DI_Mess2 As String          ' message divers tests 2
Dim DI_Mess3 As String          ' message divers tests 3
Dim DI_Boucle1 As Integer       ' indice de boucle
Dim DI_Boucle2 As Integer       ' indice de boucle
Dim DI_TESTREF As String        ' libellé actuel de la référence en cours de test de présence

G2_AAA_Verif_References = False ' on considère par défaut des tests non effectués correctement en totalité

DI_NbRefActu = ThisWorkbook.VBProject.References.Count  ' nombre de références actuelles

'----------------------------------------------------------------------------------------
' Détermination du chemin complet du fichier des outils généraux
' (utilisation de 'VBA.' pour éviter des erreurs de compilation si références manquantes)
'----------------------------------------------------------------------------------------
If VBA.Left$(DI_OUTILSDOSS, 1) = "." Then                   ' si le dossier est indiqué en relatif alors
    DI_OutilsNomComplet = ThisWorkbook.Path _
                            & VBA.Mid$(DI_OUTILSDOSS, 2)    ' le chemin complet commence par le dossier du classeur actuel
Else                                                        ' si le chemin est indiqué de façon complète alors
    DI_OutilsNomComplet = DI_OUTILSDOSS                     ' récupération directe du chemin indiqué
End If

'----------------------------------------------------------------------------------------
' Vérification de l'existence de la référence vers les outils généraux
'----------------------------------------------------------------------------------------
DI_Mess3 = ""
For DI_Boucle1 = 1 To DI_NbRefActu                                          ' parcours des références actuelles
    If ThisWorkbook.VBProject.References(DI_Boucle1).IsBroken = False Then  ' si la référence existe alors
        If ThisWorkbook.VBProject.References(DI_Boucle1).FullPath = _
                DI_OutilsNomComplet Then Exit For                       ' si c'est le bon fichier alors sortie de boucle
    End If
Next DI_Boucle1

'-------------------------------------------
' Ajout de la référence si elle n'existe pas
'-------------------------------------------
If DI_Boucle1 > DI_NbRefActu Then                                       ' si la référence n'a pas été trouvée alors
    On Error Resume Next
    ThisWorkbook.VBProject.References.AddFromFile (DI_OutilsNomComplet) ' création de la référence vers les outils
    If Err.Number <> 0 Then
        DI_Mess3 = vbCrLf _
                    & vbCrLf & "---------------------------------------------------------------" _
                    & vbCrLf & "Erreur de création de la référence vers les outils" _
                    & vbCrLf & "---------------------------------------------------------------" _
                    & vbCrLf & "Fichier : '" & DI_OutilsNomComplet & "'" _
                    & vbCrLf _
                    & vbCrLf & "Numéro d'erreur : " & Err.Number _
                    & vbCrLf & Err.Description
    End If
End If

'---------------------------------------------
' Vérification des références en état 'Broken'
' (liens cassés, fichiers inexistants)
'---------------------------------------------
DI_Mess1 = ""
For DI_Boucle1 = 1 To DI_NbRefActu                                              ' parcours des références actuelles
    If ThisWorkbook.VBProject.References(DI_Boucle1).IsBroken = True Then       ' si la référence n'existe pas alors
        DI_Mess1 = DI_Mess1 & vbCrLf & "- " & ThisWorkbook.VBProject.References(DI_Boucle1).Name
    End If
Next DI_Boucle1
If DI_Mess1 <> "" Then
    DI_Mess1 = vbCrLf _
                & vbCrLf & "---------------------------------------------------------------" _
                & vbCrLf & "Références manquantes (liens inexistants)" _
                & vbCrLf & "---------------------------------------------------------------" _
                & DI_Mess1
End If

'---------------------------------------------------------
' Vérification/Création des références minimum nécessaires
' (liste définie au début de cette fonction)
'---------------------------------------------------------
DI_Mess2 = ""
For DI_Boucle1 = 1 To UBound(DI_LISTEREFMINI)                                       ' parcours des références minimum
    For DI_Boucle2 = 1 To DI_NbRefActu                                              ' parcours des références actuelles
        If ThisWorkbook.VBProject.References(DI_Boucle2).IsBroken = False Then      ' si la référence existe alors
            If DI_LISTEREFMINI(DI_Boucle1) = _
                    ThisWorkbook.VBProject.References(DI_Boucle2).Description Then Exit For  ' si référence présente alors fin de recherche
        End If
    Next DI_Boucle2
    If DI_Boucle2 > DI_NbRefActu Then                                       ' si la référence minimum est non trouvée alors
        DI_Mess2 = DI_Mess2 & vbCrLf & "- " & DI_LISTEREFMINI(DI_Boucle1)   ' message d'erreur ne non présence de la référence
    End If
Next DI_Boucle1
If DI_Mess2 <> "" Then
    DI_Mess2 = vbCrLf _
                & vbCrLf & "---------------------------------------------------------------" _
                & vbCrLf & "Références minimum inexistantes" _
                & vbCrLf & "---------------------------------------------------------------" _
                & DI_Mess2
End If

'-----------------------------------------------------
' Vérification des messages à afficher à l'utilisateur
'-----------------------------------------------------
DI_Mess = ""
If DI_Mess1 <> "" Or DI_Mess1 <> "" Or DI_Mess3 <> "" Then
    DI_Mess = DI_Mess & DI_Mess2 & DI_Mess3
End If

If DI_Mess <> "" Then
    DI_Mess = DI_Mess & vbCrLf
    DI_Mess = DI_Mess & vbCrLf & "Votre classeur ne peut pas fonctionner correctement."
    DI_Mess = DI_Mess & vbCrLf & "Quittez-le immédiatement sans modifier les données et sans le sauvegarder."
    DI_Mess = DI_Mess & vbCrLf
    DI_Mess = DI_Mess & vbCrLf & "Contactez le développeur pour analyser et apporter une solution."

    MsgBox DI_Mess, vbCritical + vbOKOnly, "Erreur de références"
    Exit Function
End If

G2_AAA_Verif_References = True ' tout s'est bien passé

End Function

2) Dans l'événement 'Workbook_Open', j'appelle cette fonction (premières instructions de l'événement) de cette façon :
VB:
'====================================================
' Evénement déclenché lors de l'ouverture du classeur
'====================================================
Private Sub Workbook_Open()

If G2_AAA_Verif_References = False Then ' Vérification des références nécessaires au bon fonctionnement du classeur
    Exit Sub
Else
    ThisWorkbook.Save   ' sauvegarde du classeur avec la nouvelle référence des outils généraux
End If

End Sub

3) Dans l'événement 'Workbook_BeforeClose', j'exécute des instructions pour supprimer la référence vers mes outils généraux de la façon suivante :
VB:
'=====================================================
' Evénement déclenché lors de la fermeture du classeur
'=====================================================
Private Sub Workbook_BeforeClose(Cancel As Boolean)

Dim I_Mess As String        ' message divers
Dim I_Reponse As Integer    ' réponse l'utilisateur
Dim I_Ref As Object         ' objet référence des outils généraux

'-----------------------------------------
' Vérification de la sauvegarde du fichier
'-----------------------------------------
If ThisWorkbook.Saved = False Then
    I_Mess = "Vous avez effectué des modification dans le classeur '" & ThisWorkbook.Name & "'." _
                & vbCrLf _
                & vbCrLf & "Désirez-vous :" _
                & vbCrLf & "- Sauvegarder le classeur et quitter : Bouton 'Oui'" _
                & vbCrLf & "- Fermer le classeur sans sauvegarder : Bouton 'Non'" _
                & vbCrLf & "- Ne pas fermer le classeur : 'Annuler'."
    I_Reponse = MsgBox(I_Mess, vbQuestion + vbYesNoCancel)
 
    If I_Reponse = vbCancel Then    ' si demande de ne pas fermer le classeur alors
        Cancel = True               ' flag pour rester dans le classeur (ne pas le fermer)
        Exit Sub                    ' fin
    End If
 
    ' si demande de fermeture sans sauvegarde
    If I_Reponse = vbNo Then ThisWorkbook.Saved = True  ' flag de sauvegarde mis à vrai
 
    ' si demande de fermeture avec sauvegarde
    If I_Reponse = vbYes Then ThisWorkbook.Save         ' sauvegarde du fichier
End If

'------------------------------------------------------------------
' Fermeture du fichier, suppression de la référence vers les outils
'------------------------------------------------------------------
On Error Resume Next
Set I_Ref = ThisWorkbook.VBProject.References(DI_OUTILSNOM)
On Error GoTo 0
Err.Clear

If Not I_Ref Is Nothing Then
    On Error Resume Next
    ThisWorkbook.VBProject.References.Remove I_Ref
    If Err.Number = 0 Then
        ThisWorkbook.Save
        If Err.Number = 0 Then
'            MsgBox "Référence des outils supprimée correctement et fichier sauvegardé."
        Else
            I_Mess = "Sauvegarde du classeur impossible." _
                    & vbCrLf _
                    & vbCrLf & "Numéro : " & Err.Number _
                    & vbCrLf & Err.Description
            MsgBox I_Mess, vbCritical
        End If
    Else
        MsgBox "Erreur lors de la suppression de la référence '" & DI_OUTILSNOM & "'" _
                    & vbCrLf _
                    & vbCrLf & Err.Number _
                    & vbCrLf & Err.Description, vbCritical
        Cancel = True
    End If
    On Error GoTo 0
    Err.Clear
Else
    MsgBox "Référence '" & DI_OUTILSNOM & "' non trouvée."
End If

End Sub
Ceci permet d'avoir sur disque un classeur stocké SANS LA REFERENCE, et lors de son ouverture, la référence ne sera donc pas "Broken", et il sera donc possible de la recréer (voir précédemment comment faire dans l'événement 'Workbook_Open').
 
Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour