dynamische Referenzen und Codeinjection

Bild

Betrifft: dynamische Referenzen und Codeinjection
von: Broad Peak
Geschrieben am: 03.07.2015 08:09:18

Hallo,
ich habe eine VBA Applikation, die zwei Geräte über eine separate Software ansteuert. Nun soll aber die VBA Applikation auch jemand verwenden können, der nur über ein Gerät und damit nur über eine der beiden Softwareinstallationen verfügt. Aus diesem Grund füge ich die Referenzen nun dynamisch über die GUID ein. Dies funktioniert soweit.
Nun benötige ich aber bei der Deklaration den Typ der Komponente, damit das Eventhandling funktioniert. Im Template deklariere ich die Komponente über "private app as object" - damit funktioniert das Kompilieren auch ohne Referenzen soweit. Kann die Referenz beim Start hinzugefügt werden, wird die obige Definition ersetzt durch eine typisierte "private app as gerät.komponente" Deklaration. Funktioniert soweit auch, nur, dass jetzt beim Start ein Kompilierfehler auftritt. Wenn ich aber manuell das Projekt nochmals kompiliere (was dann auch funktioniert, da alle Deklarationen vorhanden sind), dann funktioniert alles wie gewünscht.
Wo könnte hier das Problem liegen? Auch programmatisches Kompilieren nach der Codeinjection hat mich bis jetzt nicht weitergebracht... Die Referenzen und das Ersetzen der Codefragmente führe ich im Wordbook.Open-Event hinzu.
Wäre super, wenn hier jemand bei der Lösung meines Problems helfen könnte...

Bild

Betrifft: AW: dynamische Referenzen und Codeinjection
von: JoWE
Geschrieben am: 03.07.2015 08:16:07
Hallo breite Spitze,
schön beschrieben und sicher ein interessantes Problem.
Die Bereitschaft zur Beteiligung an der Lösungssuche könntest Du mit detailreicheren Angaben bestimmt noch steigern. Da böte sich beispielsweise das Zeigen des Codes resp. das Hochladen einer Beispieldatei an.
Gruß
Jochen

Bild

Betrifft: AW: dynamische Referenzen und Codeinjection
von: Broad Peak
Geschrieben am: 03.07.2015 08:29:36
Hallo Jochen,
mach ich gerne:
ThisWorkBook:
----------------------------------

Public Sub Workbook_Open()
  On Error GoTo ErrHnd
  mdlGlobals.ComponentReference = mdlHandleReferences.AddReference("{f905269c-3221-43b9-b390- _
1ec3c62bd08a}")
    
    If (mdlGlobals.ComponentReference) Then
      mdlCodeInjection.InjectComponentHandles
    End If
End Sub

mdlHandleReferences
---------------------------------------
Public Function AddReference(strGuid As String) As Boolean
    On Error GoTo ErrorHandler
    Err.Clear
    Dim ref
    Dim r
    
    Set ref = Nothing
    For Each r In ThisWorkbook.VBProject.References
        If UCase(r.GUID) = UCase(strGuid) Then
            Set ref = r
            Exit For
        End If
    Next r
    
    If r Is Nothing Then
      'Add the reference
      Set ref = ThisWorkbook.VBProject.References.AddFromGuid(GUID:=strGuid, Major:=1, Minor:=0) _
    End If
    On Error GoTo 0
    If Not ref Is Nothing Then
        AddReference = True
    Else
        AddReference = False
    End If
    Exit Function
ErrorHandler:
    Set ref = Nothing
    Resume Next
End Function

mdlCodeInjection
----------------------------------------
Public Sub InjectComponentHandles()
  On Error GoTo ErrHnd
  Const FUNC_NAME_MODULE As String = "frmReportGenerator"
  Const STR_CODE As String = "Implements component.IConsumer2"
  Dim SL As Long ' start line
  Dim EL As Long ' end line
  Dim SC As Long ' start column
  Dim EC As Long ' end column
  Dim Found As Boolean
  ' add code handler in main module (route to code file work book open handler)
  Dim strCode As String
  strCode = strCode & "Public componentApp As component.MeasurementApp" & vbCrLf
  strCode = strCode & "' we implement the IConsumer2 interface so we can receive notifications  _
when values have changed" & vbCrLf
  strCode = strCode & STR_CODE & vbCrLf
  
  With ActiveWorkbook.VBProject.VBComponents("frmReportGenerator").CodeModule
  
    If False = .Find(STR_CODE, 1, 1, .CountOfDeclarationLines, -1, False, False, False) Then
      .InsertLines 3, strCode
    End If
    
    SL = 1
    EL = .CountOfDeclarationLines
    SC = 1
    EC = 255
                      
    Found = .Find(target:="Public componentApp As Object", startline:=SL, Startcolumn:=SC,  _
Endline:=EL, ENDcolumn:=EC, wholeword:=True, _
                  MatchCase:=False, patternsearch:=False)
                  
    If Found Then
      .DeleteLines SL
    End If
  End With
   
  Exit Sub
ErrHnd:
  Err.Clear
End Sub


Bild

Betrifft: AW: dynamische Referenzen und Codeinjection
von: JoWE
Geschrieben am: 03.07.2015 08:40:19
Hallo,
ja, geht doch,
aber ich Deine Arbeitsmappe nicht nachbauen um den Code zu testen.
Stelle Deine Frage daher wieder offen.
Gruß
Jochen

 Bild

Beiträge aus den Excel-Beispielen zum Thema "dynamische Referenzen und Codeinjection"