Jak programowo dodać odwołanie

89

Napisałem program, który działa i wysyła do Skype'a informacje o zakończeniu. Skype4COM.dllAby wysłać wiadomość przez Skype, muszę dodać numer referencyjny . Mamy kilkanaście komputerów w sieci i współdzielony serwer plików (między innymi). Wszystkie inne komputery muszą mieć możliwość uruchomienia tego programu. Miałem nadzieję, że uniknę ręcznego konfigurowania odniesienia. Planowałem umieścić odniesienie we współdzielonej lokalizacji i dodać je programowo po uruchomieniu programu.

Nie wiem, jak programowo dodać odwołanie do programu Excel 2007 przy użyciu języka VBA. Wiem, jak to zrobić ręcznie: Otwórz VBE --> Tools --> References --> browse --_> File Location and Name. Ale to nie jest zbyt przydatne do moich celów. Wiem, że są sposoby, aby to zrobić w Access Vb.net i kod podobny do tego ciągle się pojawiał, ale nie jestem pewien, czy to rozumiem, lub jeśli jest to istotne:

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

Do tej pory w przedstawionych rozwiązaniach, aby programowo dodać referencję, będę musiał dodać referencję ręcznie i zmienić Centrum zaufania - co jest czymś więcej niż tylko dodaniem referencji. Chociaż myślę, że jeśli zastosuję się do proponowanych rozwiązań, będę mógł programowo dodawać przyszłe odwołania. Co prawdopodobnie sprawia, że ​​jest to warte wysiłku.

Jakiekolwiek dalsze myśli byłyby świetne.

Ommit
źródło
2
możesz użyć CreateObject () bez dodawania odwołania w programie Excel 2010
Qbik
1
Nie mam pojęcia, dlaczego to znowu ożyło - ale spójrz na wczesne / późne wiązanie. Jeśli dodasz odwołanie (ręcznie lub programowo), wiąże Twój kod z określoną wersją. np. biblioteka Excel 11 jest powiązana z Excel 2003. Wszystko dobrze, jeśli tego chcesz, ale dość często (szczególnie tam, gdzie pracuję) potrzebuję jej do pracy w 2003, 2007 i 2010.
Darren Bartrup-Cook

Odpowiedzi:

110

Ommit

Istnieją dwa sposoby dodawania odwołań do projektów za pośrednictwem języka VBA

1) Korzystanie z GUID

2) Bezpośrednie odwołanie do dll.

Pozwólcie, że omówię oba.

Ale najpierw są 3 rzeczy, którymi musisz się zająć

a) Makra powinny być włączone

b) W ustawieniach zabezpieczeń upewnij się, że zaznaczona jest opcja „Ufaj dostępowi do projektu Visual Basic”

wprowadź opis obrazu tutaj

c) Ręcznie ustawiłeś odniesienie do obiektu „Microsoft Visual Basic for Applications Extensibility”

wprowadź opis obrazu tutaj

Sposób 1 (przy użyciu identyfikatora GUID)

Zwykle unikam tego, ponieważ muszę szukać GUID w rejestrze ... którego nienawidzę LOL. Więcej o GUID tutaj .

Temat: Dodaj bibliotekę referencyjną VBA za pomocą kodu

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

Sposób 2 (bezpośrednie odwołanie do biblioteki dll)

Ten kod dodaje odwołanie do 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

Uwaga : nie dodałem obsługi błędów. Zaleca się, aby w swoim rzeczywistym kodzie go używać :)

EDYCJA Pobity przez mischab1:)

Siddharth Rout
źródło
2
Wygląda więc na to, że zamiast ręcznie dodawać referencje, muszę ręcznie dodać osobne referencje i zmienić uprawnienia programu Excel? To prawda, że ​​w przyszłości będzie lepiej, ale teraz wydaje się to trochę zabawne.
Ommit
2
Tak, to brzmi śmiesznie, ale tak właśnie jest w tej chwili :)
Siddharth Rout
1
Świetna odpowiedź. FYI użytkownicy tego, zauważcie, że nadal nie można używać żadnego obiektu Word / PowerPoint / innego obiektu ani Enum poza funkcją lub procedurą z tym, ponieważ kompilator zawiedzie przed WORKBOOK_OPENrozpoczęciem wykonywania zdarzenia. Nie możesz więc stworzyć obiektu Public Word i nie możesz zdefiniować typu parametru jako Word / PPT (np. Nie możesz zrobić czegoś podobnego Sub CopyActiveChartToWord(FormatType as WdPasteDataType)).
s_a,
3
Czy lokalizacje folderów niektórych bibliotek DLL nie będą różne w różnych wersjach systemu Windows? (np. Win 8, Win 7, Vista, XP itp.). W takim przypadku dodanie przez GUID nie będzie bezpieczniejsze (jeśli Twoi użytkownicy mają różne wersje Win)?
johny why
10
Dla przypomnienia, identyfikator GUID dla MS Scripting Runtime to {420B2830-E718-11CF-893D-00A0C9054228}. Możesz znaleźć inne identyfikatory GUID, dodając je ręcznie, a następnie przeglądając je w pętli Ref ThisWorkbook.VBProject.Referencesi używającDebug.Print Ref.Name, Ref.Guid
nalot,
26

Istnieją dwa sposoby dodawania odniesień za pomocą VBA. .AddFromGuid(Guid, Major, Minor)i .AddFromFile(Filename). Który z nich jest najlepszy, zależy od tego, do czego próbujesz dodać odniesienie. Prawie zawsze używam, .AddFromFileponieważ rzeczy, do których się odwołuję, to inne projekty Excel VBA i nie ma ich w rejestrze systemu Windows.

Przykładowy kod, który pokazujesz, doda odwołanie do skoroszytu, w którym znajduje się kod. Generalnie nie widzę w tym sensu, ponieważ w 90% przypadków, zanim będziesz mógł dodać odwołanie, kod już się nie skompilował ponieważ brakuje odniesienia. (A jeśli kompilacja nie powiodła się, prawdopodobnie używasz późnego wiązania i nie musisz dodawać odwołania).

Jeśli masz problemy z uruchomieniem kodu, są dwa możliwe problemy.

  1. Aby łatwo używać modelu obiektowego VBE, musisz dodać odwołanie do Microsoft Visual Basic w celu rozszerzenia aplikacji . (VBIDE)
  2. Aby uruchomić kod Excel VBA, który zmienia cokolwiek w VBProject, musisz zaufać dostępowi do modelu obiektów projektu VBA . (W programie Excel 2010 znajduje się w Centrum zaufania - Ustawienia makr).

Poza tym, jeśli możesz bardziej precyzyjnie określić, jakie jest twoje pytanie lub co próbujesz zrobić, co nie działa, mógłbym udzielić bardziej szczegółowej odpowiedzi.

mischab1
źródło
10

Przeglądanie rejestru w poszukiwaniu przewodników lub używanie ścieżek, która metoda jest najlepsza. Jeśli przeglądanie rejestru nie jest już konieczne, czy nie będzie to lepszym sposobem korzystania z przewodników? Pakiet Office nie zawsze jest instalowany w tym samym katalogu. Ścieżkę instalacji można zmienić ręcznie. Numer wersji jest również częścią ścieżki. Nigdy nie mogłem przewidzieć, że Microsoft kiedykolwiek doda „(x86)” do „Program Files” przed wprowadzeniem 64-bitowych procesorów. Jeśli to możliwe, starałbym się unikać korzystania ze ścieżki.

Poniższy kod wywodzi się z odpowiedzi Siddharth Rout, z dodatkową funkcją do wyświetlania listy wszystkich odniesień używanych w aktywnym skoroszycie. Co się stanie, jeśli otworzę skoroszyt w nowszej wersji programu Excel? Czy skoroszyt nadal będzie działał bez dostosowania kodu VBA? Sprawdziłem już, że poradniki dla Office 2003 i 2010 są identyczne. Miejmy nadzieję, że Microsoft nie zmieni poradników w przyszłych wersjach.

Argumenty 0,0 (z .AddFromGuid) powinny używać najnowszej wersji referencji (której nie byłem w stanie przetestować).

Jakie są Twoje myśli? Oczywiście nie możemy przewidzieć przyszłości, ale co możemy zrobić, aby nasz kod był odporny na wersję?

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

Powyższy kod nie wymaga już odniesienia do obiektu „Microsoft Visual Basic for Applications Extensibility”.

hennep
źródło
3
Zauważ, że musisz mieć włączone makra i zaznaczone Ufaj dostępowi do projektu Visual Basic (punkty aib w odpowiedzi z @Siddharth_Rout), ale +1, aby wyeliminować odniesienie VBIDE! Doceniam również to, że DebugPrintExistingRefs wyświetla go w formacie umożliwiającym skopiowanie i wklejenie wiersza do kodu.
GlennFromIowa
7

Oto jak programowo uzyskać Guid! Następnie możesz użyć tych przewodników / ścieżek do powyższej odpowiedzi, aby dodać odniesienie!

Źródła: 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

Oto ten sam kod, ale drukowanie na terminalu, jeśli nie chcesz poświęcać arkusza roboczego wynikowi.

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
źródło