So fügen Sie eine Referenz programmgesteuert hinzu

88

Ich habe ein Programm geschrieben, das Skype ausführt und Nachrichten mit Informationen sendet, wenn es fertig ist. Ich muss eine Referenz für hinzufügen Skype4COM.dll, um eine Nachricht über Skype zu senden. Wir haben ungefähr ein Dutzend Computer in einem Netzwerk und einen gemeinsam genutzten Dateiserver (unter anderem). Alle anderen Computer müssen dieses Programm ausführen können. Ich hatte gehofft, die Referenz nicht von Hand einrichten zu können. Ich hatte geplant, die Referenz an einem freigegebenen Speicherort abzulegen und programmgesteuert hinzuzufügen, wenn das Programm ausgeführt wurde.

Ich kann anscheinend nicht herausfinden, wie man mit VBA programmgesteuert eine Referenz zu Excel 2007 hinzufügt. Ich weiß, wie es manuell geht: Öffnen VBE --> Tools --> References --> browse --_> File Location and Name. Aber das ist für meine Zwecke nicht sehr nützlich. Ich weiß, dass es in Access Vb.net Möglichkeiten gibt, dies zu tun, und ähnlicher Code tauchte immer wieder auf, aber ich bin mir nicht sicher, ob ich ihn verstehe oder ob er relevant ist:

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

Bisher muss ich in den vorgestellten Lösungen, um die Referenz programmgesteuert hinzuzufügen, eine Referenz von Hand hinzufügen und das Trust Center ändern - das ist mehr als nur das Hinzufügen der Referenz. Obwohl ich denke, wenn ich die vorgeschlagenen Lösungen durchführe, kann ich zukünftige Referenzen programmgesteuert hinzufügen. Das macht es wahrscheinlich die Mühe wert.

Alle weiteren Gedanken wären toll.

Auslassen
quelle
1
Sie können CreateObject () ohne Referenz unter Excel 2010
Qbik
Keine Ahnung, warum dies wieder lebendig geworden ist - aber werfen Sie einen Blick auf die frühe / späte Bindung. Wenn Sie eine Referenz hinzufügen (entweder von Hand oder programmgesteuert), wird Ihr Code an eine bestimmte Version gebunden. zB ist die Excel 11-Bibliothek an Excel 2003 gebunden. Alles gut, wenn Sie das möchten, aber ziemlich oft (besonders dort, wo ich arbeite) brauche ich es, um 2003, 2007 und 2010 zu arbeiten.
Darren Bartrup-Cook

Antworten:

108

Auslassen

Es gibt zwei Möglichkeiten, Ihren Projekten Referenzen über VBA hinzuzufügen

1) Verwenden der GUID

2) Direkte Referenzierung der DLL.

Lassen Sie mich beide behandeln.

Aber zuerst sind dies 3 Dinge, um die Sie sich kümmern müssen

a) Makros sollten aktiviert sein

b) Stellen Sie in den Sicherheitseinstellungen sicher, dass "Zugriff auf Visual Basic-Projekt vertrauen" aktiviert ist

Geben Sie hier die Bildbeschreibung ein

c) Sie haben manuell einen Verweis auf das Objekt "Microsoft Visual Basic für Anwendungserweiterbarkeit" festgelegt

Geben Sie hier die Bildbeschreibung ein

Weg 1 (mit GUID)

Normalerweise vermeide ich diesen Weg, da ich in der Registrierung nach der GUID suchen muss ... was ich LOL hasse. Mehr zur GUID hier .

Thema: Hinzufügen einer VBA-Referenzbibliothek über Code

Link : 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

Weg 2 (Direkter Verweis auf die DLL)

Dieser Code fügt einen Verweis auf hinzu 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

Hinweis : Ich habe keine Fehlerbehandlung hinzugefügt. Es wird empfohlen, dass Sie es in Ihrem eigentlichen Code verwenden :)

BEARBEITEN Geschlagen von mischab1:)

Siddharth Rout
quelle
2
Es scheint also, dass ich, anstatt die Referenz von Hand hinzuzufügen, eine separate Referenz von Hand hinzufügen und die Excel-Berechtigungen ändern muss? Zugegeben, es wird in Zukunft besser sein, aber jetzt scheint es ein bisschen lustig zu sein.
Lassen Sie den
2
Ja, es klingt lustig, aber so ist es im Moment :)
Siddharth Rout
2
Werden die Ordnerpositionen einiger DLLs in verschiedenen Windows-Versionen nicht unterschiedlich sein? (zB Win 8, Win 7, Vista, XP usw.). In welchem ​​Fall ist das Hinzufügen per GUID nicht sicherer (wenn Ihre Benutzer unterschiedliche Win-Versionen verwenden)?
Johny, warum
1
Wechseln Sie Dim chkRef As ReferencezuDim chkRef As VBIDE.Reference
petter
10
Für die Aufzeichnung ist die GUID für MS Scripting Runtime {420B2830-E718-11CF-893D-00A0C9054228} . Sie können andere GUIDs herausfinden, indem Sie sie manuell hinzufügen, dann jeweils durchlaufen Ref ThisWorkbook.VBProject.ReferencesundDebug.Print Ref.Name, Ref.Guid
airstrike
26

Es gibt zwei Möglichkeiten, Referenzen mit VBA hinzuzufügen. .AddFromGuid(Guid, Major, Minor)und .AddFromFile(Filename). Welches am besten ist, hängt davon ab, auf was Sie einen Verweis hinzufügen möchten. Ich verwende es fast immer, .AddFromFileweil die Dinge, auf die ich verweise, andere Excel VBA-Projekte sind und nicht in der Windows-Registrierung enthalten sind.

Der angezeigte Beispielcode fügt einen Verweis auf die Arbeitsmappe hinzu, in der sich der Code befindet. Ich sehe im Allgemeinen keinen Grund dafür, da der Code in 90% der Fälle, bevor Sie den Verweis hinzufügen können, bereits nicht kompiliert werden konnte weil die Referenz fehlt. (Und wenn die Kompilierung nicht fehlgeschlagen ist, verwenden Sie wahrscheinlich die späte Bindung und müssen keine Referenz hinzufügen.)

Wenn Sie Probleme haben, den Code auszuführen, gibt es zwei mögliche Probleme.

  1. Um das VBE-Objektmodell problemlos verwenden zu können, müssen Sie einen Verweis auf Microsoft Visual Basic für Application Extensibility hinzufügen . (VBIDE)
  2. Um Excel-VBA-Code auszuführen, der Änderungen an einem VBProject vornimmt, müssen Sie dem Zugriff auf das VBA-Projektobjektmodell vertrauen . (In Excel 2010 befindet es sich im Trust Center - Makroeinstellungen.)

Abgesehen davon könnte ich eine genauere Antwort geben, wenn Sie etwas klarer darüber sein können, was Ihre Frage ist oder was Sie versuchen, was nicht funktioniert.

mischab1
quelle
10

Durchsuchen Sie die Registrierung nach Guids oder verwenden Sie Pfade. Welche Methode ist am besten geeignet? Wenn das Durchsuchen der Registrierung nicht mehr erforderlich ist, ist es dann nicht die bessere Möglichkeit, Guids zu verwenden? Office wird nicht immer im selben Verzeichnis installiert. Der Installationspfad kann manuell geändert werden. Auch die Versionsnummer ist Teil des Pfades. Ich hätte nie vorhersagen können, dass Microsoft vor der Einführung von 64-Bit-Prozessoren jemals '(x86)' zu 'Programme' hinzufügen würde. Wenn möglich, würde ich versuchen, die Verwendung eines Pfades zu vermeiden.

Der folgende Code leitet sich aus der Antwort von Siddharth Rout ab und bietet eine zusätzliche Funktion zum Auflisten aller Referenzen, die in der aktiven Arbeitsmappe verwendet werden. Was passiert, wenn ich meine Arbeitsmappe in einer späteren Version von Excel öffne? Funktioniert die Arbeitsmappe weiterhin, ohne den VBA-Code anzupassen? Ich habe bereits überprüft, ob die Anleitungen für Office 2003 und 2010 identisch sind. Hoffen wir, dass Microsoft in zukünftigen Versionen keine Richtlinien ändert.

Die Argumente 0,0 (von .AddFromGuid) sollten die neueste Version einer Referenz verwenden (die ich nicht testen konnte).

Was sind deine Gedanken? Natürlich können wir die Zukunft nicht vorhersagen, aber was können wir tun, um unsere Codeversion zu beweisen?

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

Der obige Code benötigt keinen Verweis mehr auf das Objekt "Microsoft Visual Basic für Anwendungserweiterbarkeit".

hennep
quelle
3
Beachten Sie, dass Makros aktiviert und der vertrauenswürdige Zugriff auf Visual Basic-Projekt aktiviert sein müssen (Punkte a und b als Antwort von @Siddharth_Rout), aber +1, um die VBIDE-Referenz zu entfernen! Ich schätze auch, dass DebugPrintExistingRefs es im Format ausgibt, um die Zeile zu kopieren und in Code einzufügen.
GlennFromIowa
6

Hier erfahren Sie, wie Sie die Guid programmgesteuert abrufen können! Sie können diese Guids / Dateipfade mit der obigen Antwort verwenden, um die Referenz hinzuzufügen!

Referenz: 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

Hier ist derselbe Code, der jedoch auf dem Terminal gedruckt wird, wenn Sie der Ausgabe kein Arbeitsblatt zuweisen möchten.

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
quelle