Comment ajouter une référence par programme

89

J'ai écrit un programme qui s'exécute et envoie des messages à Skype avec des informations quand il est terminé. Je dois ajouter une référence pour Skype4COM.dllpour envoyer un message via Skype. Nous avons une dizaine d'ordinateurs sur un réseau et un serveur de fichiers partagé (entre autres). Tous les autres ordinateurs doivent pouvoir exécuter ce programme. J'espérais éviter de configurer la référence à la main. J'avais prévu de mettre la référence dans un emplacement partagé et de l'ajouter par programme lors de l'exécution du programme.

Je n'arrive pas à comprendre comment ajouter une référence par programme à Excel 2007 à l'aide de VBA. Je sais comment le faire manuellement: Ouvrez VBE --> Tools --> References --> browse --_> File Location and Name. Mais ce n'est pas très utile pour mes besoins. Je sais qu'il existe des moyens de le faire dans Access Vb.net et un code similaire à celui-ci continuait d'apparaître, mais je ne suis pas sûr de le comprendre, ou si c'est pertinent:

ThisWorkbook.VBProject.References.AddFromGuid _
    GUID:="{0002E157-0000-0000-C000-000000000046}", _
    Major:=5, Minor:=3

Jusqu'à présent, dans les solutions présentées, afin d'ajouter la référence par programme, je devrai ajouter une référence à la main et changer le centre de confiance - ce qui est plus que simplement ajouter la référence. Bien que je suppose que si je donne suite aux solutions proposées, je serai en mesure d'ajouter de futures références par programme. Ce qui en vaut probablement la peine.

Toute autre réflexion serait formidable.

Ommit
la source
2
vous pouvez utiliser CreateObject () sans ajouter de référence sous Excel 2010
Qbik
1
Je ne sais pas pourquoi cela est revenu à la vie - mais jetez un œil à la reliure précoce / tardive. Si vous ajoutez une référence (manuellement ou par programme), cela lie votre code à une version spécifique. par exemple, la bibliothèque Excel 11 est liée à Excel 2003. Tout va bien si c'est ce que vous voulez, mais assez souvent (surtout là où je travaille) j'en ai besoin pour travailler sur 2003, 2007 et 2010.
Darren Bartrup-Cook

Réponses:

110

Ommit

Il existe deux façons d'ajouter des références via VBA à vos projets

1) Utilisation du GUID

2) En référençant directement la dll.

Permettez-moi de couvrir les deux.

Mais d'abord, ce sont 3 choses dont vous devez vous occuper

a) Les macros doivent être activées

b) Dans les paramètres de sécurité, assurez-vous que "Trust Access To Visual Basic Project" est coché

entrez la description de l'image ici

c) Vous avez défini manuellement une référence à l'objet «Extensibilité de Microsoft Visual Basic pour Applications»

entrez la description de l'image ici

Voie 1 (en utilisant GUID)

J'évite généralement cette façon car je dois rechercher le GUID dans le registre ... ce que je déteste LOL. Plus d'informations sur GUID ici .

Sujet: Ajouter une bibliothèque de référence VBA via le code

Lien : http://www.vbaexpress.com/kb/getarticle.php?kb_id=267

'Credits: Ken Puls
Sub AddReference()
     'Macro purpose:  To add a reference to the project using the GUID for the
     'reference library

    Dim strGUID As String, theRef As Variant, i As Long

     'Update the GUID you need below.
    strGUID = "{00020905-0000-0000-C000-000000000046}"

     'Set to continue in case of error
    On Error Resume Next

     'Remove any missing references
    For i = ThisWorkbook.VBProject.References.Count To 1 Step -1
        Set theRef = ThisWorkbook.VBProject.References.Item(i)
        If theRef.isbroken = True Then
            ThisWorkbook.VBProject.References.Remove theRef
        End If
    Next i

     'Clear any errors so that error trapping for GUID additions can be evaluated
    Err.Clear

     'Add the reference
    ThisWorkbook.VBProject.References.AddFromGuid _
    GUID:=strGUID, Major:=1, Minor:=0

     'If an error was encountered, inform the user
    Select Case Err.Number
    Case Is = 32813
         'Reference already in use.  No action necessary
    Case Is = vbNullString
         'Reference added without issue
    Case Else
         'An unknown error was encountered, so alert the user
        MsgBox "A problem was encountered trying to" & vbNewLine _
        & "add or remove a reference in this file" & vbNewLine & "Please check the " _
        & "references in your VBA project!", vbCritical + vbOKOnly, "Error!"
    End Select
    On Error GoTo 0
End Sub

Way 2 (référençant directement la dll)

Ce code ajoute une référence à Microsoft VBScript Regular Expressions 5.5

Option Explicit

Sub AddReference()
    Dim VBAEditor As VBIDE.VBE
    Dim vbProj As VBIDE.VBProject
    Dim chkRef As VBIDE.Reference
    Dim BoolExists As Boolean

    Set VBAEditor = Application.VBE
    Set vbProj = ActiveWorkbook.VBProject

    '~~> Check if "Microsoft VBScript Regular Expressions 5.5" is already added
    For Each chkRef In vbProj.References
        If chkRef.Name = "VBScript_RegExp_55" Then
            BoolExists = True
            GoTo CleanUp
        End If
    Next

    vbProj.References.AddFromFile "C:\WINDOWS\system32\vbscript.dll\3"

CleanUp:
    If BoolExists = True Then
        MsgBox "Reference already exists"
    Else
        MsgBox "Reference Added Successfully"
    End If

    Set vbProj = Nothing
    Set VBAEditor = Nothing
End Sub

Remarque : je n'ai pas ajouté la gestion des erreurs. Il est recommandé que dans votre code actuel, utilisez-le :)

EDIT Battu par mischab1:)

Déroute de Siddharth
la source
2
Il semble donc qu'au lieu d'ajouter la référence à la main, j'ai besoin d'ajouter une référence distincte à la main et de modifier les autorisations Excel? Certes, ce sera mieux à l'avenir, mais cela semble un peu drôle maintenant.
Ommit
2
Oui, ça semble drôle mais c'est comme ça en ce moment :)
Siddharth Rout
1
Très bonne réponse. FYI utilisateurs de ceci, notez que vous ne pouvez toujours pas utiliser n'importe quel objet Word / PowerPoint / autre ou Enum en dehors d'une fonction ou procédure avec ceci puisque le compilateur échouera avant que l' WORKBOOK_OPENévénement commence à s'exécuter. Vous ne pouvez donc pas créer un objet Word public et vous ne pouvez pas définir le type d'un paramètre en tant que type Word / PPT (par exemple, vous ne pouvez pas faire quelque chose comme Sub CopyActiveChartToWord(FormatType as WdPasteDataType)).
s_a
3
Les emplacements des dossiers de certaines DLL ne seront-ils pas différents dans les différentes versions de Windows? (par exemple, Win 8, Win 7, Vista, XP, etc.). Dans quel cas, l'ajout par GUID ne sera-t-il pas plus sûr (si vos utilisateurs sont sur différentes versions de Win)?
johny why
10
Pour mémoire, le GUID pour MS Scripting Runtime est {420B2830-E718-11CF-893D-00A0C9054228}. Vous pouvez trouver d'autres GUID en les ajoutant manuellement, puis en les parcourant en boucle Ref ThisWorkbook.VBProject.Referenceset en utilisantDebug.Print Ref.Name, Ref.Guid
airstrike
26

Il existe deux façons d'ajouter des références à l'aide de VBA. .AddFromGuid(Guid, Major, Minor)et .AddFromFile(Filename). La meilleure solution dépend de ce à quoi vous essayez d'ajouter une référence. J'utilise presque toujours .AddFromFileparce que les choses auxquelles je fais référence sont d'autres projets Excel VBA et ne sont pas dans le registre Windows.

L'exemple de code que vous montrez ajoutera une référence au classeur dans lequel se trouve le code. Je ne vois généralement aucun intérêt à le faire car 90% du temps, avant de pouvoir ajouter la référence, la compilation du code a déjà échoué car la référence est manquante. (Et si la compilation n'a pas échoué, vous utilisez probablement une liaison tardive et vous n'avez pas besoin d'ajouter une référence.)

Si vous rencontrez des problèmes pour exécuter le code, deux problèmes sont possibles.

  1. Afin d'utiliser facilement le modèle objet du VBE, vous devez ajouter une référence à Microsoft Visual Basic pour l'extensibilité d'application . (VBIDE)
  2. Pour exécuter du code VBA Excel qui modifie quoi que ce soit dans un VBProject, vous devez approuver l'accès au modèle d'objet de projet VBA . (Dans Excel 2010, il se trouve dans le Centre de gestion de la confidentialité - Paramètres des macros.)

À part cela, si vous pouvez être un peu plus clair sur votre question ou ce que vous essayez de faire qui ne fonctionne pas, je pourrais vous donner une réponse plus précise.

mischab1
la source
10

Parcourir le registre à la recherche de guides ou utiliser des chemins, quelle méthode est la meilleure. Si la navigation dans le registre n'est plus nécessaire, ne sera-ce pas la meilleure façon d'utiliser les guides? Office n'est pas toujours installé dans le même répertoire. Le chemin d'installation peut être modifié manuellement. Le numéro de version fait également partie du chemin. Je n'aurais jamais pu prédire que Microsoft ajouterait un jour «(x86)» à «Program Files» avant l'introduction des processeurs 64 bits. Si possible, j'essaierais d'éviter d'utiliser un chemin.

Le code ci-dessous est dérivé de la réponse de Siddharth Rout, avec une fonction supplémentaire pour répertorier toutes les références utilisées dans le classeur actif. Que faire si j'ouvre mon classeur dans une version ultérieure d'Excel? Le classeur fonctionnera-t-il toujours sans adapter le code VBA? J'ai déjà vérifié que les guides pour Office 2003 et 2010 sont identiques. Espérons que Microsoft ne changera pas les guides dans les futures versions.

Les arguments 0,0 (de .AddFromGuid) doivent utiliser la dernière version d'une référence (que je n'ai pas pu tester).

Quelles sont vos pensées? Bien sûr, nous ne pouvons pas prédire l'avenir, mais que pouvons-nous faire pour rendre notre version de code preuve?

Sub AddReferences(wbk As Workbook)
    ' Run DebugPrintExistingRefs in the immediate pane, to show guids of existing references
    AddRef wbk, "{00025E01-0000-0000-C000-000000000046}", "DAO"
    AddRef wbk, "{00020905-0000-0000-C000-000000000046}", "Word"
    AddRef wbk, "{91493440-5A91-11CF-8700-00AA0060263B}", "PowerPoint"
End Sub

Sub AddRef(wbk As Workbook, sGuid As String, sRefName As String)
    Dim i As Integer
    On Error GoTo EH
    With wbk.VBProject.References
        For i = 1 To .Count
            If .Item(i).Name = sRefName Then
               Exit For
            End If
        Next i
        If i > .Count Then
           .AddFromGuid sGuid, 0, 0 ' 0,0 should pick the latest version installed on the computer
        End If
    End With
EX: Exit Sub
EH: MsgBox "Error in 'AddRef'" & vbCrLf & vbCrLf & err.Description
    Resume EX
    Resume ' debug code
End Sub

Public Sub DebugPrintExistingRefs()
    Dim i As Integer
    With Application.ThisWorkbook.VBProject.References
        For i = 1 To .Count
            Debug.Print "    AddRef wbk, """ & .Item(i).GUID & """, """ & .Item(i).Name & """"
        Next i
    End With
End Sub

Le code ci-dessus n'a plus besoin de la référence à l'objet «Microsoft Visual Basic pour Applications Extensibilité».

hennep
la source
3
Notez que vous devez avoir activé les macros et coché Trust Access To Visual Basic Project (points a et b dans la réponse de @Siddharth_Rout), mais +1 pour éliminer la référence VBIDE! En outre, j'apprécie que DebugPrintExistingRefs le génère au format pour copier et coller la ligne dans le code.
GlennFromIowa
7

Voici comment obtenir les Guid par programme! Vous pouvez ensuite utiliser ces guids / filepaths avec une réponse ci-dessus pour ajouter la référence!

Référence: http://www.vbaexpress.com/kb/getarticle.php?kb_id=278

Sub ListReferencePaths()
'Lists path and GUID (Globally Unique Identifier) for each referenced library.
'Select a reference in Tools > References, then run this code to get GUID etc.
    Dim rw As Long, ref
    With ThisWorkbook.Sheets(1)
        .Cells.Clear
        rw = 1
        .Range("A" & rw & ":D" & rw) = Array("Reference","Version","GUID","Path")
        For Each ref In ThisWorkbook.VBProject.References
            rw = rw + 1
            .Range("A" & rw & ":D" & rw) = Array(ref.Description, _
                   "v." & ref.Major & "." & ref.Minor, ref.GUID, ref.FullPath)
        Next ref
        .Range("A:D").Columns.AutoFit
    End With
End Sub

Voici le même code mais en impression sur le terminal si vous ne souhaitez pas dédier une feuille de calcul à la sortie.

Sub ListReferencePaths() 
 'Macro purpose:  To determine full path and Globally Unique Identifier (GUID)
 'to each referenced library.  Select the reference in the Tools\References
 'window, then run this code to get the information on the reference's library

On Error Resume Next 
Dim i As Long 

Debug.Print "Reference name" & " | " & "Full path to reference" & " | " & "Reference GUID" 

For i = 1 To ThisWorkbook.VBProject.References.Count 
  With ThisWorkbook.VBProject.References(i) 
    Debug.Print .Name & " | " & .FullPath  & " | " & .GUID 
  End With 
Next i 
On Error GoTo 0 
End Sub 
Chad Crowe
la source