Como adicionar uma referência programaticamente


89

Eu escrevi um programa que executa e envia mensagens pelo Skype com informações quando termina. Preciso adicionar uma referência para Skype4COM.dllpara enviar uma mensagem pelo Skype. Temos cerca de uma dúzia de computadores em rede e um servidor de arquivos compartilhado (entre outras coisas). Todos os outros computadores precisam ser capazes de executar este programa. Eu esperava evitar configurar a referência manualmente. Eu tinha planejado colocar a referência em um local compartilhado e adicioná-la programaticamente quando o programa fosse executado.

Não consigo descobrir como adicionar uma referência programaticamente ao Excel 2007 usando o VBA. Eu sei fazer manualmente: Abrir VBE --> Tools --> References --> browse --_> File Location and Name. Mas isso não é muito útil para meus objetivos. Eu sei que existem maneiras de fazer isso no Access Vb.net e um código semelhante a este sempre aparecia, mas não tenho certeza se entendi, ou se é relevante:

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

Até agora, nas soluções apresentadas, para adicionar a referência de forma programática, vou precisar adicionar uma referência manualmente e alterar a Central de Confiabilidade - o que é mais do que apenas adicionar a referência. Embora eu suponha que se eu seguir com as soluções propostas, poderei adicionar referências futuras programaticamente. O que provavelmente vale o esforço.

Quaisquer pensamentos adicionais seriam ótimos.


2
você pode usar CreateObject () sem adicionar referência no Excel 2010
Qbik

1
Não tenho ideia de por que isso voltou à vida - mas dê uma olhada na vinculação antecipada / tardia. Se você adicionar uma referência (manual ou programaticamente), ela vincula seu código a uma versão específica. por exemplo, a biblioteca do Excel 11 está vinculada ao Excel 2003. Tudo bem se é isso que você deseja, mas muitas vezes (especialmente onde eu trabalho) eu preciso dele para trabalhar em 2003, 2007 e 2010.
Darren Bartrup-Cook

Respostas:


110

Omitir

Existem duas maneiras de adicionar referências via VBA aos seus projetos

1) Usando GUID

2) Referenciando diretamente a dll.

Deixe-me cobrir ambos.

Mas primeiro, essas são três coisas que você precisa cuidar

a) As macros devem ser habilitadas

b) Nas configurações de segurança, certifique-se de que "Trust Access To Visual Basic Project" está marcado

insira a descrição da imagem aqui

c) Você definiu manualmente uma referência ao objeto `Microsoft Visual Basic for Applications Extensibility"

insira a descrição da imagem aqui

Caminho 1 (usando GUID)

Eu geralmente evito esse caminho porque tenho que procurar o GUID no registro ... o que eu odeio LOL. Mais sobre GUID aqui .

Tópico: Adicionar uma Biblioteca de Referência VBA via código

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

Caminho 2 (referenciando diretamente a dll)

Este código adiciona uma referência a 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

Nota : Eu não adicionei o tratamento de erros. É recomendado que em seu código real, use-o :)

EDIT Batido por mischab1:)


2
Então, parece que em vez de adicionar a referência manualmente, preciso adicionar uma referência separada manualmente e alterar as permissões do Excel. Concedido que será melhor no futuro, mas parece um pouco engraçado agora.
Ommit

2
Sim, parece engraçado, mas é assim que é no momento :)
Siddharth Rout

1
Ótima resposta. Para seus usuários, observe que você ainda não pode usar qualquer Word / PowerPoint / outro objeto ou Enum fora de uma função ou procedimento com isso, pois o compilador falhará antes que o WORKBOOK_OPENevento comece a ser executado. Portanto, você não pode criar um objeto Public Word e não pode definir o tipo de um parâmetro como um tipo Word / PPT (por exemplo, você não pode fazer algo como Sub CopyActiveChartToWord(FormatType as WdPasteDataType)).
s_a

3
Os locais das pastas de algumas DLLs não serão diferentes nas diferentes versões do Windows? (por exemplo, Win 8, Win 7, Vista, XP, etc). Nesse caso, adicionar por GUID não será mais seguro (se seus usuários estiverem em versões diferentes do Win)?
johny porque

10
Para o registro, o GUID para MS Scripting Runtime é {420B2830-E718-11CF-893D-00A0C9054228}. Você pode descobrir outros GUIDs adicionando-os manualmente, depois percorrendo cada um Ref ThisWorkbook.VBProject.Referencese usandoDebug.Print Ref.Name, Ref.Guid
ataque aéreo

26

Existem duas maneiras de adicionar referências usando o VBA. .AddFromGuid(Guid, Major, Minor)e .AddFromFile(Filename). Qual é o melhor depende do que você está tentando adicionar uma referência. Eu quase sempre uso .AddFromFileporque as coisas que estou fazendo referência são outros Projetos VBA do Excel e não estão no Registro do Windows.

O código de exemplo que você está mostrando adicionará uma referência à pasta de trabalho em que o código está. Geralmente não vejo sentido em fazer isso porque 90% das vezes, antes que você possa adicionar a referência, o código já não conseguiu compilar porque a referência está faltando. (E se a compilação não falhou, provavelmente você está usando ligação tardia e não precisa adicionar uma referência.)

Se você estiver tendo problemas para executar o código, há dois problemas possíveis.

  1. Para usar facilmente o modelo de objeto do VBE, você precisa adicionar uma referência ao Microsoft Visual Basic para Extensibilidade de Aplicativos . (VBIDE)
  2. Para executar o código VBA do Excel que altera qualquer coisa em um VBProject, você precisa confiar no acesso ao modelo de objeto do projeto VBA . (No Excel 2010, ele está localizado na Central de confiabilidade - Configurações de macro.)

Além disso, se você puder ser um pouco mais claro sobre qual é a sua pergunta ou o que você está tentando fazer que não está funcionando, eu poderia dar uma resposta mais específica.


10

Procurar guids no registro ou usar caminhos, que método é o melhor. Se a navegação no registro não for mais necessária, não será a melhor maneira de usar guids? O Office nem sempre é instalado no mesmo diretório. O caminho de instalação pode ser alterado manualmente. Além disso, o número da versão faz parte do caminho. Eu nunca poderia ter previsto que a Microsoft adicionaria '(x86)' a 'Arquivos de Programas' antes da introdução dos processadores de 64 bits. Se possível, tentaria evitar o uso de um caminho.

O código abaixo é derivado da resposta de Siddharth Rout, com uma função adicional para listar todas as referências que são usadas na pasta de trabalho ativa. E se eu abrir minha pasta de trabalho em uma versão posterior do Excel? A pasta de trabalho ainda funcionará sem adaptar o código VBA? Já verifiquei se os guids para Office 2003 e 2010 são idênticos. Esperemos que a Microsoft não mude os guids em versões futuras.

Os argumentos 0,0 (de .AddFromGuid) devem usar a versão mais recente de uma referência (que não pude testar).

Quais são seus pensamentos? Claro que não podemos prever o futuro, mas o que podemos fazer para tornar o nosso código à prova de versão?

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

O código acima não precisa mais da referência ao objeto "Microsoft Visual Basic for Applications Extensibility".


3
Observe que você precisa ter as macros habilitadas e Trust Access To Visual Basic Project marcada (pontos aeb na resposta de @Siddharth_Rout), mas +1 para eliminar a referência VBIDE! Além disso, agradeço que DebugPrintExistingRefs a produza no formato para copiar e colar a linha no código.
GlennFromIowa

7

Aqui está como obter o Guid de forma programática! Você pode então usar esses guias / caminhos de arquivo com uma resposta acima para adicionar a referência!

Referência: 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

Aqui está o mesmo código, mas imprimindo no terminal se você não quiser dedicar uma planilha para a saída.

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 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.